From ef298ba515dab82c7299c8fdfabed75a44829200 Mon Sep 17 00:00:00 2001 From: Niels Klomp Date: Sat, 4 Jul 2026 03:56:03 +0200 Subject: [PATCH 1/8] chore: fixes --- wallet-entitlement-components.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/wallet-entitlement-components.yml b/wallet-entitlement-components.yml index 6e13149..ea68e31 100644 --- a/wallet-entitlement-components.yml +++ b/wallet-entitlement-components.yml @@ -60,9 +60,11 @@ components: deleted: { type: boolean } WalletFeatureManifestEntry: type: object - required: [featureKey, sourceEntitlementId, sourceSubjectType] + required: [featureKey, state, sourceEntitlementId, sourceSubjectType] properties: featureKey: { type: string } + state: + $ref: '#/components/schemas/WalletEntitlementState' configJson: nullable: true $ref: '#/components/schemas/JsonObject' @@ -70,6 +72,8 @@ components: sourceSubjectType: $ref: '#/components/schemas/WalletEntitlementSubjectType' sourceSubjectId: { type: string, nullable: true } + validFrom: { type: string, format: date-time, nullable: true } + validUntil: { type: string, format: date-time, nullable: true } WalletFeatureManifest: type: object required: [version, etag, issuedAt, features] @@ -77,8 +81,16 @@ components: version: { type: string } etag: { type: string } issuedAt: { type: string, format: date-time } + tenantId: { type: string, nullable: true } + appId: { type: string, nullable: true } walletUnitId: { type: string, nullable: true } partyId: { type: string, nullable: true } + groupIds: + type: array + items: { type: string } + orgUnitIds: + type: array + items: { type: string } features: type: object additionalProperties: From d745aa54c036e156f8bed17ccb8e71a9a6fbe716 Mon Sep 17 00:00:00 2001 From: Niels Klomp Date: Sat, 4 Jul 2026 04:50:19 +0200 Subject: [PATCH 2/8] chore: fixes --- platform-config-components.yml | 388 +++++++++++++++++++-------------- 1 file changed, 225 insertions(+), 163 deletions(-) diff --git a/platform-config-components.yml b/platform-config-components.yml index a15d066..ca45dda 100644 --- a/platform-config-components.yml +++ b/platform-config-components.yml @@ -661,22 +661,37 @@ components: SoftwareKmsProvider: description: A software (local key store) KMS provider. - allOf: - - $ref: '#/components/schemas/KmsProviderCommon' - - type: object - properties: - type: - type: string - enum: [software] - autoCreateCertificate: - type: boolean - default: false - description: Whether the provider automatically creates a certificate for the keys it generates. - keystoreType: - type: string - default: pkcs12 - example: pkcs12 - description: Key store format used by the software provider. + type: object + required: [tenantId, providerId, type, enabled, system, role] + properties: + tenantId: + type: string + description: Tenant that owns the provider. + providerId: + type: string + pattern: '^[a-z0-9][a-z0-9-]*$' + description: Identifier of the provider, unique within the tenant. System providers use canonical slugs such as `license`, `platform`, or the initial tenant slug. + type: + type: string + enum: [software] + enabled: + type: boolean + description: Whether the provider is currently active. + system: + type: boolean + default: false + description: True for runtime-owned providers, which cannot be disabled or removed through tenant KMS administration. + role: + $ref: '#/components/schemas/KmsProviderRole' + autoCreateCertificate: + type: boolean + default: false + description: Whether the provider automatically creates a certificate for the keys it generates. + keystoreType: + type: string + default: pkcs12 + example: pkcs12 + description: Key store format used by the software provider. example: tenantId: acme providerId: acme @@ -691,33 +706,47 @@ components: description: > An Azure Key Vault (or Managed HSM) KMS provider. Authentication secrets are write-only and are never returned; the response reports only which credential mode is configured. - allOf: - - $ref: '#/components/schemas/KmsProviderCommon' - - type: object - required: [keyvaultUrl, azureTenantId, hsmType, credentialMode] - properties: - type: - type: string - enum: [azure_keyvault] - keyvaultUrl: - type: string - format: uri - description: Base URL of the Azure Key Vault or Managed HSM instance. - example: https://acme-kv.vault.azure.net/ - azureTenantId: - type: string - description: Microsoft Entra (Azure AD) directory tenant ID the vault belongs to. Distinct from the platform tenant in the path. - example: 72f988bf-86f1-41af-91ab-2d7cd011db47 - applicationId: - type: string - description: Microsoft Entra application (client) ID used to access the vault. - example: azure-keyvault - hsmType: - $ref: '#/components/schemas/AzureHsmType' - credentialMode: - $ref: '#/components/schemas/AzureCredentialMode' - exponentialBackoffRetry: - $ref: '#/components/schemas/KmsExponentialBackoffRetry' + type: object + required: [tenantId, providerId, type, enabled, system, role, keyvaultUrl, azureTenantId, hsmType, credentialMode] + properties: + tenantId: + type: string + description: Tenant that owns the provider. + providerId: + type: string + pattern: '^[a-z0-9][a-z0-9-]*$' + description: Identifier of the provider, unique within the tenant. System providers use canonical slugs such as `license`, `platform`, or the initial tenant slug. + type: + type: string + enum: [azure_keyvault] + enabled: + type: boolean + description: Whether the provider is currently active. + system: + type: boolean + default: false + description: True for runtime-owned providers, which cannot be disabled or removed through tenant KMS administration. + role: + $ref: '#/components/schemas/KmsProviderRole' + keyvaultUrl: + type: string + format: uri + description: Base URL of the Azure Key Vault or Managed HSM instance. + example: https://acme-kv.vault.azure.net/ + azureTenantId: + type: string + description: Microsoft Entra (Azure AD) directory tenant ID the vault belongs to. Distinct from the platform tenant in the path. + example: 72f988bf-86f1-41af-91ab-2d7cd011db47 + applicationId: + type: string + description: Microsoft Entra application (client) ID used to access the vault. + example: azure-keyvault + hsmType: + $ref: '#/components/schemas/AzureHsmType' + credentialMode: + $ref: '#/components/schemas/AzureCredentialMode' + exponentialBackoffRetry: + $ref: '#/components/schemas/KmsExponentialBackoffRetry' example: tenantId: 7b3c2d9e-1f4a-4c8b-9e2d-5a6f7c8b9d01 providerId: acme-azure @@ -735,24 +764,38 @@ components: description: > An AWS KMS provider. Authentication secrets are write-only and are never returned; the response reports only which credential mode is configured. - allOf: - - $ref: '#/components/schemas/KmsProviderCommon' - - type: object - required: [region, credentialMode] - properties: - type: - type: string - enum: [aws_kms] - region: - type: string - description: AWS region the KMS keys live in. - example: eu-west-1 - applicationId: - type: string - description: Application identifier label for the AWS KMS client. - example: aws-kms - credentialMode: - $ref: '#/components/schemas/AwsCredentialMode' + type: object + required: [tenantId, providerId, type, enabled, system, role, region, credentialMode] + properties: + tenantId: + type: string + description: Tenant that owns the provider. + providerId: + type: string + pattern: '^[a-z0-9][a-z0-9-]*$' + description: Identifier of the provider, unique within the tenant. System providers use canonical slugs such as `license`, `platform`, or the initial tenant slug. + type: + type: string + enum: [aws_kms] + enabled: + type: boolean + description: Whether the provider is currently active. + system: + type: boolean + default: false + description: True for runtime-owned providers, which cannot be disabled or removed through tenant KMS administration. + role: + $ref: '#/components/schemas/KmsProviderRole' + region: + type: string + description: AWS region the KMS keys live in. + example: eu-west-1 + applicationId: + type: string + description: Application identifier label for the AWS KMS client. + example: aws-kms + credentialMode: + $ref: '#/components/schemas/AwsCredentialMode' example: tenantId: 7b3c2d9e-1f4a-4c8b-9e2d-5a6f7c8b9d01 providerId: acme-aws @@ -933,7 +976,7 @@ components: CreateKmsProviderRequestCommon: type: object - required: [providerId] + required: [providerId, type] properties: providerId: type: string @@ -944,22 +987,25 @@ components: CreateSoftwareKmsProviderRequest: description: Request to add a software (local key store) KMS provider. - allOf: - - $ref: '#/components/schemas/CreateKmsProviderRequestCommon' - - type: object - properties: - type: - type: string - enum: [software] - default: software - autoCreateCertificate: - type: boolean - default: true - description: Whether the provider automatically creates a certificate for the keys it generates. - keystoreType: - type: string - default: pkcs12 - description: Key store format for the software provider. + type: object + required: [providerId, type] + properties: + providerId: + type: string + pattern: '^[a-z0-9][a-z0-9-]*$' + description: Identifier for the new provider, unique within the tenant. Protected system provider ids such as `license`, `platform`, and the initial tenant slug cannot be created through this admin surface. + type: + type: string + enum: [software] + default: software + autoCreateCertificate: + type: boolean + default: true + description: Whether the provider automatically creates a certificate for the keys it generates. + keystoreType: + type: string + default: pkcs12 + description: Key store format for the software provider. example: providerId: acme-secondary type: software @@ -967,30 +1013,32 @@ components: CreateAzureKeyVaultKmsProviderRequest: description: Request to add an Azure Key Vault (or Managed HSM) KMS provider. - allOf: - - $ref: '#/components/schemas/CreateKmsProviderRequestCommon' - - type: object - required: [keyvaultUrl, azureTenantId, hsmType, credentialOpts] - properties: - type: - type: string - enum: [azure_keyvault] - keyvaultUrl: - type: string - format: uri - description: Base URL of the Azure Key Vault or Managed HSM instance. - azureTenantId: - type: string - description: Microsoft Entra (Azure AD) directory tenant ID the vault belongs to. - applicationId: - type: string - description: Microsoft Entra application (client) ID used to access the vault. - hsmType: - $ref: '#/components/schemas/AzureHsmType' - credentialOpts: - $ref: '#/components/schemas/AzureCredentialOpts' - exponentialBackoffRetry: - $ref: '#/components/schemas/KmsExponentialBackoffRetry' + type: object + required: [providerId, type, keyvaultUrl, azureTenantId, hsmType, credentialOpts] + properties: + providerId: + type: string + pattern: '^[a-z0-9][a-z0-9-]*$' + description: Identifier for the new provider, unique within the tenant. Protected system provider ids such as `license`, `platform`, and the initial tenant slug cannot be created through this admin surface. + type: + type: string + enum: [azure_keyvault] + keyvaultUrl: + type: string + format: uri + description: Base URL of the Azure Key Vault or Managed HSM instance. + azureTenantId: + type: string + description: Microsoft Entra (Azure AD) directory tenant ID the vault belongs to. + applicationId: + type: string + description: Microsoft Entra application (client) ID used to access the vault. + hsmType: + $ref: '#/components/schemas/AzureHsmType' + credentialOpts: + $ref: '#/components/schemas/AzureCredentialOpts' + exponentialBackoffRetry: + $ref: '#/components/schemas/KmsExponentialBackoffRetry' example: providerId: acme-azure type: azure_keyvault @@ -1006,24 +1054,26 @@ components: CreateAwsKmsProviderRequest: description: Request to add an AWS KMS provider. - allOf: - - $ref: '#/components/schemas/CreateKmsProviderRequestCommon' - - type: object - required: [region, credentialOpts] - properties: - type: - type: string - enum: [aws_kms] - region: - type: string - description: AWS region the KMS keys live in. - applicationId: - type: string - description: Application identifier label for the AWS KMS client. - credentialOpts: - $ref: '#/components/schemas/AwsCredentialOpts' - exponentialBackoffRetry: - $ref: '#/components/schemas/KmsExponentialBackoffRetry' + type: object + required: [providerId, type, region, credentialOpts] + properties: + providerId: + type: string + pattern: '^[a-z0-9][a-z0-9-]*$' + description: Identifier for the new provider, unique within the tenant. Protected system provider ids such as `license`, `platform`, and the initial tenant slug cannot be created through this admin surface. + type: + type: string + enum: [aws_kms] + region: + type: string + description: AWS region the KMS keys live in. + applicationId: + type: string + description: Application identifier label for the AWS KMS client. + credentialOpts: + $ref: '#/components/schemas/AwsCredentialOpts' + exponentialBackoffRetry: + $ref: '#/components/schemas/KmsExponentialBackoffRetry' example: providerId: acme-aws type: aws_kms @@ -1058,57 +1108,63 @@ components: UpdateSoftwareKmsProviderRequest: description: Partial update of a software KMS provider. Omitted fields are left unchanged. - allOf: - - $ref: '#/components/schemas/UpdateKmsProviderRequestCommon' - - type: object - properties: - type: - type: string - enum: [software] - autoCreateCertificate: - type: boolean - description: Whether the provider automatically creates a certificate for the keys it generates. + type: object + required: [type] + properties: + type: + type: string + enum: [software] + enabled: + type: boolean + description: Whether the provider is active. + autoCreateCertificate: + type: boolean + description: Whether the provider automatically creates a certificate for the keys it generates. UpdateAzureKeyVaultKmsProviderRequest: description: > Partial update of an Azure KMS provider. Supplying `credentialOpts` rotates the credentials (the previous credential block is replaced). - allOf: - - $ref: '#/components/schemas/UpdateKmsProviderRequestCommon' - - type: object - properties: - type: - type: string - enum: [azure_keyvault] - keyvaultUrl: - type: string - format: uri - azureTenantId: - type: string - applicationId: - type: string - hsmType: - $ref: '#/components/schemas/AzureHsmType' - credentialOpts: - $ref: '#/components/schemas/AzureCredentialOpts' + type: object + required: [type] + properties: + type: + type: string + enum: [azure_keyvault] + enabled: + type: boolean + description: Whether the provider is active. + keyvaultUrl: + type: string + format: uri + azureTenantId: + type: string + applicationId: + type: string + hsmType: + $ref: '#/components/schemas/AzureHsmType' + credentialOpts: + $ref: '#/components/schemas/AzureCredentialOpts' UpdateAwsKmsProviderRequest: description: > Partial update of an AWS KMS provider. Supplying `credentialOpts` rotates the credentials (the previous credential block is replaced). - allOf: - - $ref: '#/components/schemas/UpdateKmsProviderRequestCommon' - - type: object - properties: - type: - type: string - enum: [aws_kms] - region: - type: string - applicationId: - type: string - credentialOpts: - $ref: '#/components/schemas/AwsCredentialOpts' + type: object + required: [type] + properties: + type: + type: string + enum: [aws_kms] + enabled: + type: boolean + description: Whether the provider is active. + region: + type: string + applicationId: + type: string + credentialOpts: + $ref: '#/components/schemas/AwsCredentialOpts' UpdateKmsProviderRequest: description: Partial update of a KMS provider's mutable settings. The concrete shape is selected by `type`. @@ -1185,6 +1241,7 @@ components: allOf: - $ref: '#/components/schemas/SecretProviderCommon' - type: object + required: [type] properties: type: type: string @@ -1214,6 +1271,7 @@ components: allOf: - $ref: '#/components/schemas/SecretProviderCommon' - type: object + required: [type] properties: type: type: string @@ -1244,6 +1302,7 @@ components: allOf: - $ref: '#/components/schemas/SecretProviderCommon' - type: object + required: [type] properties: type: type: string @@ -1269,6 +1328,7 @@ components: allOf: - $ref: '#/components/schemas/SecretProviderCommon' - type: object + required: [type] properties: type: type: string @@ -1320,6 +1380,7 @@ components: allOf: - $ref: '#/components/schemas/SetSecretProviderRequestCommon' - type: object + required: [type] properties: type: type: string @@ -1350,7 +1411,7 @@ components: allOf: - $ref: '#/components/schemas/SetSecretProviderRequestCommon' - type: object - required: [keyvaultUrl, azureTenantId, credentialOpts] + required: [type, keyvaultUrl, azureTenantId, credentialOpts] properties: type: type: string @@ -1382,7 +1443,7 @@ components: allOf: - $ref: '#/components/schemas/SetSecretProviderRequestCommon' - type: object - required: [region, credentialOpts] + required: [type, region, credentialOpts] properties: type: type: string @@ -1411,6 +1472,7 @@ components: allOf: - $ref: '#/components/schemas/SetSecretProviderRequestCommon' - type: object + required: [type] properties: type: type: string From fe97c1983f5ae48490f291210a54de6d636428b6 Mon Sep 17 00:00:00 2001 From: Niels Klomp Date: Sun, 5 Jul 2026 03:45:51 +0200 Subject: [PATCH 3/8] chore: fixes --- command-types.json | 24 +- connector-components.yml | 2689 ++++++++++-- connector-integration-openapi.yml | 6343 +++++++++++++++++++++++++++++ connector-openapi.yml | 633 ++- credential-design-components.yml | 3 +- credential-design-openapi.yml | 88 +- platform-config-components.yml | 11 + redocly.yaml | 2 + 8 files changed, 9301 insertions(+), 492 deletions(-) create mode 100644 connector-integration-openapi.yml diff --git a/command-types.json b/command-types.json index d569056..211fc6e 100644 --- a/command-types.json +++ b/command-types.json @@ -3,19 +3,19 @@ "kind": "data class", "name": "CreateCredentialDesignArgs", "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class CreateCredentialDesignArgs(\n val tenantId: String,\n val input: CreateCredentialDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class CreateCredentialDesignInput\n @JvmOverloads\n constructor(\n val bindings: List,\n val alias: String? = null,\n val hostingMode: DesignHostingMode = DesignHostingMode.LOCAL,\n val credentialTemplateId: Uuid? = null,\n val issuerDesignId: Uuid? = null,\n val displays: List,\n val claims: List = emptyList(),\n val renderVariantIds: List = emptyList(),\n val credentialType: CredentialTypeDescriptor? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\ndata class LocalizedCredentialDisplay\n @JvmOverloads\n constructor(\n val locale: String,\n val name: String,\n val description: String? = null,\n val issuerNameOverride: String? = null,\n val preferredRenderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class ClaimPresentation\n @JvmOverloads\n constructor(\n val path: DesignClaimPath,\n val labels: List,\n val mandatory: Boolean = false,\n val sdPolicy: SdPolicy = SdPolicy.ALLOWED,\n val order: Int = 0,\n val group: String? = null,\n val svgId: String? = null,\n val valueKind: ClaimValueKind? = null,\n val widgetHint: ClaimWidgetHint? = null,\n val markdownAllowed: Boolean = false,\n val entryCodes: List? = null,\n val unit: String? = null,\n )" + "source": "@JsExportCompat\n@Serializable\ndata class CreateCredentialDesignArgs(\n val tenantId: String,\n val input: CreateCredentialDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class CreateCredentialDesignInput\n @JvmOverloads\n constructor(\n val bindings: List,\n val alias: String? = null,\n val hostingMode: DesignHostingMode = DesignHostingMode.LOCAL,\n val credentialTemplateId: Uuid? = null,\n val issuerDesignId: Uuid? = null,\n val displays: List,\n val claims: List = emptyList(),\n val renderVariantIds: List = emptyList(),\n val credentialType: CredentialTypeDescriptor? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\ndata class LocalizedCredentialDisplay\n @JvmOverloads\n constructor(\n val locale: String,\n val name: String,\n val description: String? = null,\n val issuerNameOverride: String? = null,\n val preferredRenderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class ClaimPresentation\n @JvmOverloads\n constructor(\n val path: DesignClaimPath,\n val labels: List,\n val mandatory: Boolean = false,\n val sdPolicy: SdPolicy = SdPolicy.ALLOWED,\n val order: Int = 0,\n val group: String? = null,\n val svgId: String? = null,\n val valueKind: ClaimValueKind? = null,\n val widgetHint: ClaimWidgetHint? = null,\n val markdownAllowed: Boolean = false,\n val entryCodes: List? = null,\n val unit: String? = null,\n )" }, "CredentialDesignRecord": { "kind": "data class", "name": "CredentialDesignRecord", "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class CredentialDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val credentialTemplateId: Uuid? = null,\n val issuerDesignId: Uuid? = null,\n val displays: List,\n val claims: List = emptyList(),\n val renderVariantIds: List = emptyList(),\n val derivedRenderHintsId: Uuid? = null,\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n /** Optional OCA semantic attribute set this design draws from. When present, the OCA-backed\n * credential-design resolution derives selective-disclosure and mandatory flags from it. */\n val semanticAttributeSetRef: SemanticAttributeSetRef? = null,\n /** Optional attribute-profile this design draws from. When present, credential-design\n * resolution derives selective-disclosure and mandatory flags from the profile's resolved\n * effective projection in preference to [semanticAttributeSetRef]. The id and pinned\n * version are held as primitives so this IDK contract stays free of the EDK profile types. */\n val attributeProfileId: Uuid? = null,\n val attributeProfileVersion: Long? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n val credentialType: CredentialTypeDescriptor? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\ndata class LocalizedCredentialDisplay\n @JvmOverloads\n constructor(\n val locale: String,\n val name: String,\n val description: String? = null,\n val issuerNameOverride: String? = null,\n val preferredRenderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class ClaimPresentation\n @JvmOverloads\n constructor(\n val path: DesignClaimPath,\n val labels: List,\n val mandatory: Boolean = false,\n val sdPolicy: SdPolicy = SdPolicy.ALLOWED,\n val order: Int = 0,\n val group: String? = null,\n val svgId: String? = null,\n val valueKind: ClaimValueKind? = null,\n val widgetHint: ClaimWidgetHint? = null,\n val markdownAllowed: Boolean = false,\n val entryCodes: List? = null,\n val unit: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class SemanticAttributeSetRef(\n /** OCA bundle / vocabulary identifier. */\n val bundleId: String,\n /** Optional pinned bundle version; null = resolve the current version. */\n val version: String? = null,\n)\n\ntypealias DesignClaimPath = List\n\n@JsExportCompat\n@Serializable\ndata class ClaimLabel\n @JvmOverloads\n constructor(\n val locale: String,\n val label: String,\n val description: String? = null,\n @JsExportIgnoreCompat\n val entryValues: Map? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class SdPolicy {\n ALWAYS,\n ALLOWED,\n NEVER,\n}\n\n@JsExportCompat\n@Serializable\nenum class ClaimValueKind {\n STRING,\n BOOLEAN,\n NUMBER,\n INTEGER,\n ARRAY,\n OBJECT,\n DATE,\n DATE_TIME,\n URI,\n IMAGE,\n BINARY,\n MARKDOWN,\n REFERENCE,\n UNKNOWN,\n}\n\n@JsExportCompat\n@Serializable\nenum class ClaimWidgetHint {\n TEXT,\n MULTILINE_TEXT,\n CHECKBOX,\n BADGE,\n LIST,\n TABLE,\n GROUP,\n DATE,\n DATE_TIME,\n URI,\n IMAGE,\n MARKDOWN,\n HIDDEN,\n PICKLIST,\n FILE,\n}" + "source": "@JsExportCompat\n@Serializable\ndata class CredentialDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val credentialTemplateId: Uuid? = null,\n val issuerDesignId: Uuid? = null,\n val displays: List,\n val claims: List = emptyList(),\n val renderVariantIds: List = emptyList(),\n val derivedRenderHintsId: Uuid? = null,\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n /** Optional OCA semantic attribute set this design draws from. When present, the OCA-backed\n * credential-design resolution derives selective-disclosure and mandatory flags from it. */\n val semanticAttributeSetRef: SemanticAttributeSetRef? = null,\n /** Optional attribute-profile this design draws from. When present, credential-design\n * resolution derives selective-disclosure and mandatory flags from the profile's resolved\n * effective projection in preference to [semanticAttributeSetRef]. The id and pinned\n * version are held as primitives so this IDK contract stays free of the EDK profile types. */\n val attributeProfileId: Uuid? = null,\n val attributeProfileVersion: Long? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n val credentialType: CredentialTypeDescriptor? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\ndata class LocalizedCredentialDisplay\n @JvmOverloads\n constructor(\n val locale: String,\n val name: String,\n val description: String? = null,\n val issuerNameOverride: String? = null,\n val preferredRenderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class ClaimPresentation\n @JvmOverloads\n constructor(\n val path: DesignClaimPath,\n val labels: List,\n val mandatory: Boolean = false,\n val sdPolicy: SdPolicy = SdPolicy.ALLOWED,\n val order: Int = 0,\n val group: String? = null,\n val svgId: String? = null,\n val valueKind: ClaimValueKind? = null,\n val widgetHint: ClaimWidgetHint? = null,\n val markdownAllowed: Boolean = false,\n val entryCodes: List? = null,\n val unit: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class SemanticAttributeSetRef(\n /** OCA bundle / vocabulary identifier. */\n val bundleId: String,\n /** Optional pinned bundle version; null = resolve the current version. */\n val version: String? = null,\n)\n\ntypealias DesignClaimPath = List\n\n@JsExportCompat\n@Serializable\ndata class ClaimLabel\n @JvmOverloads\n constructor(\n val locale: String,\n val label: String,\n val description: String? = null,\n @JsExportIgnoreCompat\n val entryValues: Map? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class SdPolicy {\n ALWAYS,\n ALLOWED,\n NEVER,\n}\n\n@JsExportCompat\n@Serializable\nenum class ClaimValueKind {\n STRING,\n BOOLEAN,\n NUMBER,\n INTEGER,\n ARRAY,\n OBJECT,\n DATE,\n DATE_TIME,\n URI,\n IMAGE,\n BINARY,\n MARKDOWN,\n REFERENCE,\n UNKNOWN,\n}\n\n@JsExportCompat\n@Serializable\nenum class ClaimWidgetHint {\n TEXT,\n MULTILINE_TEXT,\n CHECKBOX,\n BADGE,\n LIST,\n TABLE,\n GROUP,\n DATE,\n DATE_TIME,\n URI,\n IMAGE,\n MARKDOWN,\n HIDDEN,\n PICKLIST,\n FILE,\n}" }, "ListDesignsArgs": { "kind": "data class", "name": "ListDesignsArgs", "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class ListDesignsArgs\n @JvmOverloads\n constructor(\n val tenantId: String,\n val filter: DesignFilter = DesignFilter(),\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignFilter\n @JvmOverloads\n constructor(\n val entityType: DesignEntityType? = null,\n val hostingMode: DesignHostingMode? = null,\n val binding: DesignBinding? = null,\n val bindingKey: DesignBindingKey? = null,\n val bindingValue: String? = null,\n val aliasContains: String? = null,\n val sourceType: DesignSourceType? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignEntityType {\n CREDENTIAL,\n ISSUER,\n VERIFIER,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}" + "source": "@JsExportCompat\n@Serializable\ndata class ListDesignsArgs\n @JvmOverloads\n constructor(\n val tenantId: String,\n val filter: DesignFilter = DesignFilter(),\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignFilter\n @JvmOverloads\n constructor(\n val entityType: DesignEntityType? = null,\n val hostingMode: DesignHostingMode? = null,\n val binding: DesignBinding? = null,\n val bindingKey: DesignBindingKey? = null,\n val bindingValue: String? = null,\n val aliasContains: String? = null,\n val sourceType: DesignSourceType? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignEntityType {\n CREDENTIAL,\n ISSUER,\n VERIFIER,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}" }, "FindByBindingKeyArgs": { "kind": "data class", @@ -27,19 +27,19 @@ "kind": "data class", "name": "ImportExternalDesignArgs", "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class ImportExternalDesignArgs(\n val tenantId: String,\n val input: ImportExternalDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class ImportExternalDesignInput\n @JvmOverloads\n constructor(\n val entityType: DesignEntityType,\n val bindings: List,\n val alias: String? = null,\n val sourceUrl: String,\n val sourceType: DesignSourceType,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignEntityType {\n CREDENTIAL,\n ISSUER,\n VERIFIER,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}" + "source": "@JsExportCompat\n@Serializable\ndata class ImportExternalDesignArgs(\n val tenantId: String,\n val input: ImportExternalDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class ImportExternalDesignInput\n @JvmOverloads\n constructor(\n val entityType: DesignEntityType,\n val bindings: List,\n val alias: String? = null,\n val sourceUrl: String,\n val sourceType: DesignSourceType,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignEntityType {\n CREDENTIAL,\n ISSUER,\n VERIFIER,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}" }, "ResolveCredentialDesignArgs": { "kind": "data class", "name": "ResolveCredentialDesignArgs", "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class ResolveCredentialDesignArgs(\n val tenantId: String,\n val input: ResolveCredentialDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class ResolveCredentialDesignInput\n @JvmOverloads\n constructor(\n val designId: Uuid? = null,\n val binding: DesignBinding? = null,\n val bindingKey: DesignBindingKey? = null,\n val bindingValue: String? = null,\n val preferredLocales: List = emptyList(),\n val renderTarget: RenderVariantKind? = null,\n val externalMetadata: ExternalDesignMetadata? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}\n\n@JsExportCompat\n@Serializable\nenum class RenderVariantKind {\n SIMPLE_CARD,\n SVG_TEMPLATE,\n W3C_RENDER_METHOD,\n PDF_TEMPLATE,\n EXTERNAL_REFERENCE,\n}\n\n@JsExportCompat\n@Serializable\ndata class ExternalDesignMetadata\n @JvmOverloads\n constructor(\n val sdJwtVctMetadata: JsonObject? = null,\n val oid4vciCredentialConfiguration: JsonObject? = null,\n val oid4vciIssuerMetadata: JsonObject? = null,\n val sdJwtIssuerMetadata: JsonObject? = null,\n val jsonSchema: JsonObject? = null,\n val jsonLdContext: JsonObject? = null,\n val oidcDiscovery: JsonObject? = null,\n val openIdFederationEntity: JsonObject? = null,\n val oauthClientRegistration: JsonObject? = null,\n val eidasRegistryData: JsonObject? = null,\n val eidasCatalogueData: JsonObject? = null,\n val w3cRenderMethod: JsonObject? = null,\n val ocaBundle: JsonObject? = null,\n val ocaCaptureBase: JsonObject? = null,\n val ocaOverlays: List = emptyList(),\n val ocaFile: String? = null,\n val overlayFiles: List = emptyList(),\n )" + "source": "@JsExportCompat\n@Serializable\ndata class ResolveCredentialDesignArgs(\n val tenantId: String,\n val input: ResolveCredentialDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class ResolveCredentialDesignInput\n @JvmOverloads\n constructor(\n val designId: Uuid? = null,\n val binding: DesignBinding? = null,\n val bindingKey: DesignBindingKey? = null,\n val bindingValue: String? = null,\n val preferredLocales: List = emptyList(),\n val renderTarget: RenderVariantKind? = null,\n val externalMetadata: ExternalDesignMetadata? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}\n\n@JsExportCompat\n@Serializable\nenum class RenderVariantKind {\n SIMPLE_CARD,\n SVG_TEMPLATE,\n W3C_RENDER_METHOD,\n PDF_TEMPLATE,\n EXTERNAL_REFERENCE,\n}\n\n@JsExportCompat\n@Serializable\ndata class ExternalDesignMetadata\n @JvmOverloads\n constructor(\n val sdJwtVctMetadata: JsonObject? = null,\n val oid4vciCredentialConfiguration: JsonObject? = null,\n val oid4vciIssuerMetadata: JsonObject? = null,\n val sdJwtIssuerMetadata: JsonObject? = null,\n val jsonSchema: JsonObject? = null,\n val jsonLdContext: JsonObject? = null,\n val oidcDiscovery: JsonObject? = null,\n val openIdFederationEntity: JsonObject? = null,\n val oauthClientRegistration: JsonObject? = null,\n val eidasRegistryData: JsonObject? = null,\n val eidasCatalogueData: JsonObject? = null,\n val w3cRenderMethod: JsonObject? = null,\n val ocaBundle: JsonObject? = null,\n val ocaCaptureBase: JsonObject? = null,\n val ocaOverlays: List = emptyList(),\n val ocaFile: String? = null,\n val overlayFiles: List = emptyList(),\n )" }, "ResolvedCredentialDesign": { "kind": "data class", "name": "ResolvedCredentialDesign", "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class ResolvedCredentialDesign\n @JvmOverloads\n constructor(\n val design: CredentialDesignRecord,\n val issuerDesign: IssuerDesignRecord? = null,\n val verifierDesign: VerifierDesignRecord? = null,\n val renderVariants: List,\n val derivedRenderHints: DerivedRenderHintsRecord? = null,\n val appliedLayers: List,\n @JsExportIgnoreCompat\n val lockedFields: Map,\n val resolvedAt: Instant,\n val etag: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class CredentialDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val credentialTemplateId: Uuid? = null,\n val issuerDesignId: Uuid? = null,\n val displays: List,\n val claims: List = emptyList(),\n val renderVariantIds: List = emptyList(),\n val derivedRenderHintsId: Uuid? = null,\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n /** Optional OCA semantic attribute set this design draws from. When present, the OCA-backed\n * credential-design resolution derives selective-disclosure and mandatory flags from it. */\n val semanticAttributeSetRef: SemanticAttributeSetRef? = null,\n /** Optional attribute-profile this design draws from. When present, credential-design\n * resolution derives selective-disclosure and mandatory flags from the profile's resolved\n * effective projection in preference to [semanticAttributeSetRef]. The id and pinned\n * version are held as primitives so this IDK contract stays free of the EDK profile types. */\n val attributeProfileId: Uuid? = null,\n val attributeProfileVersion: Long? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n val credentialType: CredentialTypeDescriptor? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class IssuerDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val partyId: Uuid? = null,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n )\n\n@JsExportCompat\n@Serializable\ndata class VerifierDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val partyId: Uuid? = null,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n )\n\n@JsExportCompat\n@Serializable\ndata class RenderVariantRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val kind: RenderVariantKind,\n val alias: String? = null,\n val localeApplicability: List = emptyList(),\n val sourceSnapshotId: Uuid? = null,\n val logo: AssetReference? = null,\n val backgroundImage: AssetReference? = null,\n val backgroundColor: String? = null,\n val textColor: String? = null,\n val accentColor: String? = null,\n val svgTemplate: SvgTemplate? = null,\n val w3cRenderMethod: W3cRenderMethodReference? = null,\n val pdfTemplate: AssetReference? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DerivedRenderHintsRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val sourceSnapshotIds: List = emptyList(),\n val fieldHints: List,\n @JsExportIgnoreCompat\n val groupHints: Map> = emptyMap(),\n val defaultOrdering: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class AppliedDesignLayer\n @JvmOverloads\n constructor(\n val sourceType: DesignSourceType,\n val sourceUrl: String? = null,\n val priority: Int,\n val authoritative: Boolean = false,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\ndata class LocalizedCredentialDisplay\n @JvmOverloads\n constructor(\n val locale: String,\n val name: String,\n val description: String? = null,\n val issuerNameOverride: String? = null,\n val preferredRenderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class ClaimPresentation\n @JvmOverloads\n constructor(\n val path: DesignClaimPath,\n val labels: List,\n val mandatory: Boolean = false,\n val sdPolicy: SdPolicy = SdPolicy.ALLOWED,\n val order: Int = 0,\n val group: String? = null,\n val svgId: String? = null,\n val valueKind: ClaimValueKind? = null,\n val widgetHint: ClaimWidgetHint? = null,\n val markdownAllowed: Boolean = false,\n val entryCodes: List? = null,\n val unit: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class SemanticAttributeSetRef(\n /** OCA bundle / vocabulary identifier. */\n val bundleId: String,\n /** Optional pinned bundle version; null = resolve the current version. */\n val version: String? = null,\n)\n\n@JsExportCompat\n@Serializable\ndata class EntityLocaleDesign\n @JvmOverloads\n constructor(\n val locale: String,\n val displayName: String? = null,\n val description: String? = null,\n )" + "source": "@JsExportCompat\n@Serializable\ndata class ResolvedCredentialDesign\n @JvmOverloads\n constructor(\n val design: CredentialDesignRecord,\n val issuerDesign: IssuerDesignRecord? = null,\n val verifierDesign: VerifierDesignRecord? = null,\n val renderVariants: List,\n val derivedRenderHints: DerivedRenderHintsRecord? = null,\n val appliedLayers: List,\n @JsExportIgnoreCompat\n val lockedFields: Map,\n val resolvedAt: Instant,\n val etag: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class CredentialDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val credentialTemplateId: Uuid? = null,\n val issuerDesignId: Uuid? = null,\n val displays: List,\n val claims: List = emptyList(),\n val renderVariantIds: List = emptyList(),\n val derivedRenderHintsId: Uuid? = null,\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n /** Optional OCA semantic attribute set this design draws from. When present, the OCA-backed\n * credential-design resolution derives selective-disclosure and mandatory flags from it. */\n val semanticAttributeSetRef: SemanticAttributeSetRef? = null,\n /** Optional attribute-profile this design draws from. When present, credential-design\n * resolution derives selective-disclosure and mandatory flags from the profile's resolved\n * effective projection in preference to [semanticAttributeSetRef]. The id and pinned\n * version are held as primitives so this IDK contract stays free of the EDK profile types. */\n val attributeProfileId: Uuid? = null,\n val attributeProfileVersion: Long? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n val credentialType: CredentialTypeDescriptor? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class IssuerDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val partyId: Uuid? = null,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n )\n\n@JsExportCompat\n@Serializable\ndata class VerifierDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val partyId: Uuid? = null,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n )\n\n@JsExportCompat\n@Serializable\ndata class RenderVariantRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val kind: RenderVariantKind,\n val alias: String? = null,\n val localeApplicability: List = emptyList(),\n val sourceSnapshotId: Uuid? = null,\n val logo: AssetReference? = null,\n val backgroundImage: AssetReference? = null,\n val backgroundColor: String? = null,\n val textColor: String? = null,\n val accentColor: String? = null,\n val svgTemplate: SvgTemplate? = null,\n val w3cRenderMethod: W3cRenderMethodReference? = null,\n val pdfTemplate: AssetReference? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DerivedRenderHintsRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val sourceSnapshotIds: List = emptyList(),\n val fieldHints: List,\n @JsExportIgnoreCompat\n val groupHints: Map> = emptyMap(),\n val defaultOrdering: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class AppliedDesignLayer\n @JvmOverloads\n constructor(\n val sourceType: DesignSourceType,\n val sourceUrl: String? = null,\n val priority: Int,\n val authoritative: Boolean = false,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\ndata class LocalizedCredentialDisplay\n @JvmOverloads\n constructor(\n val locale: String,\n val name: String,\n val description: String? = null,\n val issuerNameOverride: String? = null,\n val preferredRenderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class ClaimPresentation\n @JvmOverloads\n constructor(\n val path: DesignClaimPath,\n val labels: List,\n val mandatory: Boolean = false,\n val sdPolicy: SdPolicy = SdPolicy.ALLOWED,\n val order: Int = 0,\n val group: String? = null,\n val svgId: String? = null,\n val valueKind: ClaimValueKind? = null,\n val widgetHint: ClaimWidgetHint? = null,\n val markdownAllowed: Boolean = false,\n val entryCodes: List? = null,\n val unit: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class SemanticAttributeSetRef(\n /** OCA bundle / vocabulary identifier. */\n val bundleId: String,\n /** Optional pinned bundle version; null = resolve the current version. */\n val version: String? = null,\n)\n\n@JsExportCompat\n@Serializable\ndata class EntityLocaleDesign\n @JvmOverloads\n constructor(\n val locale: String,\n val displayName: String? = null,\n val description: String? = null,\n )" }, "GetCredentialDesignArgs": { "kind": "data class", @@ -51,7 +51,7 @@ "kind": "data class", "name": "UpdateCredentialDesignArgs", "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class UpdateCredentialDesignArgs(\n val tenantId: String,\n val id: Uuid,\n val input: UpdateCredentialDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class UpdateCredentialDesignInput\n @JvmOverloads\n constructor(\n val alias: String? = null,\n val bindings: List? = null,\n val credentialTemplateId: Uuid? = null,\n val issuerDesignId: Uuid? = null,\n val displays: List? = null,\n val claims: List? = null,\n val renderVariantIds: List? = null,\n val hostingMode: DesignHostingMode? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\ndata class LocalizedCredentialDisplay\n @JvmOverloads\n constructor(\n val locale: String,\n val name: String,\n val description: String? = null,\n val issuerNameOverride: String? = null,\n val preferredRenderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class ClaimPresentation\n @JvmOverloads\n constructor(\n val path: DesignClaimPath,\n val labels: List,\n val mandatory: Boolean = false,\n val sdPolicy: SdPolicy = SdPolicy.ALLOWED,\n val order: Int = 0,\n val group: String? = null,\n val svgId: String? = null,\n val valueKind: ClaimValueKind? = null,\n val widgetHint: ClaimWidgetHint? = null,\n val markdownAllowed: Boolean = false,\n val entryCodes: List? = null,\n val unit: String? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}" + "source": "@JsExportCompat\n@Serializable\ndata class UpdateCredentialDesignArgs(\n val tenantId: String,\n val id: Uuid,\n val input: UpdateCredentialDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class UpdateCredentialDesignInput\n @JvmOverloads\n constructor(\n val alias: String? = null,\n val bindings: List? = null,\n val credentialTemplateId: Uuid? = null,\n val issuerDesignId: Uuid? = null,\n val displays: List? = null,\n val claims: List? = null,\n val renderVariantIds: List? = null,\n val hostingMode: DesignHostingMode? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\ndata class LocalizedCredentialDisplay\n @JvmOverloads\n constructor(\n val locale: String,\n val name: String,\n val description: String? = null,\n val issuerNameOverride: String? = null,\n val preferredRenderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class ClaimPresentation\n @JvmOverloads\n constructor(\n val path: DesignClaimPath,\n val labels: List,\n val mandatory: Boolean = false,\n val sdPolicy: SdPolicy = SdPolicy.ALLOWED,\n val order: Int = 0,\n val group: String? = null,\n val svgId: String? = null,\n val valueKind: ClaimValueKind? = null,\n val widgetHint: ClaimWidgetHint? = null,\n val markdownAllowed: Boolean = false,\n val entryCodes: List? = null,\n val unit: String? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}" }, "DeleteDesignArgs": { "kind": "data class", @@ -69,25 +69,25 @@ "kind": "data class", "name": "CreateIssuerDesignArgs", "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class CreateIssuerDesignArgs(\n val tenantId: String,\n val input: CreateIssuerDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class CreateIssuerDesignInput\n @JvmOverloads\n constructor(\n val bindings: List,\n val partyId: Uuid? = null,\n val alias: String? = null,\n val hostingMode: DesignHostingMode = DesignHostingMode.LOCAL,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\ndata class EntityLocaleDesign\n @JvmOverloads\n constructor(\n val locale: String,\n val displayName: String? = null,\n val description: String? = null,\n )" + "source": "@JsExportCompat\n@Serializable\ndata class CreateIssuerDesignArgs(\n val tenantId: String,\n val input: CreateIssuerDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class CreateIssuerDesignInput\n @JvmOverloads\n constructor(\n val bindings: List,\n val partyId: Uuid? = null,\n val alias: String? = null,\n val hostingMode: DesignHostingMode = DesignHostingMode.LOCAL,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\ndata class EntityLocaleDesign\n @JvmOverloads\n constructor(\n val locale: String,\n val displayName: String? = null,\n val description: String? = null,\n )" }, "IssuerDesignRecord": { "kind": "data class", "name": "IssuerDesignRecord", "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class IssuerDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val partyId: Uuid? = null,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\ndata class EntityLocaleDesign\n @JvmOverloads\n constructor(\n val locale: String,\n val displayName: String? = null,\n val description: String? = null,\n )" + "source": "@JsExportCompat\n@Serializable\ndata class IssuerDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val partyId: Uuid? = null,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\ndata class EntityLocaleDesign\n @JvmOverloads\n constructor(\n val locale: String,\n val displayName: String? = null,\n val description: String? = null,\n )" }, "ResolveIssuerDesignArgs": { "kind": "data class", "name": "ResolveIssuerDesignArgs", "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class ResolveIssuerDesignArgs(\n val tenantId: String,\n val input: ResolveEntityDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class ResolveEntityDesignInput\n @JvmOverloads\n constructor(\n val designId: Uuid? = null,\n val binding: DesignBinding? = null,\n val bindingKey: DesignBindingKey? = null,\n val bindingValue: String? = null,\n val preferredLocales: List = emptyList(),\n val externalMetadata: ExternalDesignMetadata? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}\n\n@JsExportCompat\n@Serializable\ndata class ExternalDesignMetadata\n @JvmOverloads\n constructor(\n val sdJwtVctMetadata: JsonObject? = null,\n val oid4vciCredentialConfiguration: JsonObject? = null,\n val oid4vciIssuerMetadata: JsonObject? = null,\n val sdJwtIssuerMetadata: JsonObject? = null,\n val jsonSchema: JsonObject? = null,\n val jsonLdContext: JsonObject? = null,\n val oidcDiscovery: JsonObject? = null,\n val openIdFederationEntity: JsonObject? = null,\n val oauthClientRegistration: JsonObject? = null,\n val eidasRegistryData: JsonObject? = null,\n val eidasCatalogueData: JsonObject? = null,\n val w3cRenderMethod: JsonObject? = null,\n val ocaBundle: JsonObject? = null,\n val ocaCaptureBase: JsonObject? = null,\n val ocaOverlays: List = emptyList(),\n val ocaFile: String? = null,\n val overlayFiles: List = emptyList(),\n )" + "source": "@JsExportCompat\n@Serializable\ndata class ResolveIssuerDesignArgs(\n val tenantId: String,\n val input: ResolveEntityDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class ResolveEntityDesignInput\n @JvmOverloads\n constructor(\n val designId: Uuid? = null,\n val binding: DesignBinding? = null,\n val bindingKey: DesignBindingKey? = null,\n val bindingValue: String? = null,\n val preferredLocales: List = emptyList(),\n val externalMetadata: ExternalDesignMetadata? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}\n\n@JsExportCompat\n@Serializable\ndata class ExternalDesignMetadata\n @JvmOverloads\n constructor(\n val sdJwtVctMetadata: JsonObject? = null,\n val oid4vciCredentialConfiguration: JsonObject? = null,\n val oid4vciIssuerMetadata: JsonObject? = null,\n val sdJwtIssuerMetadata: JsonObject? = null,\n val jsonSchema: JsonObject? = null,\n val jsonLdContext: JsonObject? = null,\n val oidcDiscovery: JsonObject? = null,\n val openIdFederationEntity: JsonObject? = null,\n val oauthClientRegistration: JsonObject? = null,\n val eidasRegistryData: JsonObject? = null,\n val eidasCatalogueData: JsonObject? = null,\n val w3cRenderMethod: JsonObject? = null,\n val ocaBundle: JsonObject? = null,\n val ocaCaptureBase: JsonObject? = null,\n val ocaOverlays: List = emptyList(),\n val ocaFile: String? = null,\n val overlayFiles: List = emptyList(),\n )" }, "ResolvedIssuerDesign": { "kind": "data class", "name": "ResolvedIssuerDesign", "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class ResolvedIssuerDesign\n @JvmOverloads\n constructor(\n val design: IssuerDesignRecord,\n val renderVariants: List,\n val appliedLayers: List,\n @JsExportIgnoreCompat\n val lockedFields: Map,\n val resolvedAt: Instant,\n val etag: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class IssuerDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val partyId: Uuid? = null,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n )\n\n@JsExportCompat\n@Serializable\ndata class RenderVariantRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val kind: RenderVariantKind,\n val alias: String? = null,\n val localeApplicability: List = emptyList(),\n val sourceSnapshotId: Uuid? = null,\n val logo: AssetReference? = null,\n val backgroundImage: AssetReference? = null,\n val backgroundColor: String? = null,\n val textColor: String? = null,\n val accentColor: String? = null,\n val svgTemplate: SvgTemplate? = null,\n val w3cRenderMethod: W3cRenderMethodReference? = null,\n val pdfTemplate: AssetReference? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class AppliedDesignLayer\n @JvmOverloads\n constructor(\n val sourceType: DesignSourceType,\n val sourceUrl: String? = null,\n val priority: Int,\n val authoritative: Boolean = false,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\ndata class EntityLocaleDesign\n @JvmOverloads\n constructor(\n val locale: String,\n val displayName: String? = null,\n val description: String? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class RenderVariantKind {\n SIMPLE_CARD,\n SVG_TEMPLATE,\n W3C_RENDER_METHOD,\n PDF_TEMPLATE,\n EXTERNAL_REFERENCE,\n}\n\n@JsExportCompat\n@Serializable\ndata class AssetReference\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val altText: String? = null,\n val contentType: String? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class SvgTemplate\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val orientation: SvgOrientation? = null,\n val colorScheme: SvgColorScheme? = null,\n val contrast: SvgContrast? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class W3cRenderMethodReference\n @JvmOverloads\n constructor(\n val type: String,\n val renderSuite: String? = null,\n val uri: String,\n val mediaType: String? = null,\n val name: String? = null,\n val description: String? = null,\n val digestMultibase: String? = null,\n val renderProperties: List? = null,\n )" + "source": "@JsExportCompat\n@Serializable\ndata class ResolvedIssuerDesign\n @JvmOverloads\n constructor(\n val design: IssuerDesignRecord,\n val renderVariants: List,\n val appliedLayers: List,\n @JsExportIgnoreCompat\n val lockedFields: Map,\n val resolvedAt: Instant,\n val etag: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class IssuerDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val partyId: Uuid? = null,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n )\n\n@JsExportCompat\n@Serializable\ndata class RenderVariantRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val kind: RenderVariantKind,\n val alias: String? = null,\n val localeApplicability: List = emptyList(),\n val sourceSnapshotId: Uuid? = null,\n val logo: AssetReference? = null,\n val backgroundImage: AssetReference? = null,\n val backgroundColor: String? = null,\n val textColor: String? = null,\n val accentColor: String? = null,\n val svgTemplate: SvgTemplate? = null,\n val w3cRenderMethod: W3cRenderMethodReference? = null,\n val pdfTemplate: AssetReference? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class AppliedDesignLayer\n @JvmOverloads\n constructor(\n val sourceType: DesignSourceType,\n val sourceUrl: String? = null,\n val priority: Int,\n val authoritative: Boolean = false,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\ndata class EntityLocaleDesign\n @JvmOverloads\n constructor(\n val locale: String,\n val displayName: String? = null,\n val description: String? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class RenderVariantKind {\n SIMPLE_CARD,\n SVG_TEMPLATE,\n W3C_RENDER_METHOD,\n PDF_TEMPLATE,\n EXTERNAL_REFERENCE,\n}\n\n@JsExportCompat\n@Serializable\ndata class AssetReference\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val altText: String? = null,\n val contentType: String? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class SvgTemplate\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val orientation: SvgOrientation? = null,\n val colorScheme: SvgColorScheme? = null,\n val contrast: SvgContrast? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class W3cRenderMethodReference\n @JvmOverloads\n constructor(\n val type: String,\n val renderSuite: String? = null,\n val uri: String,\n val mediaType: String? = null,\n val name: String? = null,\n val description: String? = null,\n val digestMultibase: String? = null,\n val renderProperties: List? = null,\n )" }, "CreateRenderVariantArgs": { "kind": "data class", @@ -105,7 +105,7 @@ "kind": "data class", "name": "ListRenderVariantsArgs", "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class ListRenderVariantsArgs\n @JvmOverloads\n constructor(\n val tenantId: String,\n val filter: DesignFilter = DesignFilter(),\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignFilter\n @JvmOverloads\n constructor(\n val entityType: DesignEntityType? = null,\n val hostingMode: DesignHostingMode? = null,\n val binding: DesignBinding? = null,\n val bindingKey: DesignBindingKey? = null,\n val bindingValue: String? = null,\n val aliasContains: String? = null,\n val sourceType: DesignSourceType? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignEntityType {\n CREDENTIAL,\n ISSUER,\n VERIFIER,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}" + "source": "@JsExportCompat\n@Serializable\ndata class ListRenderVariantsArgs\n @JvmOverloads\n constructor(\n val tenantId: String,\n val filter: DesignFilter = DesignFilter(),\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignFilter\n @JvmOverloads\n constructor(\n val entityType: DesignEntityType? = null,\n val hostingMode: DesignHostingMode? = null,\n val binding: DesignBinding? = null,\n val bindingKey: DesignBindingKey? = null,\n val bindingValue: String? = null,\n val aliasContains: String? = null,\n val sourceType: DesignSourceType? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignEntityType {\n CREDENTIAL,\n ISSUER,\n VERIFIER,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}" }, "GetSourceSnapshotArgs": { "kind": "data class", diff --git a/connector-components.yml b/connector-components.yml index 4fc0e22..4219015 100644 --- a/connector-components.yml +++ b/connector-components.yml @@ -62,6 +62,38 @@ components: schema: $ref: '#/components/schemas/ConnectorRunId' example: 9a785884-63ea-4b07-9976-264a1fc595f1 + InvocationBindingId: + name: invocationBindingId + in: path + description: Stable identifier of a connector invocation binding. + required: true + schema: + $ref: '#/components/schemas/ConnectorInvocationBindingId' + example: issuer-config-1:post-issuance:proof-vault + LogicalConnectionBindingId: + name: logicalConnectionBindingId + in: path + description: Stable identifier of a logical connection binding. + required: true + schema: + $ref: '#/components/schemas/LogicalConnectionBindingId' + example: brand-a-proof-vault + ExposureDescriptorId: + name: exposureDescriptorId + in: path + description: Stable identifier of a route exposure descriptor. + required: true + schema: + $ref: '#/components/schemas/RouteExposureDescriptorId' + example: proof-vault-read-exposure + DataProductId: + name: dataProductId + in: path + description: Stable identifier of a connector data product descriptor. + required: true + schema: + $ref: '#/components/schemas/ConnectorDataProductId' + example: dp-proof-status Role: name: role in: query @@ -102,6 +134,70 @@ components: schema: $ref: '#/components/schemas/ConnectorRunStatus' example: FAILED + RouteIdQuery: + name: routeId + in: query + description: Filters connector executions by route id. + required: false + schema: + $ref: '#/components/schemas/ConnectorRouteId' + example: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + ConnectorInstanceIdQuery: + name: connectorInstanceId + in: query + description: Filters connector executions by the registry connector instance id. + required: false + schema: + $ref: '#/components/schemas/ConnectorInstanceId' + example: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + InvocationBindingIdQuery: + name: invocationBindingId + in: query + description: Filters connector executions by Phase 5 invocation binding lineage. + required: false + schema: + $ref: '#/components/schemas/ConnectorInvocationBindingId' + example: issuer-config-1:post-issuance:proof-vault + LogicalConnectionBindingIdQuery: + name: logicalConnectionBindingId + in: query + description: Filters connector executions by logical connection binding lineage. + required: false + schema: + $ref: '#/components/schemas/LogicalConnectionBindingId' + example: brand-a-proof-vault + PhysicalConnectorInstanceIdQuery: + name: physicalConnectorInstanceId + in: query + description: Filters connector executions by physical connector instance lineage. + required: false + schema: + $ref: '#/components/schemas/ConnectorInstanceId' + example: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + ConnectorExchangeModeQuery: + name: exchangeMode + in: query + description: Filters connector executions by the Phase 5 data-direction and initiation-side quadrant. + required: false + schema: + $ref: '#/components/schemas/ConnectorExchangeMode' + example: PLATFORM_INITIATED_PUSH + ProtocolSurfaceQuery: + name: protocolSurface + in: query + description: Filters connector executions by the product, protocol, form, portal, workflow, or application surface that initiated the run. + required: false + schema: + $ref: '#/components/schemas/ConnectorOwnerSurface' + example: OID4VCI + CorrelationIdQuery: + name: correlationId + in: query + description: Filters connector executions by durable route-run correlation id. + required: false + schema: + type: string + example: route-correlation-1 schemas: ConnectorInstanceId: @@ -169,6 +265,22 @@ components: format: uuid description: Stable identifier for a connector route or operation run. example: 9a785884-63ea-4b07-9976-264a1fc595f1 + ConnectorInvocationBindingId: + type: string + description: Stable identifier of the domain invocation binding that caused a connector call. + example: issuer-config-1:post-issuance:proof-vault + LogicalConnectionBindingId: + type: string + description: Stable identifier of a tenant, OU, brand, legal-entity, or channel usage binding for a physical connector instance. + example: brand-a-proof-vault + RouteExposureDescriptorId: + type: string + description: Stable identifier of an externally callable route exposure descriptor. + example: proof-vault-read-exposure + ConnectorDataProductId: + type: string + description: Stable identifier of a connector data product descriptor. + example: dp-proof-status ConnectorType: type: string description: Extensible connector family identifier. This names the connector implementation or adapter family, not the transport, resource kind, or representation. @@ -180,11 +292,10 @@ components: DataFlowRole: type: string - description: How a connector participates in data movement. Use SOURCE for reads, DESTINATION for writes, and SOURCE_AND_DESTINATION for systems that can do both. + description: How a connector participates in data movement. Use SOURCE for reads and DESTINATION for writes. Connectors that support both roles declare both values in supportedRoles. enum: - SOURCE - DESTINATION - - SOURCE_AND_DESTINATION example: SOURCE ConnectorLifecycleStatus: type: string @@ -197,11 +308,10 @@ components: example: ACTIVE ConnectorManagementMode: type: string - description: Indicates whether the platform manages the connector runtime/configuration, references an externally managed system, or uses a hybrid model. + description: Indicates whether the platform manages connector runtime/configuration or references an externally managed system. Runtime placement is described separately by runtimeMode. enum: - MANAGED - EXTERNAL - - HYBRID example: EXTERNAL ConnectorRuntimeMode: type: string @@ -211,6 +321,149 @@ components: - REMOTE_AGENT - EXTERNAL_CALLBACK example: REMOTE_AGENT + ConnectorExchangeMode: + type: string + description: Explicit exchange quadrant. Data direction and initiation side remain separate axes in run responses. + enum: + - PLATFORM_INITIATED_PULL + - PLATFORM_INITIATED_PUSH + - EXTERNALLY_INITIATED_READ_FROM_VDX + - EXTERNALLY_INITIATED_WRITE_INTO_VDX + - SUBSCRIPTION_CALLBACK + - BIDIRECTIONAL_SYNC + example: PLATFORM_INITIATED_PUSH + ConnectorDataDirection: + type: string + description: Direction of data movement relative to VDX. + enum: + - INTO_VDX + - OUT_OF_VDX + - BIDIRECTIONAL + example: OUT_OF_VDX + ConnectorInitiationSide: + type: string + description: Side that initiated the exchange. + enum: + - PLATFORM + - EXTERNAL + - SUBSCRIPTION_CALLBACK + - BIDIRECTIONAL_SYNC + example: PLATFORM + ConnectorOwnerSurface: + type: string + description: Product, protocol, form, portal, workflow, or application surface that owns a connector invocation binding. + enum: + - OID4VCI + - OID4VP + - FORM + - PORTAL + - WORKFLOW + - APPLICATION + example: OID4VCI + ConnectorInvocationStage: + type: string + description: Product or protocol lifecycle stage at which a connector invocation can run. + enum: + - OID4VCI_AUTHORIZATION + - OID4VCI_PRE_AUTHORIZED + - OID4VCI_TOKEN + - OID4VCI_CREDENTIAL_REQUEST + - OID4VCI_DEFERRED + - OID4VCI_PRE_ISSUE + - OID4VCI_POST_ISSUANCE + - OID4VCI_NOTIFICATION_RECEIPT + - OID4VP_AFTER_VALIDATION + - OID4VP_PRE_REQUEST_ENRICHMENT + - FORM_LIFECYCLE + - FORM_ACTION_START + - FORM_ACTION_COMPLETE + - FORM_FIELD_LOOKUP + - FORM_SUBMIT + - PORTAL_FLOW + - WORKFLOW_STEP_EXECUTION + example: OID4VCI_POST_ISSUANCE + ConnectorInvocationRole: + type: string + description: Role the connector performs for a lifecycle invocation. + enum: + - ENRICHMENT_SOURCE + - EXPORT_DESTINATION + - VAULT_RETENTION + - NOTIFICATION + - BIDIRECTIONAL_SYNC + - ROUTE_ORCHESTRATION + example: VAULT_RETENTION + ConnectorExecutionTiming: + type: string + description: Timing contract for connector invocation execution. + enum: + - INLINE_REQUIRED + - INLINE_OPTIONAL + - DEFERRED_ASYNC + - DURABLE_OUTBOX + example: INLINE_REQUIRED + ConnectorFailureEffect: + type: string + description: How connector invocation failure affects the owning protocol, form, portal, or workflow. + enum: + - FAIL_PROTOCOL + - CONTINUE_WITHOUT_EFFECT + - DEAD_LETTER + - QUARANTINE + - RETRY_ONLY + example: FAIL_PROTOCOL + ConnectorDiscriminatorSource: + type: string + description: Source of a logical connection discriminator value. + enum: + - LOGICAL_CONTEXT + - AUTHENTICATED_CONTEXT + - PAYLOAD_FIELD + - STATIC_VALUE + example: LOGICAL_CONTEXT + ConnectorDiscriminatorPlacement: + type: string + description: Where a logical connection discriminator is applied to an outbound connector request. + enum: + - HEADER + - QUERY + - BODY_FIELD + - CONFIG + - METADATA + example: HEADER + ConnectorAuthOverlayMode: + type: string + description: Authentication overlay mode for a logical connection binding. + enum: + - USE_PHYSICAL_BASE + - TENANT_SECRET_REF + - DELEGATED_OAUTH_CLIENT + - MTLS_IDENTITY + - CONNECTOR_CREDENTIAL_SELECTOR + example: TENANT_SECRET_REF + ConnectorDeploymentMode: + type: string + description: Deployment mode projected into the system catalog for a logical connection binding. + enum: + - MANAGED + - EXTERNAL + - HYBRID + example: HYBRID + ConnectorAuditCategory: + type: string + description: Audit category used by governed connector invocations, runs, and externally callable route exposures. + enum: + - PROTOCOL_ISSUANCE + - PROTOCOL_VERIFICATION + - FORM + - PORTAL + - WORKFLOW + - DATASPACE + - INDUSTRIAL + - EXTERNAL_EXCHANGE + - VAULT + - SYSTEM_CATALOG + example: EXTERNAL_EXCHANGE OperationKind: type: string description: Reusable operation taxonomy shared by connectors, inventory, policy, and workflows. The operation kind is logical; connector-local details live in operationName. @@ -224,12 +477,19 @@ components: - SEARCH - IMPORT - EXPORT - - STREAM_READ - - STREAM_WRITE - INVOKE - DISCOVER - VALIDATE example: READ + OperationTransferMode: + type: string + description: Transfer semantics for an operation binding. Streaming and batching are execution modes of a logical operation, not operation kinds. + enum: + - SINGLE + - BATCH + - STREAM + default: SINGLE + example: STREAM AccessProtocol: type: string description: "Transport or access protocol. This is intentionally separate from ResourceKind and RepresentationKind: for example, CSV data can be read over HTTPS, S3, SFTP, FILE, or VAULT." @@ -401,11 +661,12 @@ components: ConnectorInstanceCreateRequest: type: object - description: Request to register a connector instance and create or link the backing Party. Identities are optional, but when identifiers are needed they must be nested under an identity. + description: Request to register a connector instance and create or link the backing Party. Identity data is required so the connector aggregate is Party-backed at creation time. required: - displayName - connectorType - supportedRoles + - identities properties: displayName: type: string @@ -422,24 +683,27 @@ components: $ref: '#/components/schemas/ConnectorManagementMode' runtimeMode: $ref: '#/components/schemas/ConnectorRuntimeMode' - ownerPartyId: + partyId: $ref: '#/components/schemas/PartyId' supportedRoles: type: array description: Data-flow roles supported by this connector instance. minItems: 1 + uniqueItems: true items: $ref: '#/components/schemas/DataFlowRole' example: [SOURCE] supportedOperations: type: array description: Logical operations this connector instance can perform. + uniqueItems: true items: $ref: '#/components/schemas/OperationKind' example: [READ, QUERY, DISCOVER] identities: type: array - description: Identities assigned to the connector Party. Identifiers are nested under Identity, matching the Party model. + description: Identities assigned to the connector Party. Exactly one identity must be marked as default. Each identity must reference an existing identity or include at least one identifier. + minItems: 1 items: $ref: '#/components/schemas/ConnectorIdentityInput' endpoints: @@ -523,10 +787,13 @@ components: $ref: '#/components/schemas/ConnectorRuntimeMode' supportedRoles: type: array + minItems: 1 + uniqueItems: true items: $ref: '#/components/schemas/DataFlowRole' supportedOperations: type: array + uniqueItems: true items: $ref: '#/components/schemas/OperationKind' defaultAccessProtocol: @@ -684,6 +951,7 @@ components: identifiers: type: array description: Identifiers attached to this Identity. Identifiers are not attached directly to the connector. + minItems: 1 items: $ref: '#/components/schemas/ConnectorIdentifierInput' example: @@ -790,25 +1058,6 @@ components: isPrimary: true isVerified: true - AttachConnectorIdentityRequest: - type: object - description: Request to attach an Identity to the connector Party. - required: - - identity - properties: - identity: - $ref: '#/components/schemas/ConnectorIdentityInput' - example: - identity: - identityRole: external-system - displayName: Workday tenant acme-prod - isDefault: true - identifiers: - - identifierType: DNS_NAME - value: hr.example.com - isPrimary: true - isVerified: true - ConnectorEndpointInput: type: object description: Endpoint or address used by a connector. The endpoint says how to reach the connector; resource descriptors say what data is exchanged. @@ -1224,7 +1473,7 @@ components: OperationBindingCreateRequest: type: object - description: Request to bind a connector resource to a logical operation. The binding connects connector instance, attached resource, protocol, operation name, optional transformation, and destination delivery policy. + description: Request to bind a connector resource to a logical operation. The binding connects connector instance, attached resource, logical operation, transfer mode, protocol, operation name, optional transformation, and destination delivery policy. required: - connectorInstanceId - connectorResourceId @@ -1236,6 +1485,8 @@ components: $ref: '#/components/schemas/ConnectorResourceId' operationKind: $ref: '#/components/schemas/OperationKind' + transferMode: + $ref: '#/components/schemas/OperationTransferMode' direction: $ref: '#/components/schemas/BindingDirection' accessProtocol: @@ -1260,6 +1511,7 @@ components: connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 connectorResourceId: b4cf21b1-0292-4803-8d32-9ebf9f5359a2 operationKind: READ + transferMode: SINGLE direction: INBOUND accessProtocol: HTTPS operationName: getEmployeeProfile @@ -1278,6 +1530,8 @@ components: properties: operationKind: $ref: '#/components/schemas/OperationKind' + transferMode: + $ref: '#/components/schemas/OperationTransferMode' direction: $ref: '#/components/schemas/BindingDirection' accessProtocol: @@ -1332,6 +1586,7 @@ components: connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 connectorResourceId: b4cf21b1-0292-4803-8d32-9ebf9f5359a2 operationKind: READ + transferMode: SINGLE direction: INBOUND accessProtocol: HTTPS operationName: getEmployeeProfile @@ -1446,170 +1701,1271 @@ components: iri: https://vocab.example.com/employee#email version: '1.0' - TransformationCreateRequest: + ConnectorInvocationBindingCreateRequest: type: object - description: Request to define a reusable transformation from one resource descriptor to another. Attribute mapper steps can coexist with expression-based transformations. + description: Request to persist a connector invocation binding. required: - - displayName - - language + - binding properties: - displayName: - type: string - description: Human-readable transformation name. - example: Employee profile to license invitation - description: - type: string - description: Transformation purpose and scope. - example: Maps HR employee attributes into the invitation payload used by the license issuance flow. - language: - $ref: '#/components/schemas/TransformationLanguage' - sourceDescriptorId: - $ref: '#/components/schemas/ResourceDescriptorId' - targetDescriptorId: - $ref: '#/components/schemas/ResourceDescriptorId' - steps: - type: array - description: Ordered transformation steps for step-based languages. - items: - $ref: '#/components/schemas/TransformationStep' - expression: - type: string - description: Transformation expression for expression-based languages. - example: 'employee.{ "email": email, "subject": givenName & " " & familyName }' - metadata: - $ref: '#/components/schemas/StringMap' + binding: + $ref: '#/components/schemas/ConnectorInvocationBinding' example: - displayName: Employee profile to license invitation - description: Maps HR employee attributes into the invitation payload used by the license issuance flow. - language: ATTRIBUTE_MAPPER - sourceDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b - targetDescriptorId: 7a44f0de-e4d9-44ef-9211-372433933a88 - steps: - - stepType: MAP - sourcePath: email - targetPath: recipient.email - - stepType: MAP - sourcePath: license_type - targetPath: credential.licenseType - - stepType: CONSTANT - targetPath: invitation.channel - value: email - metadata: - mapper_version: '1' + binding: + invocationBindingId: issuer-config-1:post-issuance:proof-vault + ownerSurface: OID4VCI + ownerReference: issuer-config-1 + stage: OID4VCI_POST_ISSUANCE + role: VAULT_RETENTION + target: + routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + exchangeMode: PLATFORM_INITIATED_PUSH + dataDirection: OUT_OF_VDX + initiationSide: PLATFORM + logicalContext: + tenantId: acme + organizationUnitId: nl-ops + brandId: brand-a + logicalConnectionBindingId: brand-a-proof-vault + physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b - TransformationUpdateRequest: + ConnectorInvocationBinding: type: object - description: Partial update for a transformation definition. + description: Persisted binding from an owning product/protocol lifecycle stage to a connector target, logical context, governance envelope, and execution policy. + required: + - invocationBindingId + - ownerSurface + - ownerReference + - stage + - role + - target + - exchangeMode + - logicalContext properties: - displayName: - type: string - description: Updated transformation name. - example: Employee profile to license invitation - description: - type: string - description: Updated transformation description. - example: Maps employee profile rows into the current license invitation payload. - language: - $ref: '#/components/schemas/TransformationLanguage' - sourceDescriptorId: - $ref: '#/components/schemas/ResourceDescriptorId' - targetDescriptorId: - $ref: '#/components/schemas/ResourceDescriptorId' - steps: - type: array - items: - $ref: '#/components/schemas/TransformationStep' - expression: + invocationBindingId: + $ref: '#/components/schemas/ConnectorInvocationBindingId' + ownerSurface: + $ref: '#/components/schemas/ConnectorOwnerSurface' + ownerReference: type: string - description: Updated expression for expression-based transformations. - example: $.employee + description: Owner-specific reference such as issuer configuration id, verifier profile id, form id, portal flow id, or workflow id. + example: issuer-config-1 + stage: + $ref: '#/components/schemas/ConnectorInvocationStage' + role: + $ref: '#/components/schemas/ConnectorInvocationRole' + target: + $ref: '#/components/schemas/ConnectorInvocationTarget' + exchangeMode: + $ref: '#/components/schemas/ConnectorExchangeMode' + dataDirection: + $ref: '#/components/schemas/ConnectorDataDirection' + initiationSide: + $ref: '#/components/schemas/ConnectorInitiationSide' + subsetMapping: + $ref: '#/components/schemas/ConnectorSubsetMapping' + logicalContext: + $ref: '#/components/schemas/ConnectorLogicalContext' + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + physicalConnectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + executionPolicy: + $ref: '#/components/schemas/ConnectorInvocationExecutionPolicy' + governance: + $ref: '#/components/schemas/ConnectorGovernanceEnvelope' + partyAnchors: + $ref: '#/components/schemas/ConnectorPartyAnchorSet' + materializationPolicy: + $ref: '#/components/schemas/MaterializationPolicy' metadata: $ref: '#/components/schemas/StringMap' example: - description: Maps employee profile rows into the current license invitation payload. - steps: - - stepType: MAP - sourcePath: email - targetPath: recipient.email - - stepType: DEFAULT - targetPath: invitation.locale - value: en-US + invocationBindingId: issuer-config-1:post-issuance:proof-vault + ownerSurface: OID4VCI + ownerReference: issuer-config-1 + stage: OID4VCI_POST_ISSUANCE + role: VAULT_RETENTION + target: + routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + exchangeMode: PLATFORM_INITIATED_PUSH + dataDirection: OUT_OF_VDX + initiationSide: PLATFORM + logicalContext: + tenantId: acme + organizationUnitId: nl-ops + brandId: brand-a + logicalConnectionBindingId: brand-a-proof-vault + physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b - TransformationDefinition: - description: Stored transformation definition. - allOf: - - $ref: '#/components/schemas/TransformationCreateRequest' - - type: object - required: - - transformationId - - createdAt - - updatedAt - properties: - transformationId: - $ref: '#/components/schemas/TransformationId' - createdAt: - type: string - format: date-time - description: Creation timestamp. - example: '2026-06-18T09:35:00Z' - updatedAt: - type: string - format: date-time - description: Last update timestamp. - example: '2026-06-18T09:40:00Z' + ConnectorInvocationTarget: + type: object + description: Registry target selected by an invocation binding. + properties: + routeId: + $ref: '#/components/schemas/ConnectorRouteId' + connectorId: + $ref: '#/components/schemas/ConnectorInstanceId' + operationBindingId: + $ref: '#/components/schemas/OperationBindingId' example: - transformationId: 0e60abcc-41b5-4cc5-bec2-f0047f129341 - displayName: Employee profile to license invitation - description: Maps HR employee attributes into the invitation payload used by the license issuance flow. - language: ATTRIBUTE_MAPPER - sourceDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b - targetDescriptorId: 7a44f0de-e4d9-44ef-9211-372433933a88 - steps: - - stepType: MAP - sourcePath: email - targetPath: recipient.email - - stepType: MAP - sourcePath: license_type - targetPath: credential.licenseType - createdAt: '2026-06-18T09:35:00Z' - updatedAt: '2026-06-18T09:40:00Z' + routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f - TransformationStep: + ConnectorLogicalContext: type: object - description: One step in a transformation pipeline. Step semantics are intentionally generic so existing attribute mappers and future expression engines can share the route model. + description: Tenant, OU, brand, legal entity, channel, product, and discriminator context used to resolve a logical connector binding. required: - - stepType + - tenantId properties: - stepType: + tenantId: + $ref: '#/components/schemas/TenantId' + organizationUnitId: type: string - description: Transformation step operation. - enum: - - MAP - - CONSTANT - - DEFAULT - - REQUIRE - - REDACT - - HASH - - LOOKUP - - CUSTOM - example: MAP - sourcePath: + example: nl-ops + brandId: type: string - description: Source path or field used by this step. - example: email - targetPath: + example: brand-a + legalEntityId: type: string - description: Target path or field written by this step. - example: recipient.email - value: - description: Literal value used by CONSTANT or DEFAULT steps. - nullable: true - example: email - expression: + example: legal-entity-a + channel: type: string - description: Optional expression used by LOOKUP, CUSTOM, or expression-based steps. - example: lower($.email) - metadata: + example: web + productId: + type: string + example: employee-license + discriminators: + $ref: '#/components/schemas/StringMap' + example: + tenantId: acme + organizationUnitId: nl-ops + brandId: brand-a + discriminators: + jurisdiction: NL + + ConnectorSubsetMapping: + type: object + description: Field selection, lookup, output mapping, provenance, and minimization rules used by an invocation or exposure. + properties: + lookupInputs: + type: array + items: + $ref: '#/components/schemas/ConnectorFieldSelector' + selectedFields: + type: array + items: + $ref: '#/components/schemas/ConnectorFieldSelector' + producedFields: + type: array + description: Fields an invocation is expected to produce for later connector or protocol stages. + items: + $ref: '#/components/schemas/ConnectorFieldSelector' + outputMappings: + type: array + items: + $ref: '#/components/schemas/ConnectorFieldMapping' + sourceProvenanceFields: + type: array + items: + $ref: '#/components/schemas/ConnectorFieldSelector' + qualityStatusFields: + type: array + items: + $ref: '#/components/schemas/ConnectorFieldSelector' + redactionProfileId: + type: string + example: redact-proof-source + minimizationProfileId: + type: string + example: min-proof-source + example: + lookupInputs: + - protocolClaimPath: credential_subject.id + selectedFields: + - canonicalFieldPath: proof.status + minimizationProfileId: min-proof-source + + ConnectorFieldSelector: + type: object + description: Selector for a canonical, protocol, form, proof, status, source, data product, or semantic field. + properties: + canonicalFieldPath: + type: string + example: proof.status + lookupKey: + type: string + example: employee_id + protocolClaimPath: + type: string + example: credential_subject.email + dcqlCredentialQueryId: + type: string + example: employeeCredential + dcqlClaimId: + type: string + example: email + formFieldPath: + type: string + example: applicant.email + proofRef: + type: string + example: proof://presentation/1 + statusRef: + type: string + example: status://credential/1 + tokenRef: + type: string + example: token://access/1 + sourceFieldPath: + type: string + example: worker.email + dataProductFieldScope: + type: string + example: dpp.asset.serial + contractAgreementTargetRef: + type: string + example: contract-target-1 + semanticReference: + $ref: '#/components/schemas/SemanticReference' + required: + type: boolean + default: true + example: true + + ConnectorFieldMapping: + type: object + description: Mapping from a source selector to a target selector. + required: + - source + - target + properties: + source: + $ref: '#/components/schemas/ConnectorFieldSelector' + target: + $ref: '#/components/schemas/ConnectorFieldSelector' + required: + type: boolean + default: true + example: true + + ConnectorInvocationExecutionPolicy: + type: object + description: Timing, retry, idempotency, and correlation policy for an invocation binding. + properties: + timing: + $ref: '#/components/schemas/ConnectorExecutionTiming' + failureEffect: + $ref: '#/components/schemas/ConnectorFailureEffect' + timeoutMillis: + type: integer + format: int64 + minimum: 0 + example: 30000 + syncWaitWindowMillis: + type: integer + format: int64 + minimum: 0 + example: 5000 + retryPolicy: + $ref: '#/components/schemas/RetryPolicy' + idempotencyKey: + type: string + example: issuer-config-1:offer-123 + correlationId: + type: string + example: protocol-correlation-1 + example: + timing: INLINE_REQUIRED + failureEffect: FAIL_PROTOCOL + timeoutMillis: 30000 + + LogicalConnectionBindingCreateRequest: + type: object + description: Request to persist a logical connection binding. + required: + - binding + properties: + binding: + $ref: '#/components/schemas/LogicalConnectionBinding' + example: + binding: + logicalConnectionBindingId: brand-a-proof-vault + physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + logicalContext: + tenantId: acme + organizationUnitId: nl-ops + brandId: brand-a + + LogicalConnectionBinding: + type: object + description: Logical usage binding for a physical connector instance, including caller context, discriminator rules, auth overlay, grants, governance defaults, and system catalog projection metadata. + required: + - logicalConnectionBindingId + - physicalConnectorInstanceId + - logicalContext + properties: + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + physicalConnectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + logicalContext: + $ref: '#/components/schemas/ConnectorLogicalContext' + callerParty: + $ref: '#/components/schemas/PartyRef' + beneficiaryParty: + $ref: '#/components/schemas/PartyRef' + discriminatorRules: + type: array + items: + $ref: '#/components/schemas/ConnectorDiscriminatorRule' + authOverlay: + $ref: '#/components/schemas/ConnectorAuthOverlay' + grants: + type: array + items: + $ref: '#/components/schemas/LogicalConnectionGrant' + allowedOperations: + type: array + items: + $ref: '#/components/schemas/OperationKind' + defaultSubsetMapping: + $ref: '#/components/schemas/ConnectorSubsetMapping' + defaultGovernance: + $ref: '#/components/schemas/ConnectorGovernanceEnvelope' + defaultMaterializationPolicy: + $ref: '#/components/schemas/MaterializationPolicy' + systemCatalog: + $ref: '#/components/schemas/SystemCatalogProjectionMetadata' + example: + logicalConnectionBindingId: brand-a-proof-vault + physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + logicalContext: + tenantId: acme + organizationUnitId: nl-ops + brandId: brand-a + authOverlay: + mode: TENANT_SECRET_REF + secretRef: vault://tenant/acme/connectors/proof-vault + allowedOperations: [READ, WRITE] + + ConnectorDiscriminatorRule: + type: object + description: Rule for deriving and placing a discriminator value when resolving or invoking a logical connector binding. + required: + - source + - sourceKey + - targetKey + - placement + properties: + source: + $ref: '#/components/schemas/ConnectorDiscriminatorSource' + sourceKey: + type: string + example: brandId + targetKey: + type: string + example: X-Brand-Id + placement: + $ref: '#/components/schemas/ConnectorDiscriminatorPlacement' + required: + type: boolean + default: true + example: true + staticValue: + type: string + example: brand-a + + ConnectorAuthOverlay: + type: object + description: Logical authentication overlay applied on top of the physical connector configuration. + properties: + mode: + $ref: '#/components/schemas/ConnectorAuthOverlayMode' + secretRef: + type: string + example: vault://tenant/acme/connectors/proof-vault + oauthClientRef: + type: string + example: oauth-client://issuer-proof-vault + mtlsIdentityRef: + type: string + example: mtls://identity/issuer-proof-vault + credentialSelector: + type: string + example: tenant-default + example: + mode: TENANT_SECRET_REF + secretRef: vault://tenant/acme/connectors/proof-vault + + LogicalConnectionGrant: + type: object + description: Grant that allows another tenant or caller context to use a logical connection binding. + required: + - grantId + - grantedToTenantId + properties: + grantId: + type: string + example: grant-proof-vault-to-supplier + grantedToTenantId: + $ref: '#/components/schemas/TenantId' + grantedBy: + $ref: '#/components/schemas/PartyRef' + allowedOperations: + type: array + items: + $ref: '#/components/schemas/OperationKind' + active: + type: boolean + default: true + example: true + + SystemCatalogProjectionMetadata: + type: object + description: Party and deployment metadata projected from a logical connection binding into system catalog or governance views. + properties: + operatorParty: + $ref: '#/components/schemas/PartyRef' + vendorSupplierParty: + $ref: '#/components/schemas/PartyRef' + deploymentRegion: + type: string + example: eu-west-1 + managementMode: + $ref: '#/components/schemas/ConnectorManagementMode' + runtimeMode: + $ref: '#/components/schemas/ConnectorRuntimeMode' + deploymentMode: + $ref: '#/components/schemas/ConnectorDeploymentMode' + dataCategoriesTouched: + type: array + items: + type: string + example: [proof-status] + downstreamRecipients: + type: array + items: + $ref: '#/components/schemas/PartyRef' + processorRefs: + type: array + items: + $ref: '#/components/schemas/PartyRef' + + RouteExposureDescriptorCreateRequest: + type: object + description: Request to persist a route exposure descriptor. + required: + - exposure + properties: + exposure: + $ref: '#/components/schemas/RouteExposureDescriptor' + example: + exposure: + exposureDescriptorId: proof-vault-read-exposure + exposedCapabilityId: proof-vault-read + owningTenantId: acme + logicalConnectionBindingId: brand-a-proof-vault + exchangeMode: EXTERNALLY_INITIATED_READ_FROM_VDX + allowedOperation: READ + acceptedAuthMethods: [bearer, mtls] + + RouteExposureDescriptor: + type: object + description: Externally callable connector route capability and its caller, schema, subset, payload, rate, and audit constraints. + required: + - exposureDescriptorId + - exposedCapabilityId + - owningTenantId + - logicalConnectionBindingId + - exchangeMode + - allowedOperation + - acceptedAuthMethods + properties: + exposureDescriptorId: + $ref: '#/components/schemas/RouteExposureDescriptorId' + exposedCapabilityId: + type: string + example: proof-vault-read + owningTenantId: + $ref: '#/components/schemas/TenantId' + organizationUnitId: + type: string + example: nl-ops + brandId: + type: string + example: brand-a + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + exchangeMode: + $ref: '#/components/schemas/ConnectorExchangeMode' + allowedOperation: + $ref: '#/components/schemas/OperationKind' + acceptedAuthMethods: + type: array + items: + type: string + example: [bearer, mtls] + callerPartyConstraints: + type: array + items: + $ref: '#/components/schemas/PartyRef' + callerRelationshipConstraints: + type: array + items: + $ref: '#/components/schemas/RelationshipRef' + requestSchemaRef: + type: string + example: schema://proof-vault/read-request + responseSchemaRef: + type: string + example: schema://proof-vault/read-response + subsetMapping: + $ref: '#/components/schemas/ConnectorSubsetMapping' + cursorStrategy: + type: string + example: opaque-page-token + idempotencyKeyStrategy: + type: string + example: header:X-Idempotency-Key + payloadLimitBytes: + type: integer + format: int64 + minimum: 0 + example: 1048576 + rateLimitKey: + type: string + example: tenant:caller + auditCategory: + $ref: '#/components/schemas/ConnectorAuditCategory' + example: + exposureDescriptorId: proof-vault-read-exposure + exposedCapabilityId: proof-vault-read + owningTenantId: acme + organizationUnitId: nl-ops + brandId: brand-a + logicalConnectionBindingId: brand-a-proof-vault + exchangeMode: EXTERNALLY_INITIATED_READ_FROM_VDX + allowedOperation: READ + acceptedAuthMethods: [bearer, mtls] + payloadLimitBytes: 1048576 + auditCategory: EXTERNAL_EXCHANGE + + RouteExposureExternalReadRequest: + type: object + description: Governed request envelope for an externally initiated read through a route exposure descriptor. + required: + - authMethod + - callerParty + - canonicalFields + - policyDecision + properties: + authMethod: + type: string + description: Auth or trust method accepted by the exposure descriptor. + example: bearer + callerParty: + $ref: '#/components/schemas/PartyRef' + canonicalFields: + type: object + description: Canonical field values eligible for projection through the governed exposure. + additionalProperties: true + example: + proof.status: valid + governance: + $ref: '#/components/schemas/ConnectorGovernanceEnvelope' + policyDecision: + $ref: '#/components/schemas/ConnectorPolicyDecision' + cursor: + $ref: '#/components/schemas/ConnectorCursor' + example: + authMethod: bearer + callerParty: + partyId: party-consumer + canonicalFields: + proof.status: valid + governance: + classification: confidential + legalBasis: dpv:Contract + purpose: dpv:Audit + auditCategory: EXTERNAL_EXCHANGE + policyDecision: + decisionId: policy-external-read + outcome: PERMIT + cursor: + value: page-1 + + RouteExposureExternalWriteRequest: + type: object + description: Governed request envelope for an externally initiated write through a route exposure descriptor. + required: + - authMethod + - callerParty + - payload + - fieldMappings + - policyDecision + properties: + authMethod: + type: string + description: Auth or trust method accepted by the exposure descriptor. + example: bearer + callerParty: + $ref: '#/components/schemas/PartyRef' + payload: + type: object + description: External payload values supplied by the caller. + additionalProperties: true + example: + supplierStatus: valid + fieldMappings: + type: array + items: + $ref: '#/components/schemas/ConnectorFieldMapping' + governance: + $ref: '#/components/schemas/ConnectorGovernanceEnvelope' + policyDecision: + $ref: '#/components/schemas/ConnectorPolicyDecision' + idempotencyKey: + type: string + example: supplier-status-1 + partyProjectionCandidates: + type: array + items: + $ref: '#/components/schemas/PartyProjectionCandidate' + example: + authMethod: bearer + callerParty: + partyId: party-supplier + payload: + supplierStatus: valid + fieldMappings: + - source: + sourceFieldPath: supplierStatus + target: + canonicalFieldPath: evidence.status + governance: + classification: confidential + legalBasis: dpv:Contract + purpose: dpv:Audit + auditCategory: EXTERNAL_EXCHANGE + policyDecision: + decisionId: policy-external-write + outcome: PERMIT + idempotencyKey: supplier-status-1 + + ConnectorExternalReadResponse: + type: object + description: Approved governed view returned by an externally initiated read exposure. + required: + - state + - exposureDescriptorId + - logicalConnectionBindingId + - policyDecisionId + - selectedFieldPaths + - manifest + properties: + state: + type: string + example: APPROVED_VIEW + runId: + $ref: '#/components/schemas/ConnectorRunId' + exposureDescriptorId: + $ref: '#/components/schemas/RouteExposureDescriptorId' + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + policyDecisionId: + type: string + example: policy-external-read + selectedFieldPaths: + type: array + items: + type: string + example: [proof.status] + manifest: + $ref: '#/components/schemas/ConnectorExportManifest' + cursor: + $ref: '#/components/schemas/ConnectorCursor' + sourceSurface: + type: string + example: route-exposure + + ConnectorExternalWriteReceipt: + type: object + description: Governed-ingress receipt returned by an externally initiated write exposure. + required: + - state + - exposureDescriptorId + - logicalConnectionBindingId + - canonicalFields + - projectionCandidateIds + - policyDecisionId + - idempotencyResult + - payloadHash + - laterUseAvailabilityScope + properties: + state: + $ref: '#/components/schemas/ConnectorGovernedIngressStatus' + runId: + $ref: '#/components/schemas/ConnectorRunId' + exposureDescriptorId: + $ref: '#/components/schemas/RouteExposureDescriptorId' + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + canonicalFields: + type: object + description: Canonical fields produced after mapping the external payload. + additionalProperties: true + example: + evidence.status: valid + projectionCandidateIds: + type: array + items: + type: string + example: [supplier-party-1] + policyDecisionId: + type: string + example: policy-external-write + idempotencyResult: + type: string + example: accepted:supplier-status-1 + payloadHash: + type: string + example: stable64:external-write + laterUseAvailabilityScope: + type: array + items: + $ref: '#/components/schemas/ConnectorOwnerSurface' + example: [FORM, OID4VCI, OID4VP, WORKFLOW] + + ConnectorPolicyDecision: + type: object + description: Policy decision supplied to governed connector ingress, egress, and external exposure execution. + required: + - decisionId + - outcome + properties: + decisionId: + type: string + example: policy-external-read + outcome: + $ref: '#/components/schemas/ConnectorPolicyOutcome' + reason: + type: string + example: Purpose, agreement, and caller constraints permit the external exchange. + metadata: + $ref: '#/components/schemas/StringMap' + + ConnectorPolicyOutcome: + type: string + description: Outcome returned by the governing policy layer for a connector exchange. + enum: + - PERMIT + - DENY + - MINIMIZE + - REDACT + - QUARANTINE + - REQUIRE_SECOND_SOURCE + - REQUIRE_HUMAN_REVIEW + - REQUIRE_WALLET_PROOF + - REQUIRE_STEP_UP + example: PERMIT + + ConnectorGovernedIngressStatus: + type: string + description: Result state for governed external write ingress. + enum: + - ACCEPTED + - MINIMIZED + - REDACTED + - QUARANTINED + - REJECTED + example: ACCEPTED + + ConnectorCursor: + type: object + description: Opaque cursor or watermark returned by connector runtimes and external exposure reads. + required: + - value + properties: + value: + type: string + example: page-1 + metadata: + $ref: '#/components/schemas/StringMap' + + ConnectorExportedField: + type: object + description: A field included in an external-read manifest, with minimization and integrity metadata. + required: + - fieldPath + - integrityHash + properties: + fieldPath: + type: string + example: proof.status + value: + type: object + additionalProperties: true + nullable: true + redacted: + type: boolean + default: false + example: false + minimized: + type: boolean + default: false + example: false + integrityHash: + type: string + example: stable64:proof-status + + ConnectorExportManifest: + type: object + description: Governed egress manifest for an external-read response. + required: + - manifestId + - destinationIdentity + - selectedFields + - mappingVersion + - policyDecisionId + - retentionProfileId + - manifestHash + properties: + manifestId: + type: string + example: manifest-external-read + destinationIdentity: + type: string + example: party-consumer + selectedFields: + type: array + items: + $ref: '#/components/schemas/ConnectorExportedField' + mappingVersion: + type: string + example: external-read:proof-vault-read + mappingProvenance: + type: string + example: route-exposure-subset + policyDecisionId: + type: string + example: policy-external-read + retentionProfileId: + type: string + example: retention-proof + agreementRef: + type: object + additionalProperties: true + participantIdentity: + type: object + additionalProperties: true + transferProcess: + type: object + additionalProperties: true + obligations: + type: array + items: + type: object + additionalProperties: true + manifestHash: + type: string + example: stable64:manifest-external-read + + PartyProjectionCandidate: + type: object + description: Candidate Party or relationship projection emitted by governed external write ingress. + required: + - candidateId + - entityKind + properties: + candidateId: + type: string + example: supplier-party-1 + entityKind: + type: string + example: supplier + party: + $ref: '#/components/schemas/PartyRef' + relationships: + type: array + items: + type: object + additionalProperties: true + materializationIntent: + $ref: '#/components/schemas/ConnectorEntityMaterializationIntent' + semanticClassifications: + type: array + items: + type: object + additionalProperties: true + canonicalFields: + type: object + additionalProperties: true + + ConnectorEntityMaterializationIntent: + type: string + description: How a governed external write or discovery record may materialize into durable Party, relationship, semantic, event, or DPP records. + enum: + - REFERENCE_ONLY + - EXISTING_PARTY + - NEW_PARTY_CANDIDATE + - RELATIONSHIP_CANDIDATE + - SEMANTIC_VALUE + - EVENT + - DPP_RECORD + example: NEW_PARTY_CANDIDATE + + ConnectorDataProductDescriptorCreateRequest: + type: object + description: Request to persist a connector data product descriptor. + required: + - descriptor + properties: + descriptor: + $ref: '#/components/schemas/ConnectorDataProductDescriptor' + example: + descriptor: + dataProductId: dp-proof-status + providerParty: + partyId: party-provider + displayName: Proof provider + physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + logicalConnectionBindingId: brand-a-proof-vault + datasetResourceIds: [41436f49-040c-4f5f-9c7f-657f43762e2b] + title: Proof status product + canonicalFieldScopes: [proof.status] + distributionTransferTypes: [HTTPS_PULL] + catalogOfferRefs: + - offerId: offer-proof-status + policy: + profileId: dpv-odrl + policyType: OFFER + policyUid: policy-proof-status + + ConnectorDataProductDescriptor: + type: object + description: Dataspace/data-use-contract-ready descriptor for a product exposed from a connector route or logical binding. It carries provider/consumer Party refs, dataset resource refs, field scopes, governance scope, transfer type, and catalog offer/policy refs without implementing DSP/DCAT wire behavior. + required: + - dataProductId + - providerParty + - physicalConnectorInstanceId + - logicalConnectionBindingId + - datasetResourceIds + - title + - distributionTransferTypes + - catalogOfferRefs + properties: + dataProductId: + $ref: '#/components/schemas/ConnectorDataProductId' + providerParty: + $ref: '#/components/schemas/PartyRef' + consumerParty: + $ref: '#/components/schemas/PartyRef' + physicalConnectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + datasetResourceIds: + type: array + minItems: 1 + items: + $ref: '#/components/schemas/ResourceDescriptorId' + title: + type: string + minLength: 1 + example: Proof status product + description: + type: string + example: Governed proof status view exposed from the proof-vault route. + version: + type: string + example: '1.0' + canonicalFieldScopes: + type: array + items: + type: string + example: [proof.status] + schemaRefs: + type: array + items: + type: string + example: [schema://proof-status] + freshness: + type: string + example: PT5M + quality: + type: string + example: verified + distributionTransferTypes: + type: array + minItems: 1 + items: + type: string + example: [HTTPS_PULL] + residency: + type: string + example: EU + classification: + type: string + example: confidential + governanceScope: + type: string + example: proof-status + catalogOfferRefs: + type: array + minItems: 1 + items: + $ref: '#/components/schemas/ConnectorCatalogOfferRef' + partyAnchors: + $ref: '#/components/schemas/ConnectorPartyAnchorSet' + example: + dataProductId: dp-proof-status + providerParty: + partyId: party-provider + displayName: Proof provider + physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + logicalConnectionBindingId: brand-a-proof-vault + datasetResourceIds: [41436f49-040c-4f5f-9c7f-657f43762e2b] + title: Proof status product + canonicalFieldScopes: [proof.status] + distributionTransferTypes: [HTTPS_PULL] + governanceScope: proof-status + catalogOfferRefs: + - offerId: offer-proof-status + policy: + profileId: dpv-odrl + policyType: OFFER + policyUid: policy-proof-status + + ConnectorCatalogOfferRef: + type: object + description: Reference to a catalog offer and the ODRL policy attached to it. + required: + - offerId + - policy + properties: + offerId: + $ref: '#/components/schemas/ConnectorCatalogOfferId' + policy: + $ref: '#/components/schemas/ConnectorOdrlPolicyRef' + projectionHint: + type: string + example: public-catalog + + ConnectorCatalogOfferId: + type: string + description: Stable catalog offer identifier associated with a connector data product. + example: offer-proof-status + + ConnectorOdrlPolicyType: + type: string + description: ODRL policy reference type. + enum: + - SET + - OFFER + - AGREEMENT + example: OFFER + + ConnectorOdrlPolicyRef: + type: object + description: ODRL policy reference associated with a data product catalog offer. + required: + - profileId + - policyType + - policyUid + properties: + profileId: + type: string + example: dpv-odrl + policyType: + $ref: '#/components/schemas/ConnectorOdrlPolicyType' + policyUid: + type: string + example: policy-proof-status + targetRefs: + type: array + items: + type: string + example: [proof.status] + assigner: + $ref: '#/components/schemas/PartyRef' + assignee: + $ref: '#/components/schemas/PartyRef' + permissionRefs: + type: array + items: + type: string + prohibitionRefs: + type: array + items: + type: string + dutyRefs: + type: array + items: + type: string + + TransformationCreateRequest: + type: object + description: Request to define a reusable transformation from one resource descriptor to another. Attribute mapper steps can coexist with expression-based transformations. + required: + - displayName + - language + properties: + displayName: + type: string + description: Human-readable transformation name. + example: Employee profile to license invitation + description: + type: string + description: Transformation purpose and scope. + example: Maps HR employee attributes into the invitation payload used by the license issuance flow. + language: + $ref: '#/components/schemas/TransformationLanguage' + sourceDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + targetDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + steps: + type: array + description: Ordered transformation steps for step-based languages. + items: + $ref: '#/components/schemas/TransformationStep' + expression: + type: string + description: Transformation expression for expression-based languages. + example: 'employee.{ "email": email, "subject": givenName & " " & familyName }' + metadata: + $ref: '#/components/schemas/StringMap' + example: + displayName: Employee profile to license invitation + description: Maps HR employee attributes into the invitation payload used by the license issuance flow. + language: ATTRIBUTE_MAPPER + sourceDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b + targetDescriptorId: 7a44f0de-e4d9-44ef-9211-372433933a88 + steps: + - stepType: MAP + sourcePath: email + targetPath: recipient.email + - stepType: MAP + sourcePath: license_type + targetPath: credential.licenseType + - stepType: CONSTANT + targetPath: invitation.channel + value: email + metadata: + mapper_version: '1' + + TransformationUpdateRequest: + type: object + description: Partial update for a transformation definition. + properties: + displayName: + type: string + description: Updated transformation name. + example: Employee profile to license invitation + description: + type: string + description: Updated transformation description. + example: Maps employee profile rows into the current license invitation payload. + language: + $ref: '#/components/schemas/TransformationLanguage' + sourceDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + targetDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + steps: + type: array + items: + $ref: '#/components/schemas/TransformationStep' + expression: + type: string + description: Updated expression for expression-based transformations. + example: $.employee + metadata: + $ref: '#/components/schemas/StringMap' + example: + description: Maps employee profile rows into the current license invitation payload. + steps: + - stepType: MAP + sourcePath: email + targetPath: recipient.email + - stepType: DEFAULT + targetPath: invitation.locale + value: en-US + + TransformationDefinition: + description: Stored transformation definition. + allOf: + - $ref: '#/components/schemas/TransformationCreateRequest' + - type: object + required: + - transformationId + - createdAt + - updatedAt + properties: + transformationId: + $ref: '#/components/schemas/TransformationId' + createdAt: + type: string + format: date-time + description: Creation timestamp. + example: '2026-06-18T09:35:00Z' + updatedAt: + type: string + format: date-time + description: Last update timestamp. + example: '2026-06-18T09:40:00Z' + example: + transformationId: 0e60abcc-41b5-4cc5-bec2-f0047f129341 + displayName: Employee profile to license invitation + description: Maps HR employee attributes into the invitation payload used by the license issuance flow. + language: ATTRIBUTE_MAPPER + sourceDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b + targetDescriptorId: 7a44f0de-e4d9-44ef-9211-372433933a88 + steps: + - stepType: MAP + sourcePath: email + targetPath: recipient.email + - stepType: MAP + sourcePath: license_type + targetPath: credential.licenseType + createdAt: '2026-06-18T09:35:00Z' + updatedAt: '2026-06-18T09:40:00Z' + + TransformationStep: + type: object + description: One step in a transformation pipeline. Step semantics are intentionally generic so existing attribute mappers and future expression engines can share the route model. + required: + - stepType + properties: + stepType: + type: string + description: Transformation step operation. + enum: + - MAP + - CONSTANT + - DEFAULT + - REQUIRE + - REDACT + - HASH + - LOOKUP + - CUSTOM + example: MAP + sourcePath: + type: string + description: Source path or field used by this step. + example: email + targetPath: + type: string + description: Target path or field written by this step. + example: recipient.email + value: + description: Literal value used by CONSTANT or DEFAULT steps. + nullable: true + example: email + expression: + type: string + description: Optional expression used by LOOKUP, CUSTOM, or expression-based steps. + example: lower($.email) + metadata: $ref: '#/components/schemas/StringMap' example: stepType: MAP @@ -1750,15 +3106,12 @@ components: - type: object required: - routeId - - tenantId - materializationPolicy - createdAt - updatedAt properties: routeId: $ref: '#/components/schemas/ConnectorRouteId' - tenantId: - $ref: '#/components/schemas/TenantId' createdAt: type: string format: date-time @@ -1784,7 +3137,6 @@ components: example: '2026-06-19T10:05:00Z' example: routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f - tenantId: acme displayName: Employee CSV to license invitations description: Imports employee rows, maps them to invitation payloads, and writes them to the invitation service. sourceBindingIds: @@ -2276,6 +3628,20 @@ components: description: Whether the run should validate and transform without committing destination writes. default: false example: false + invocationBindingId: + $ref: '#/components/schemas/ConnectorInvocationBindingId' + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + physicalConnectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + exchangeMode: + $ref: '#/components/schemas/ConnectorExchangeMode' + governance: + $ref: '#/components/schemas/ConnectorGovernanceEnvelope' + partyAnchors: + $ref: '#/components/schemas/ConnectorPartyAnchorSet' + protocolContext: + $ref: '#/components/schemas/ConnectorProtocolEventContext' correlationId: type: string description: Caller-provided correlation id for logs, run events, and downstream traceability. @@ -2295,20 +3661,35 @@ components: description: Execution record for a connector route or operation. Counts are item-level where the connector runtime can report item-level progress. required: - runId - - tenantId - status - startedAt properties: runId: $ref: '#/components/schemas/ConnectorRunId' - tenantId: - $ref: '#/components/schemas/TenantId' routeId: $ref: '#/components/schemas/ConnectorRouteId' bindingId: $ref: '#/components/schemas/OperationBindingId' connectorInstanceId: $ref: '#/components/schemas/ConnectorInstanceId' + invocationBindingId: + $ref: '#/components/schemas/ConnectorInvocationBindingId' + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + physicalConnectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + exchangeMode: + $ref: '#/components/schemas/ConnectorExchangeMode' + dataDirection: + $ref: '#/components/schemas/ConnectorDataDirection' + initiationSide: + $ref: '#/components/schemas/ConnectorInitiationSide' + governance: + $ref: '#/components/schemas/ConnectorGovernanceEnvelope' + partyAnchors: + $ref: '#/components/schemas/ConnectorPartyAnchorSet' + protocolContext: + $ref: '#/components/schemas/ConnectorProtocolEventContext' connectorResourceId: $ref: '#/components/schemas/ConnectorResourceId' operationKind: @@ -2382,7 +3763,6 @@ components: example: '2026-07-18T10:21:12Z' example: runId: 9a785884-63ea-4b07-9976-264a1fc595f1 - tenantId: acme routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 connectorResourceId: 8d228f50-a86c-4d5f-9eb4-83fdad7d75fa @@ -2403,7 +3783,6 @@ components: description: Timestamped event emitted during route or operation execution. required: - eventId - - tenantId - runId - level - message @@ -2414,8 +3793,6 @@ components: format: uuid description: Stable run event identifier. example: 524d8a98-c4a4-4982-b414-e29679b41eaf - tenantId: - $ref: '#/components/schemas/TenantId' runId: $ref: '#/components/schemas/ConnectorRunId' routeId: @@ -2450,7 +3827,6 @@ components: $ref: '#/components/schemas/StringMap' example: eventId: 524d8a98-c4a4-4982-b414-e29679b41eaf - tenantId: acme runId: 9a785884-63ea-4b07-9976-264a1fc595f1 routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 @@ -2468,7 +3844,6 @@ components: description: Failed item captured after validation, transformation, or destination delivery failure. Payloads are referenced, not necessarily embedded, so retention policy can control storage. required: - deadLetterId - - tenantId - runId - reason - createdAt @@ -2478,8 +3853,6 @@ components: format: uuid description: Stable dead-letter identifier. example: a7d38149-19d4-4d0e-8af7-f7f8891f73bb - tenantId: - $ref: '#/components/schemas/TenantId' runId: $ref: '#/components/schemas/ConnectorRunId' routeId: @@ -2518,7 +3891,6 @@ components: example: '2026-07-18T10:21:11Z' example: deadLetterId: a7d38149-19d4-4d0e-8af7-f7f8891f73bb - tenantId: acme runId: 9a785884-63ea-4b07-9976-264a1fc595f1 routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 @@ -2532,19 +3904,18 @@ components: row_number: '42' ConnectorInstancePage: + type: object description: Page of connector instances. - allOf: - - $ref: '#/components/schemas/Page' - - type: object - required: - - items - properties: - items: - type: array - items: - $ref: '#/components/schemas/ConnectorInstance' + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorInstance' + pagination: + $ref: '#/components/schemas/Page' example: - items: + data: - connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 partyId: f9c97b4e-e756-4b70-b230-6f1d9f81b426 displayName: Workday employee profile API @@ -2553,118 +3924,133 @@ components: supportedRoles: [SOURCE] createdAt: '2026-06-18T08:30:00Z' updatedAt: '2026-06-18T08:45:00Z' - total_count: 1 - limit: 20 - offset: 0 - has_more: false + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false ConnectorIdentityPage: + type: object description: Page of connector identities. - allOf: - - $ref: '#/components/schemas/Page' - - type: object - required: - - items - properties: - items: - type: array - items: - $ref: '#/components/schemas/ConnectorIdentity' + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorIdentity' + pagination: + $ref: '#/components/schemas/Page' example: - items: + data: - identityId: 3a5cf979-2d89-4057-a721-c7ab884f0c68 identityRole: external-system displayName: Workday tenant acme-prod isDefault: true identifiers: [] - total_count: 1 - limit: 20 - offset: 0 - has_more: false + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false ConnectorResourcePage: + type: object description: Page of resources attached to connectors. - allOf: - - $ref: '#/components/schemas/Page' - - type: object - required: - - items - properties: - items: - type: array - items: - $ref: '#/components/schemas/ConnectorResource' + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorResource' + pagination: + $ref: '#/components/schemas/Page' example: - items: + data: - connectorResourceId: b4cf21b1-0292-4803-8d32-9ebf9f5359a2 connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 resourceDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b role: SOURCE externalResourceName: /employees/{employee_id} accessProtocol: HTTPS - total_count: 1 - limit: 20 - offset: 0 - has_more: false + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false ResourceDescriptorPage: + type: object description: Page of resource descriptors. - allOf: - - $ref: '#/components/schemas/Page' - - type: object - required: - - items - properties: - items: - type: array - items: - $ref: '#/components/schemas/ResourceDescriptor' + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ResourceDescriptor' + pagination: + $ref: '#/components/schemas/Page' example: - items: + data: - resourceDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b displayName: Employee profile CSV row resourceKind: TABULAR representationKind: CSV createdAt: '2026-06-18T09:00:00Z' updatedAt: '2026-06-18T09:10:00Z' - total_count: 1 - limit: 20 - offset: 0 - has_more: false + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false FieldDescriptorPage: + type: object description: Page of field descriptors. - allOf: - - $ref: '#/components/schemas/Page' - - type: object - required: - - items - properties: - items: - type: array - items: - $ref: '#/components/schemas/FieldDescriptor' + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/FieldDescriptor' + pagination: + $ref: '#/components/schemas/Page' example: - items: + data: - fieldDescriptorId: f00b9edc-5498-483f-9b91-a42ef080b909 fieldPath: email displayName: Work email valueType: string required: true - total_count: 1 - limit: 20 - offset: 0 - has_more: false + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false OperationBindingPage: + type: object description: Page of operation bindings. - allOf: - - $ref: '#/components/schemas/Page' - - type: object - required: - - items - properties: - items: - type: array - items: - $ref: '#/components/schemas/OperationBinding' + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/OperationBinding' + pagination: + $ref: '#/components/schemas/Page' example: - items: + data: - bindingId: 2777417e-82ce-4d3e-b96c-94e00a4d9a93 connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 connectorResourceId: b4cf21b1-0292-4803-8d32-9ebf9f5359a2 @@ -2673,25 +4059,28 @@ components: accessProtocol: HTTPS operationName: getEmployeeProfile createdAt: '2026-06-18T09:20:00Z' - updatedAt: '2026-06-18T09:25:00Z' - total_count: 1 - limit: 20 - offset: 0 - has_more: false + updatedAt: '2026-06-18T09:25:00Z' + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false SemanticConnectorBindingPage: + type: object description: Page of semantic connector bindings. - allOf: - - $ref: '#/components/schemas/Page' - - type: object - required: - - items - properties: - items: - type: array - items: - $ref: '#/components/schemas/SemanticConnectorBinding' + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/SemanticConnectorBinding' + pagination: + $ref: '#/components/schemas/Page' example: - items: + data: - semanticBindingId: 20392e94-3b35-4a77-afc2-5e552a0a4023 resourceDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b fieldDescriptorId: f00b9edc-5498-483f-9b91-a42ef080b909 @@ -2699,47 +4088,174 @@ components: validationMode: ENFORCE createdAt: '2026-06-18T09:30:00Z' updatedAt: '2026-06-18T09:30:00Z' - total_count: 1 - limit: 20 - offset: 0 - has_more: false + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + ConnectorInvocationBindingPage: + type: object + description: Page of connector invocation bindings. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorInvocationBinding' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - invocationBindingId: issuer-config-1:post-issuance:proof-vault + ownerSurface: OID4VCI + ownerReference: issuer-config-1 + stage: OID4VCI_POST_ISSUANCE + role: VAULT_RETENTION + target: + routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + exchangeMode: PLATFORM_INITIATED_PUSH + logicalContext: + tenantId: acme + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + LogicalConnectionBindingPage: + type: object + description: Page of logical connection bindings. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/LogicalConnectionBinding' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - logicalConnectionBindingId: brand-a-proof-vault + physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + logicalContext: + tenantId: acme + organizationUnitId: nl-ops + brandId: brand-a + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + RouteExposureDescriptorPage: + type: object + description: Page of route exposure descriptors. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/RouteExposureDescriptor' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - exposureDescriptorId: proof-vault-read-exposure + exposedCapabilityId: proof-vault-read + owningTenantId: acme + logicalConnectionBindingId: brand-a-proof-vault + exchangeMode: EXTERNALLY_INITIATED_READ_FROM_VDX + allowedOperation: READ + acceptedAuthMethods: [bearer, mtls] + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + ConnectorDataProductDescriptorPage: + type: object + description: Page of connector data product descriptors. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorDataProductDescriptor' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - dataProductId: dp-proof-status + providerParty: + partyId: party-provider + physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + logicalConnectionBindingId: brand-a-proof-vault + datasetResourceIds: [41436f49-040c-4f5f-9c7f-657f43762e2b] + title: Proof status product + distributionTransferTypes: [HTTPS_PULL] + catalogOfferRefs: + - offerId: offer-proof-status + policy: + profileId: dpv-odrl + policyType: OFFER + policyUid: policy-proof-status + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false TransformationPage: + type: object description: Page of transformation definitions. - allOf: - - $ref: '#/components/schemas/Page' - - type: object - required: - - items - properties: - items: - type: array - items: - $ref: '#/components/schemas/TransformationDefinition' + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/TransformationDefinition' + pagination: + $ref: '#/components/schemas/Page' example: - items: + data: - transformationId: 0e60abcc-41b5-4cc5-bec2-f0047f129341 displayName: Employee profile to license invitation language: ATTRIBUTE_MAPPER createdAt: '2026-06-18T09:35:00Z' updatedAt: '2026-06-18T09:40:00Z' - total_count: 1 - limit: 20 - offset: 0 - has_more: false + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false ConnectorRoutePage: + type: object description: Page of connector routes. - allOf: - - $ref: '#/components/schemas/Page' - - type: object - required: - - items - properties: - items: - type: array - items: - $ref: '#/components/schemas/ConnectorRoute' + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorRoute' + pagination: + $ref: '#/components/schemas/Page' example: - items: + data: - routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f displayName: Employee CSV to license invitations sourceBindingIds: @@ -2749,24 +4265,27 @@ components: atomicity: PER_RECORD createdAt: '2026-06-18T10:00:00Z' updatedAt: '2026-06-18T10:05:00Z' - total_count: 1 - limit: 20 - offset: 0 - has_more: false + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false ConnectorRunPage: + type: object description: Page of connector runs. - allOf: - - $ref: '#/components/schemas/Page' - - type: object - required: - - items - properties: - items: - type: array - items: - $ref: '#/components/schemas/ConnectorRun' + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorRun' + pagination: + $ref: '#/components/schemas/Page' example: - items: + data: - runId: 9a785884-63ea-4b07-9976-264a1fc595f1 routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f status: PARTIALLY_FAILED @@ -2775,72 +4294,79 @@ components: itemCount: 250 successCount: 247 failureCount: 3 - total_count: 1 - limit: 20 - offset: 0 - has_more: false + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false ConnectorRunEventPage: + type: object description: Page of connector run events. - allOf: - - $ref: '#/components/schemas/Page' - - type: object - required: - - items - properties: - items: - type: array - items: - $ref: '#/components/schemas/ConnectorRunEvent' + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorRunEvent' + pagination: + $ref: '#/components/schemas/Page' example: - items: + data: - eventId: 524d8a98-c4a4-4982-b414-e29679b41eaf runId: 9a785884-63ea-4b07-9976-264a1fc595f1 level: WARN message: Three rows failed validation and were written to dead letters. occurredAt: '2026-06-18T10:21:10Z' - total_count: 1 - limit: 20 - offset: 0 - has_more: false + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false ConnectorDeadLetterPage: + type: object description: Page of connector dead letters. - allOf: - - $ref: '#/components/schemas/Page' - - type: object - required: - - items - properties: - items: - type: array - items: - $ref: '#/components/schemas/ConnectorDeadLetter' + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorDeadLetter' + pagination: + $ref: '#/components/schemas/Page' example: - items: + data: - deadLetterId: a7d38149-19d4-4d0e-8af7-f7f8891f73bb runId: 9a785884-63ea-4b07-9976-264a1fc595f1 routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f reason: Missing required field recipient.email. createdAt: '2026-06-18T10:21:11Z' - total_count: 1 - limit: 20 - offset: 0 - has_more: false + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false Page: type: object - description: Standard page metadata shape used by this API. The page is not wrapped in an additional data envelope. + description: Pagination metadata emitted with each paged response under the `pagination` property. required: - - total_count - limit - offset - - has_more + - page + - size + - total + - totalPages + - hasMore properties: - total_count: - type: integer - format: int64 - description: Total number of matching records. - minimum: 0 - example: 1 limit: type: integer description: Maximum number of records requested for this page. @@ -2851,15 +4377,416 @@ components: description: Zero-based offset of the first record in this page. minimum: 0 example: 0 - has_more: + page: + type: integer + description: Zero-based page index derived from offset and limit. + minimum: 0 + example: 0 + size: + type: integer + description: Effective page size. + minimum: 0 + example: 20 + total: + type: integer + format: int64 + description: Total number of matching records. + minimum: 0 + example: 1 + totalPages: + type: integer + description: Total number of available pages. + minimum: 0 + example: 1 + hasMore: type: boolean description: Whether another page is available after this page. example: false example: - total_count: 1 limit: 20 offset: 0 - has_more: false + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + + ConnectorIntegrityReference: + type: object + description: Integrity and evidence references carried with governed connector ingress, egress, and run lineage. + properties: + originalPayloadHash: + type: string + example: stable64:0000000000000001 + canonicalPayloadHash: + type: string + example: stable64:0000000000000002 + transformationHash: + type: string + example: stable64:0000000000000003 + evidenceRef: + type: string + example: vault://evidence/connector-run-1 + vaultRef: + type: string + example: vault://proofs/proof-1 + signatureRef: + type: string + example: jades://signature-1 + sealRef: + type: string + example: seal://qualified-seal-1 + timestampRef: + type: string + example: timestamp://tsa-1 + sourceAuthenticityVerdict: + type: string + example: VERIFIED + outputManifestHash: + type: string + example: stable64:0000000000000004 + + ConnectorGovernanceEnvelope: + type: object + description: Governance metadata attached to connector records, invocations, and runs before data crosses a protocol, form, vault, dataspace, or external-exchange boundary. + properties: + classification: + type: string + example: confidential + sensitivity: + type: string + example: high + specialCategory: + type: boolean + default: false + legalBasis: + type: string + example: dpv:Contract + purpose: + type: string + example: dpv:Audit + b2bUsagePurpose: + type: string + description: B2B or dataspace usage purpose, separate from privacy legal basis and processing purpose. + example: predictive-maintenance + frameworkAgreementRef: + type: string + example: catena-x:framework:1 + contractReference: + type: string + example: agreement-2026-001 + minimizationStatus: + type: string + enum: + - NOT_EVALUATED + - MINIMIZED + - REDACTED + - FULL_DATASET + - EXCESSIVE + example: MINIMIZED + retentionProfileId: + type: string + example: retention-proof + retention: + $ref: '#/components/schemas/RetentionSpec' + crossBorderRestriction: + type: string + enum: + - NONE + - SAME_COUNTRY + - EEA_ONLY + - APPROVED_COUNTRIES + - CONTRACT_REQUIRED + - BLOCKED + example: EEA_ONLY + encryptionRequirement: + type: string + enum: + - NONE + - IN_TRANSIT + - AT_REST + - AT_REST_AND_IN_TRANSIT + - CUSTOMER_MANAGED_KEY + example: AT_REST_AND_IN_TRANSIT + dpiaRequired: + type: boolean + default: false + integrity: + $ref: '#/components/schemas/ConnectorIntegrityReference' + policyDecisionId: + type: string + example: policy-connector-run + relianceVerdict: + type: string + enum: + - NOT_EVALUATED + - RELIABLE + - CONDITIONAL + - NOT_RELIABLE + example: RELIABLE + auditCategory: + type: string + enum: + - PROTOCOL_ISSUANCE + - PROTOCOL_VERIFICATION + - FORM + - PORTAL + - WORKFLOW + - DATASPACE + - INDUSTRIAL + - EXTERNAL_EXCHANGE + - VAULT + - SYSTEM_CATALOG + example: PROTOCOL_ISSUANCE + + PartyRef: + type: object + description: Neutral Party reference carried by EDK connector envelopes without importing the VDX Party repository. + properties: + partyId: + type: string + example: party-subject + externalId: + type: string + example: urn:external:asset:press-1 + partyType: + type: string + example: organization + displayName: + type: string + example: Example BV + metadata: + $ref: '#/components/schemas/StringMap' + + RelationshipRef: + type: object + description: Neutral Party relationship reference used by connector exposure caller constraints without importing the VDX Party repository. + required: + - relationshipType + - fromParty + - toParty + properties: + relationshipId: + type: string + example: rel-supplier-acme + relationshipType: + type: string + example: supplierOf + fromParty: + $ref: '#/components/schemas/PartyRef' + toParty: + $ref: '#/components/schemas/PartyRef' + + ConnectorPartyAnchor: + type: object + description: Role-specific Party anchor used for governed durable connector entities. + properties: + role: + type: string + example: SUBJECT + party: + $ref: '#/components/schemas/PartyRef' + relationships: + type: array + items: + type: object + additionalProperties: true + + ConnectorPartyAnchorSet: + type: object + description: Party, relationship, and projection candidates attached to connector invocation/run lineage. + properties: + anchors: + type: array + items: + $ref: '#/components/schemas/ConnectorPartyAnchor' + relationshipCandidates: + type: array + items: + type: object + additionalProperties: true + projectionCandidates: + type: array + items: + type: object + additionalProperties: true + + ConnectorProtocolEventContext: + type: object + description: Canonical protocol, form, portal, or workflow event context mapped into connector run lineage. + properties: + tenantId: + type: string + example: acme + organizationUnitId: + type: string + example: nl-ops + brandId: + type: string + example: brand-a + legalEntityId: + type: string + example: legal-entity-a + actor: + $ref: '#/components/schemas/PartyRef' + protocolSurface: + type: string + enum: + - OID4VCI + - OID4VP + - FORM + - PORTAL + - WORKFLOW + - APPLICATION + example: OID4VCI + ownerReference: + type: string + example: issuer-config-1 + stage: + type: string + example: OID4VCI_POST_ISSUANCE + sessionId: + type: string + example: protocol-session-1 + transactionId: + type: string + example: protocol-transaction-1 + correlationId: + type: string + example: protocol-correlation-1 + + ConnectorInvocationRequest: + type: object + description: Runtime request passed from a protocol, form, portal, or workflow stage into a connector invocation binding. + required: + - binding + properties: + binding: + $ref: '#/components/schemas/ConnectorInvocationBinding' + fields: + type: object + description: Canonical and protocol field values available to the connector invocation. + additionalProperties: true + protocolContext: + $ref: '#/components/schemas/ConnectorProtocolEventContext' + record: + $ref: '#/components/schemas/ConnectorRecord' + + ConnectorRunCorrelation: + type: object + description: Route-run lineage produced by connector invocation execution. + properties: + runId: + $ref: '#/components/schemas/ConnectorRunId' + externalRunRef: + type: string + example: run-issuer-config-1-proof-vault + routeId: + $ref: '#/components/schemas/ConnectorRouteId' + + ConnectorVaultRetentionProfile: + type: string + description: Vault retention profile requested by a connector invocation result. + enum: + - ISSUANCE_PROOF + - CANONICAL_SUBJECT_DATA + - RECEIVED_CUSTOMER_DATA + example: ISSUANCE_PROOF + + ConnectorVaultWrite: + type: object + description: Idempotent vault write requested by a connector invocation after protocol completion. + required: + - vaultProfile + - idempotentUpsertKey + - governance + properties: + vaultProfile: + $ref: '#/components/schemas/ConnectorVaultRetentionProfile' + idempotentUpsertKey: + type: string + example: proof:offer-123:E-100 + subjectCorrelationHandle: + type: string + example: subject:E-100 + revocationReissueLookupKey: + type: string + example: reissue:E-100 + selectedFields: + type: object + additionalProperties: true + proofRef: + type: string + example: proof-ref + statusHandle: + type: string + example: status-ref + auditLineage: + $ref: '#/components/schemas/ConnectorRunCorrelation' + governance: + $ref: '#/components/schemas/ConnectorGovernanceEnvelope' + + ConnectorInvocationResult: + type: object + description: Runtime result emitted by a connector invocation, including produced fields, written records, route lineage, and vault writes. + properties: + producedFields: + type: object + additionalProperties: true + records: + type: array + items: + $ref: '#/components/schemas/ConnectorRecord' + writeResult: + $ref: '#/components/schemas/ConnectorWriteResult' + runCorrelation: + $ref: '#/components/schemas/ConnectorRunCorrelation' + vaultWrites: + type: array + items: + $ref: '#/components/schemas/ConnectorVaultWrite' + + Oid4vciConnectorPipelineRequest: + type: object + description: EDK-neutral OID4VCI connector pipeline request used to run connector-native enrichment, export, or vault-retention bindings. + required: + - protocolContext + - initialFields + - bindings + - stages + properties: + protocolContext: + $ref: '#/components/schemas/ConnectorProtocolEventContext' + initialFields: + type: object + additionalProperties: true + bindings: + type: array + items: + $ref: '#/components/schemas/ConnectorInvocationBinding' + stages: + type: array + items: + $ref: '#/components/schemas/ConnectorInvocationStage' + + Oid4vciConnectorPipelineResult: + type: object + description: Result of an OID4VCI connector pipeline run, including accumulated fields and post-issuance vault writes. + required: + - fields + - invocationResults + properties: + fields: + type: object + additionalProperties: true + invocationResults: + type: array + items: + $ref: '#/components/schemas/ConnectorInvocationResult' + vaultWrites: + type: array + items: + $ref: '#/components/schemas/ConnectorVaultWrite' StringMap: type: object diff --git a/connector-integration-openapi.yml b/connector-integration-openapi.yml new file mode 100644 index 0000000..53b96f4 --- /dev/null +++ b/connector-integration-openapi.yml @@ -0,0 +1,6343 @@ +openapi: 3.0.4 +info: + title: Connector Integration Profile API + version: 0.1.0 + x-generated-from: connector-openapi.yml + x-profile: integration + x-audience: external-partner + x-contract-version: v1 + x-contract-stability: stable + x-products: [vdx] + description: | + Register and operate connector instances that can act as sources, destinations, or both. + The API is mounted as a singular product API at `/api/connector/v1`; resources inside the API + use plural REST paths. + + This generated external integration profile is the curated subset that third-party connector builders, SDK consumers, and low-code importers should consume. It is derived from the v1-stable connector REST contract and is not a second source of truth. Compatible additions may appear, but existing + response fields, path names, operation ids, and request shapes are governed as public + integration and SDK-facing contract surface. + + The model deliberately separates transport from data: + + - `AccessProtocol` describes how a connector reaches a system, such as HTTPS, JDBC, S3, + Kafka, OIDC, or vault access. + - `ResourceKind` describes the logical resource being accessed, such as tabular data, + documents, claim sets, event streams, files, secrets, credentials, or presentations. + - `RepresentationKind` describes the serialization or data representation, such as JSON, + JSON-LD, CSV, JWT, RDF, Parquet, text, or binary. + - `ContractKind` describes the schema or contract source, such as OpenAPI, JSON Schema, + SQL schema, RDF shape, OIDC discovery, or CSV profile. + + A connector instance is represented as a Party and can be assigned Identities. Identifiers are + always nested under Identity, matching the existing Party -> Identity -> Identifier model. This + allows external systems, technical accounts, issuers, relying parties, APIs, and LOB systems to + have durable identities without flattening identifiers directly onto connectors. + + Routes compose source and destination operation bindings with optional transformations. This + supports current issuance use cases, CSV import/export, vault/blob materialization, HTTP/OpenAPI + connector runtimes, SQL connector runtimes, OIDC claim sources, forms, workflows, and future governance + controls without coupling the API to one credential or form pipeline. + contact: + name: Product Engineering + email: support@example.com + url: https://example.com + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0 + +servers: + - url: https://api.example.com/api/connector/v1 + description: Production server. + - url: http://localhost:8080/api/connector/v1 + description: Local development server. + +security: + - bearer: [] + +tags: + - name: Connectors + description: Register connector instances as durable Party-backed integration endpoints. + - name: ConnectorResources + description: Attach described resources to connector instances. + - name: ResourceDescriptors + description: Describe data shapes, contracts, fields, and semantic meaning independent of transport. + - name: OperationBindings + description: Bind connector operations to resources, protocols, transformations, and delivery policies. + - name: SemanticBindings + description: Bind resource fields and connector resources to semantic model references. + - name: ConnectorInvocationBindings + description: Bind product and protocol invocation stages to persisted connector routes, operations, logical context, and governance defaults. + - name: LogicalConnectionBindings + description: Scope physical connector instances to tenant, organization, brand, channel, and caller-specific logical usage contexts. + - name: RouteExposures + description: Describe externally callable route capabilities and their authorization, schema, subset, rate, and audit constraints. + - name: ConnectorDataProducts + description: Describe connector-exposed data products, catalog offers, transfer types, and governance scope without implementing DSP/DCAT wire behavior. + - name: Transformations + description: Define reusable transformations between resource descriptors. + - name: Routes + description: Compose source and destination operation bindings with optional transformation and trigger policy. + - name: Runs + description: Observe connector route and operation executions. + +paths: + /connectors: + get: + operationId: listConnectorInstances + summary: List connector instances + description: | + Lists connector instances registered for the tenant. Use this endpoint to find durable + integration endpoints by connector family, data-flow role, or logical operation support. + A connector instance is not itself a resource shape; resource descriptors and operation + bindings describe what the connector can read or write. + tags: [Connectors] + parameters: + - $ref: '#/components/parameters/ConnectorType' + - $ref: '#/components/parameters/Role' + - $ref: '#/components/parameters/OperationKind' + - $ref: '#/components/parameters/Page' + - $ref: '#/components/parameters/Size' + responses: + '200': + description: Paged connector instances. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorInstancePage' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + post: + operationId: createConnectorInstance + summary: Create a connector instance + description: | + Creates the connector instance and its backing Party. The request must include the + connector identity data needed to bind or create the Party identity up front. Identifiers + must be supplied inside an identity. + tags: [Connectors] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorInstanceCreateRequest' + responses: + '201': + description: Connector instance created. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorInstance' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + + /connectors/{connectorInstanceId}: + get: + operationId: getConnectorInstance + summary: Get a connector instance + description: | + Reads one connector instance, including its backing Party id, assigned identities, + endpoint references, credential references, settings bindings, and default policies. + Secret values are never returned. + tags: [Connectors] + parameters: + - $ref: '#/components/parameters/ConnectorInstanceId' + responses: + '200': + description: Connector instance. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorInstance' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + patch: + operationId: updateConnectorInstance + summary: Update a connector instance + description: | + Updates connector instance metadata, lifecycle state, supported operations, and default + policies. Use lifecycleStatus=SUSPENDED to stop new route runs without deleting durable + configuration or Party identity information. + tags: [Connectors] + parameters: + - $ref: '#/components/parameters/ConnectorInstanceId' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorInstanceUpdateRequest' + responses: + '200': + description: Connector instance updated. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorInstance' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + delete: + operationId: deleteConnectorInstance + summary: Delete a connector instance + description: | + Deletes or tombstones the connector registration according to the runtime implementation. + This removes the connector registry entry, but implementations should treat Party, + Identity, Identifier, audit, and historical run data according to their own retention rules. + tags: [Connectors] + parameters: + - $ref: '#/components/parameters/ConnectorInstanceId' + responses: + '204': + description: Connector instance deleted. + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + + /connectors/{connectorInstanceId}/resources: + get: + operationId: listConnectorResources + summary: List resources attached to a connector + description: | + Lists resource descriptors attached to a connector instance for source and destination use. + The attached resource adds connector-local access details such as external resource name, + endpoint id, and access protocol; the descriptor remains the reusable logical data shape. + tags: [ConnectorResources] + parameters: + - $ref: '#/components/parameters/ConnectorInstanceId' + - $ref: '#/components/parameters/Role' + - $ref: '#/components/parameters/ResourceKind' + - $ref: '#/components/parameters/Page' + - $ref: '#/components/parameters/Size' + responses: + '200': + description: Paged resources attached to the connector. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorResourcePage' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + post: + operationId: attachConnectorResource + summary: Attach a resource descriptor to a connector + description: | + Attaches a reusable resource descriptor to a connector instance. For example, the same + employee profile descriptor can be attached to an HTTP/OpenAPI connector over HTTPS, a CSV + resource accessed over VAULT, and a SQL connector accessed over JDBC without changing the descriptor. + tags: [ConnectorResources] + parameters: + - $ref: '#/components/parameters/ConnectorInstanceId' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AttachConnectorResourceRequest' + responses: + '201': + description: Resource attached to the connector. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorResource' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + + /connectors/{connectorInstanceId}/discoveryruns: + post: + operationId: createConnectorDiscoveryRun + summary: Discover connector resources + description: | + Runs connector discovery and returns suggested resource descriptors and operation hints. + Discovery results are advisory; callers must create resource descriptors and operation + bindings explicitly before routes can use them. + tags: [ConnectorResources] + parameters: + - $ref: '#/components/parameters/ConnectorInstanceId' + requestBody: + required: false + content: + application/json: + schema: + $ref: '#/components/schemas/DiscoverResourcesRequest' + responses: + '200': + description: Discovery result with suggested resource descriptors. + content: + application/json: + schema: + $ref: '#/components/schemas/DiscoveryResult' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + + /connectors/{connectorInstanceId}/healthchecks: + post: + operationId: createConnectorHealthCheck + summary: Check connector health + description: | + Performs a health check for the connector instance and optionally its dependencies, such as + endpoint reachability, credentials, contract availability, or operation-specific readiness. + The health result is observational and does not change connector lifecycle status. + tags: [Connectors] + parameters: + - $ref: '#/components/parameters/ConnectorInstanceId' + requestBody: + required: false + content: + application/json: + schema: + $ref: '#/components/schemas/HealthCheckRequest' + responses: + '200': + description: Connector health result. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorHealth' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + + /resource/descriptors: + get: + operationId: listResourceDescriptors + summary: List resource descriptors + description: | + Lists reusable resource descriptors. Descriptors describe the logical resource, data + representation, structural contract, fields, semantic bindings, sensitivity, and retention + hints independently from connector transport. + tags: [ResourceDescriptors] + parameters: + - $ref: '#/components/parameters/ResourceKind' + - $ref: '#/components/parameters/Page' + - $ref: '#/components/parameters/Size' + responses: + '200': + description: Paged resource descriptors. + content: + application/json: + schema: + $ref: '#/components/schemas/ResourceDescriptorPage' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + post: + operationId: createResourceDescriptor + summary: Create a resource descriptor + description: | + Creates a reusable descriptor for data that can flow through connectors. Use this for CSV + rows, REST payloads, OIDC claim sets, SQL tables, vault objects, forms, workflow payloads, + credentials, presentations, and future resource types. + tags: [ResourceDescriptors] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ResourceDescriptorCreateRequest' + responses: + '201': + description: Resource descriptor created. + content: + application/json: + schema: + $ref: '#/components/schemas/ResourceDescriptor' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + + /resource/descriptors/{resourceDescriptorId}: + get: + operationId: getResourceDescriptor + summary: Get a resource descriptor + description: | + Reads one resource descriptor including field metadata, contract reference, representation, + and semantic/governance hints. The descriptor does not contain connector credentials or + transport endpoint details. + tags: [ResourceDescriptors] + parameters: + - $ref: '#/components/parameters/ResourceDescriptorId' + responses: + '200': + description: Resource descriptor. + content: + application/json: + schema: + $ref: '#/components/schemas/ResourceDescriptor' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + patch: + operationId: updateResourceDescriptor + summary: Update a resource descriptor + description: | + Updates descriptor metadata, resource classification, representation, contract reference, + or governance metadata. Field-level changes are managed through the fields subresource. + tags: [ResourceDescriptors] + parameters: + - $ref: '#/components/parameters/ResourceDescriptorId' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ResourceDescriptorUpdateRequest' + responses: + '200': + description: Resource descriptor updated. + content: + application/json: + schema: + $ref: '#/components/schemas/ResourceDescriptor' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + + /resource/descriptors/{resourceDescriptorId}/fields: + get: + operationId: listFieldDescriptors + summary: List resource descriptor fields + description: | + Lists fields declared for a resource descriptor. Fields carry path/column names, value + type hints, required/multi-valued semantics, semantic attribute references, sensitivity, + and optional retention metadata. + tags: [ResourceDescriptors] + parameters: + - $ref: '#/components/parameters/ResourceDescriptorId' + - $ref: '#/components/parameters/Page' + - $ref: '#/components/parameters/Size' + responses: + '200': + description: Paged field descriptors. + content: + application/json: + schema: + $ref: '#/components/schemas/FieldDescriptorPage' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + post: + operationId: createFieldDescriptor + summary: Add a field descriptor + description: | + Adds a field to a descriptor. Use this to document a CSV column, JSON path, SQL column, + OIDC claim, form field, credential claim, or presentation attribute that can be validated, + mapped, governed, or transformed. + tags: [ResourceDescriptors] + parameters: + - $ref: '#/components/parameters/ResourceDescriptorId' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/FieldDescriptorInput' + responses: + '201': + description: Field descriptor created. + content: + application/json: + schema: + $ref: '#/components/schemas/FieldDescriptor' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + + /operation/bindings: + get: + operationId: listOperationBindings + summary: List operation bindings + description: | + Lists connector operation bindings. Operation bindings connect connector instances, + attached resources, logical operation kinds, connector-local operation names, protocols, + transformations, delivery behavior, and egress policies. + tags: [OperationBindings] + parameters: + - $ref: '#/components/parameters/ConnectorType' + - $ref: '#/components/parameters/OperationKind' + - $ref: '#/components/parameters/Role' + - $ref: '#/components/parameters/Page' + - $ref: '#/components/parameters/Size' + responses: + '200': + description: Paged operation bindings. + content: + application/json: + schema: + $ref: '#/components/schemas/OperationBindingPage' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + post: + operationId: createOperationBinding + summary: Create an operation binding + description: | + Creates a source or destination operation binding. A source READ binding can later be + paired with a destination WRITE binding in a route, optionally with a transformation + between their resource descriptors. + tags: [OperationBindings] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/OperationBindingCreateRequest' + responses: + '201': + description: Operation binding created. + content: + application/json: + schema: + $ref: '#/components/schemas/OperationBinding' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + + /operation/bindings/{bindingId}: + get: + operationId: getOperationBinding + summary: Get an operation binding + description: | + Reads one operation binding, including connector-local operation name, protocol, request + and response descriptors, transformation reference, delivery settings, and egress policy. + tags: [OperationBindings] + parameters: + - $ref: '#/components/parameters/BindingId' + responses: + '200': + description: Operation binding. + content: + application/json: + schema: + $ref: '#/components/schemas/OperationBinding' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + patch: + operationId: updateOperationBinding + summary: Update an operation binding + description: | + Updates an operation binding without changing unrelated connector or resource descriptor + state. Use this for contract changes, renamed operation ids, updated delivery policies, + or new transformation references. + tags: [OperationBindings] + parameters: + - $ref: '#/components/parameters/BindingId' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/OperationBindingUpdateRequest' + responses: + '200': + description: Operation binding updated. + content: + application/json: + schema: + $ref: '#/components/schemas/OperationBinding' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + delete: + operationId: deleteOperationBinding + summary: Delete an operation binding + description: | + Deletes an operation binding. Implementations should reject deletion while active routes + still depend on the binding, or require those routes to be updated first. + tags: [OperationBindings] + parameters: + - $ref: '#/components/parameters/BindingId' + responses: + '204': + description: Operation binding deleted. + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + + /semantic/bindings: + get: + operationId: listSemanticConnectorBindings + summary: List semantic connector bindings + description: | + Lists semantic bindings for connector resources and fields. These bindings let the platform + understand that an external field represents an employee email, SSN, customer id, supplier + relationship, policy classification, or other semantic concept. + tags: [SemanticBindings] + parameters: + - $ref: '#/components/parameters/ConnectorType' + - $ref: '#/components/parameters/ResourceKind' + - $ref: '#/components/parameters/Page' + - $ref: '#/components/parameters/Size' + responses: + '200': + description: Paged semantic connector bindings. + content: + application/json: + schema: + $ref: '#/components/schemas/SemanticConnectorBindingPage' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + post: + operationId: createSemanticConnectorBinding + summary: Create a semantic connector binding + description: | + Creates a semantic binding for a connector resource or field. This is the link that allows + validation, documentation, mapping, and future policy checks to reason over external data + using the same semantic model as credential designs, forms, parties, and relationships. + tags: [SemanticBindings] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SemanticConnectorBindingCreateRequest' + responses: + '201': + description: Semantic connector binding created. + content: + application/json: + schema: + $ref: '#/components/schemas/SemanticConnectorBinding' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + + /invocation/bindings: + get: + operationId: listConnectorInvocationBindings + summary: List connector invocation bindings + description: | + Lists persisted invocation bindings that connect product or protocol lifecycle stages to + connector routes, operations, logical connection bindings, subset mappings, governance, and + execution policies. These records are the registry surface used when an issuer, verifier, + form, portal, or workflow needs a durable connector action at a named stage. + tags: [ConnectorInvocationBindings] + parameters: + - name: ownerSurface + in: query + required: false + description: Filter by the product or protocol surface that owns the invocation. + schema: + $ref: '#/components/schemas/ConnectorOwnerSurface' + example: OID4VCI + - name: ownerReference + in: query + required: false + description: Filter by owner-specific reference, such as issuer configuration id, verifier profile id, form id, or workflow id. + schema: + type: string + example: issuer-config-1 + - name: stage + in: query + required: false + description: Filter by product or protocol lifecycle stage. + schema: + $ref: '#/components/schemas/ConnectorInvocationStage' + example: OID4VCI_POST_ISSUANCE + - name: role + in: query + required: false + description: Filter by the connector's invocation role at the lifecycle stage. + schema: + $ref: '#/components/schemas/ConnectorInvocationRole' + example: VAULT_RETENTION + - name: logicalConnectionBindingId + in: query + required: false + description: Filter by logical connection binding used by the invocation. + schema: + $ref: '#/components/schemas/LogicalConnectionBindingId' + example: brand-a-proof-vault + - $ref: '#/components/parameters/Page' + - $ref: '#/components/parameters/Size' + responses: + '200': + description: Paged connector invocation bindings. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorInvocationBindingPage' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + post: + operationId: createConnectorInvocationBinding + summary: Create a connector invocation binding + description: | + Creates or replaces a durable invocation binding for a product or protocol lifecycle stage. + The stored binding carries the physical or logical connector target, subset mapping, + governance metadata, Party anchors, materialization policy, and execution policy that the + runtime will attach to resulting connector runs. + tags: [ConnectorInvocationBindings] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorInvocationBindingCreateRequest' + responses: + '201': + description: Connector invocation binding created. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorInvocationBinding' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + + /invocation/bindings/{invocationBindingId}: + get: + operationId: getConnectorInvocationBinding + summary: Get a connector invocation binding + description: Reads one persisted invocation binding by id. + tags: [ConnectorInvocationBindings] + parameters: + - $ref: '#/components/parameters/InvocationBindingId' + responses: + '200': + description: Connector invocation binding. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorInvocationBinding' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + + /logical/bindings: + get: + operationId: listLogicalConnectionBindings + summary: List logical connection bindings + description: | + Lists logical usage bindings for physical connector instances. Logical bindings let one + connector instance be safely reused across tenants, organization units, brands, legal + entities, channels, and caller contexts while keeping discriminator, auth overlay, + governance, and catalog projection metadata explicit. + tags: [LogicalConnectionBindings] + parameters: + - name: physicalConnectorInstanceId + in: query + required: false + description: Filter by the physical connector instance backing the logical binding. + schema: + $ref: '#/components/schemas/ConnectorInstanceId' + example: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + - name: organizationUnitId + in: query + required: false + description: Filter by organization unit in the logical context. + schema: + type: string + example: nl-ops + - name: brandId + in: query + required: false + description: Filter by brand in the logical context. + schema: + type: string + example: brand-a + - $ref: '#/components/parameters/Page' + - $ref: '#/components/parameters/Size' + responses: + '200': + description: Paged logical connection bindings. + content: + application/json: + schema: + $ref: '#/components/schemas/LogicalConnectionBindingPage' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + post: + operationId: createLogicalConnectionBinding + summary: Create a logical connection binding + description: | + Creates or replaces a logical connection binding for a physical connector instance. Use this + resource to declare tenant, OU, brand, channel, caller, auth overlay, grant, governance, and + system-catalog projection metadata without duplicating the physical connector registration. + tags: [LogicalConnectionBindings] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/LogicalConnectionBindingCreateRequest' + responses: + '201': + description: Logical connection binding created. + content: + application/json: + schema: + $ref: '#/components/schemas/LogicalConnectionBinding' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + + /logical/bindings/{logicalConnectionBindingId}: + get: + operationId: getLogicalConnectionBinding + summary: Get a logical connection binding + description: Reads one logical connection binding by id. + tags: [LogicalConnectionBindings] + parameters: + - $ref: '#/components/parameters/LogicalConnectionBindingId' + responses: + '200': + description: Logical connection binding. + content: + application/json: + schema: + $ref: '#/components/schemas/LogicalConnectionBinding' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + + /route/exposures: + get: + operationId: listRouteExposureDescriptors + summary: List route exposure descriptors + description: | + Lists externally callable route exposure descriptors. Exposure descriptors are registry + records for external read/write capabilities, including accepted auth methods, caller Party + and relationship constraints, schemas, subset mapping, payload/rate limits, and audit category. + tags: [RouteExposures] + parameters: + - name: logicalConnectionBindingId + in: query + required: false + description: Filter by logical connection binding backing the exposed capability. + schema: + $ref: '#/components/schemas/LogicalConnectionBindingId' + example: brand-a-proof-vault + - name: exchangeMode + in: query + required: false + description: Filter by the route exposure exchange quadrant. + schema: + $ref: '#/components/schemas/ConnectorExchangeMode' + example: EXTERNALLY_INITIATED_READ_FROM_VDX + - $ref: '#/components/parameters/Page' + - $ref: '#/components/parameters/Size' + responses: + '200': + description: Paged route exposure descriptors. + content: + application/json: + schema: + $ref: '#/components/schemas/RouteExposureDescriptorPage' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + post: + operationId: createRouteExposureDescriptor + summary: Create a route exposure descriptor + description: | + Creates or replaces a route exposure descriptor for an externally initiated connector + capability. This registers the externally callable surface but does not by itself implement + the runtime endpoint for the external caller. + tags: [RouteExposures] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/RouteExposureDescriptorCreateRequest' + responses: + '201': + description: Route exposure descriptor created. + content: + application/json: + schema: + $ref: '#/components/schemas/RouteExposureDescriptor' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + + /route/exposures/{exposureDescriptorId}: + get: + operationId: getRouteExposureDescriptor + summary: Get a route exposure descriptor + description: Reads one route exposure descriptor by id. + tags: [RouteExposures] + parameters: + - $ref: '#/components/parameters/ExposureDescriptorId' + responses: + '200': + description: Route exposure descriptor. + content: + application/json: + schema: + $ref: '#/components/schemas/RouteExposureDescriptor' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + + /route/exposures/{exposureDescriptorId}/read: + post: + operationId: executeRouteExposureRead + summary: Execute an externally initiated route exposure read + description: | + Executes an explicitly registered external-read route exposure. The caller supplies the + authenticated Party context, governed canonical fields already eligible for projection, + governance metadata, a policy decision, and optional cursor state. The response is an + approved governed view with manifest, policy lineage, selected fields, and cursor state. + This endpoint does not expose internal connector records, Party tables, vault rows, or + semantic stores directly. + tags: [RouteExposures] + parameters: + - $ref: '#/components/parameters/ExposureDescriptorId' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/RouteExposureExternalReadRequest' + responses: + '200': + description: Governed external-read view. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorExternalReadResponse' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + + /route/exposures/{exposureDescriptorId}/write: + post: + operationId: executeRouteExposureWrite + summary: Execute an externally initiated route exposure write + description: | + Executes an explicitly registered external-write route exposure. The caller supplies the + authenticated Party context, governed payload envelope, field mappings, governance metadata, + policy decision, optional idempotency key, and optional Party projection candidates. The + response is an accepted, minimized, redacted, quarantined, or rejected governed-ingress + receipt with canonical-field mapping, projection-candidate ids, policy lineage, idempotency + result, payload hash, and later-use availability scope. + tags: [RouteExposures] + parameters: + - $ref: '#/components/parameters/ExposureDescriptorId' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/RouteExposureExternalWriteRequest' + responses: + '200': + description: Governed external-write receipt. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorExternalWriteReceipt' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + + /data/products: + get: + operationId: listDataProductDescriptors + summary: List connector data product descriptors + description: | + Lists connector data product descriptors. These registry records connect a logical binding + and physical connector instance to dataset resource descriptors, selected field scopes, + transfer types, provider and consumer Party references, governance scope, and catalog offer + references. This is the Phase 5 dataspace/data-use-contract readiness surface; it does not + implement DSP/DCAT runtime behavior by itself. + tags: [ConnectorDataProducts] + parameters: + - name: logicalConnectionBindingId + in: query + required: false + description: Filter by logical connection binding backing the data product. + schema: + $ref: '#/components/schemas/LogicalConnectionBindingId' + example: brand-a-proof-vault + - name: physicalConnectorInstanceId + in: query + required: false + description: Filter by the physical connector instance backing the data product. + schema: + $ref: '#/components/schemas/ConnectorInstanceId' + example: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + - $ref: '#/components/parameters/Page' + - $ref: '#/components/parameters/Size' + responses: + '200': + description: Paged connector data product descriptors. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorDataProductDescriptorPage' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + post: + operationId: createDataProductDescriptor + summary: Create a connector data product descriptor + description: | + Creates or replaces a connector data product descriptor. The descriptor must reference an + existing logical connection binding, matching physical connector instance, known dataset + resource descriptors, at least one transfer type, and at least one catalog offer policy ref. + tags: [ConnectorDataProducts] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorDataProductDescriptorCreateRequest' + responses: + '201': + description: Connector data product descriptor created. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorDataProductDescriptor' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + + /data/products/{dataProductId}: + get: + operationId: getDataProductDescriptor + summary: Get a connector data product descriptor + description: Reads one connector data product descriptor by id. + tags: [ConnectorDataProducts] + parameters: + - $ref: '#/components/parameters/DataProductId' + responses: + '200': + description: Connector data product descriptor. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorDataProductDescriptor' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + + /transformations: + get: + operationId: listTransformations + summary: List transformations + description: | + Lists reusable transformations between resource descriptors. Transformations can represent + existing attribute mappers, expression-based mappings, template mappings, redaction steps, + lookup steps, or future workflow-specific transformation engines. + tags: [Transformations] + parameters: + - $ref: '#/components/parameters/Page' + - $ref: '#/components/parameters/Size' + - name: language + in: query + required: false + description: Filter by transformation language. + schema: + $ref: '#/components/schemas/TransformationLanguage' + example: ATTRIBUTE_MAPPER + - name: sourceDescriptorId + in: query + required: false + description: Filter by source resource descriptor id. + schema: + $ref: '#/components/schemas/ResourceDescriptorId' + example: 41436f49-040c-4f5f-9c7f-657f43762e2b + - name: targetDescriptorId + in: query + required: false + description: Filter by target resource descriptor id. + schema: + $ref: '#/components/schemas/ResourceDescriptorId' + example: 7a44f0de-e4d9-44ef-9211-372433933a88 + responses: + '200': + description: Paged transformations. + content: + application/json: + schema: + $ref: '#/components/schemas/TransformationPage' + '401': + $ref: '#/components/responses/Unauthorized' + post: + operationId: createTransformation + summary: Create a transformation + description: | + Creates a transformation definition. Use this when a route must map a source representation + to a destination representation, such as CSV employee rows to credential claims, REST HR + profiles to invitation payloads, or OIDC claims to a semantic profile. + tags: [Transformations] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/TransformationCreateRequest' + responses: + '201': + description: Transformation created. + content: + application/json: + schema: + $ref: '#/components/schemas/TransformationDefinition' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + + /transformations/{transformationId}: + get: + operationId: getTransformation + summary: Get a transformation + description: | + Reads one transformation definition, including source and target descriptors, step-based + mappings, expression text, and metadata used by the runtime mapper. + tags: [Transformations] + parameters: + - $ref: '#/components/parameters/TransformationId' + responses: + '200': + description: Transformation. + content: + application/json: + schema: + $ref: '#/components/schemas/TransformationDefinition' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + patch: + operationId: updateTransformation + summary: Update a transformation + description: | + Updates transformation metadata, descriptor references, steps, or expression text. Route + implementations should version or snapshot transformations when repeatable historical + execution is required. + tags: [Transformations] + parameters: + - $ref: '#/components/parameters/TransformationId' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/TransformationUpdateRequest' + responses: + '200': + description: Transformation updated. + content: + application/json: + schema: + $ref: '#/components/schemas/TransformationDefinition' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + + /routes: + get: + operationId: listConnectorRoutes + summary: List connector routes + description: | + Lists routes that compose source bindings, destination bindings, optional transformations, + triggers, delivery policy, materialization policy, and atomicity. Routes are the durable + registry shape for import/export, issuance enrichment, form capture, and workflow + data movement. + tags: [Routes] + parameters: + - $ref: '#/components/parameters/Page' + - $ref: '#/components/parameters/Size' + responses: + '200': + description: Paged connector routes. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorRoutePage' + '401': + $ref: '#/components/responses/Unauthorized' + post: + operationId: createConnectorRoute + summary: Create a connector route + description: | + Creates a route from one or more source operation bindings to one or more destination operation bindings. + The route can be on-demand, scheduled, event-triggered, webhook-triggered, or started by a + higher-level platform pipeline. + tags: [Routes] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorRouteCreateRequest' + responses: + '201': + description: Connector route created. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorRoute' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + + /routes/{routeId}: + get: + operationId: getConnectorRoute + summary: Get a connector route + description: | + Reads one route definition. Use this before starting a run when a UI or orchestrator needs + to show the effective source, destination, transformation, trigger, materialization, and + atomicity policy. + tags: [Routes] + parameters: + - $ref: '#/components/parameters/RouteId' + responses: + '200': + description: Connector route. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorRoute' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + patch: + operationId: updateConnectorRoute + summary: Update a connector route + description: | + Updates a route definition. Implementations should avoid mutating routes that are currently + running unless they snapshot the effective route definition into each run. + tags: [Routes] + parameters: + - $ref: '#/components/parameters/RouteId' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorRouteUpdateRequest' + responses: + '200': + description: Connector route updated. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorRoute' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + delete: + operationId: deleteConnectorRoute + summary: Delete a connector route + description: | + Deletes a route definition. Historical runs, events, and dead letters should remain subject + to audit and retention policies even when the route definition is removed. + tags: [Routes] + parameters: + - $ref: '#/components/parameters/RouteId' + responses: + '204': + description: Connector route deleted. + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + + /routes/{routeId}/runs: + get: + operationId: listConnectorRouteRuns + summary: List connector route runs + description: | + Lists execution history for one connector route. Use this route-scoped view when a route + detail screen or orchestrator needs only runs belonging to the selected route. Tenant-wide + operational dashboards should use `/runs` and its filters. + tags: [Runs] + parameters: + - $ref: '#/components/parameters/RouteId' + - $ref: '#/components/parameters/ConnectorRunStatus' + - $ref: '#/components/parameters/ConnectorInstanceIdQuery' + - $ref: '#/components/parameters/InvocationBindingIdQuery' + - $ref: '#/components/parameters/LogicalConnectionBindingIdQuery' + - $ref: '#/components/parameters/PhysicalConnectorInstanceIdQuery' + - $ref: '#/components/parameters/ConnectorExchangeModeQuery' + - $ref: '#/components/parameters/ProtocolSurfaceQuery' + - $ref: '#/components/parameters/CorrelationIdQuery' + - $ref: '#/components/parameters/Page' + - $ref: '#/components/parameters/Size' + responses: + '200': + description: Paged connector runs for the route. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorRunPage' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + post: + operationId: createConnectorRouteRun + summary: Start a connector route run + description: | + Starts a route run and returns the accepted execution record. The optional input can carry + lookup keys, batch references, dry-run flags, or caller metadata. Long-running execution is + observed through the runs, events, and dead-letter endpoints. + tags: [Runs] + parameters: + - $ref: '#/components/parameters/RouteId' + requestBody: + required: false + content: + application/json: + schema: + $ref: '#/components/schemas/StartConnectorRouteRunRequest' + responses: + '202': + description: Connector route run accepted. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorRun' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + + /runs: + get: + operationId: listConnectorRuns + summary: List connector runs + description: | + Lists route and operation runs across the tenant. Use this direct tenant-wide run resource + for operational dashboards, customer support, audit trails, retry decisions, and monitoring + failed or partially failed imports and exports. Use `/routes/{routeId}/runs` for + route-scoped history. + tags: [Runs] + parameters: + - $ref: '#/components/parameters/ConnectorRunStatus' + - $ref: '#/components/parameters/RouteIdQuery' + - $ref: '#/components/parameters/ConnectorInstanceIdQuery' + - $ref: '#/components/parameters/InvocationBindingIdQuery' + - $ref: '#/components/parameters/LogicalConnectionBindingIdQuery' + - $ref: '#/components/parameters/PhysicalConnectorInstanceIdQuery' + - $ref: '#/components/parameters/ConnectorExchangeModeQuery' + - $ref: '#/components/parameters/ProtocolSurfaceQuery' + - $ref: '#/components/parameters/CorrelationIdQuery' + - $ref: '#/components/parameters/Page' + - $ref: '#/components/parameters/Size' + responses: + '200': + description: Paged connector runs. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorRunPage' + '400': + $ref: '#/components/responses/ValidationError' + '401': + $ref: '#/components/responses/Unauthorized' + + /runs/{runId}: + get: + operationId: getConnectorRun + summary: Get a connector run + description: | + Reads one connector execution record, including status, timestamps, counts, correlation id, + and error summary. Detailed logs are exposed as run events. + tags: [Runs] + parameters: + - $ref: '#/components/parameters/RunId' + responses: + '200': + description: Connector run. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorRun' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + + /runs/{runId}/events: + get: + operationId: listConnectorRunEvents + summary: List connector run events + description: | + Lists timestamped run events emitted by the connector runtime. Events should contain enough + detail for support and audit without embedding sensitive payloads unless policy permits it. + tags: [Runs] + parameters: + - $ref: '#/components/parameters/RunId' + - $ref: '#/components/parameters/Page' + - $ref: '#/components/parameters/Size' + responses: + '200': + description: Paged connector run events. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorRunEventPage' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + + /runs/{runId}/deadletters: + get: + operationId: listConnectorDeadLetters + summary: List connector dead letters + description: | + Lists failed items captured for a run after validation, transformation, or destination + delivery failure. Dead letters should reference retained payloads rather than embedding + them by default so retention and sensitivity policy can control access. + tags: [Runs] + parameters: + - $ref: '#/components/parameters/RunId' + - $ref: '#/components/parameters/Page' + - $ref: '#/components/parameters/Size' + responses: + '200': + description: Paged connector dead letters. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorDeadLetterPage' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + +components: + securitySchemes: + bearer: + type: http + scheme: bearer + bearerFormat: JWT + description: Bearer JWT token. Tenant context is resolved from this token. + responses: + ValidationError: + description: Validation error. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + Unauthorized: + description: Authentication is required. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + NotFound: + description: The requested resource was not found. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + parameters: + Page: + name: page + in: query + description: Zero-based page index. + schema: + type: integer + minimum: 0 + default: 0 + Size: + name: size + in: query + description: Page size. + schema: + type: integer + minimum: 1 + maximum: 100 + default: 20 + ConnectorInstanceId: + name: connectorInstanceId + in: path + description: Stable identifier of the configured connector instance. This is not the Party id; the connector instance has its own id and points at its backing Party. + required: true + schema: + $ref: '#/components/schemas/ConnectorInstanceId' + example: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + IdentityId: + name: identityId + in: path + description: Stable Identity id assigned to the connector Party. Identifiers remain nested under the Identity. + required: true + schema: + $ref: '#/components/schemas/IdentityId' + example: 3a5cf979-2d89-4057-a721-c7ab884f0c68 + ResourceDescriptorId: + name: resourceDescriptorId + in: path + description: Stable identifier of the resource descriptor that describes the shape, representation, and semantic meaning of a connector resource. + required: true + schema: + $ref: '#/components/schemas/ResourceDescriptorId' + example: 41436f49-040c-4f5f-9c7f-657f43762e2b + BindingId: + name: bindingId + in: path + description: Stable identifier of an operation binding, such as a configured source read or destination write operation. + required: true + schema: + $ref: '#/components/schemas/OperationBindingId' + example: 2777417e-82ce-4d3e-b96c-94e00a4d9a93 + TransformationId: + name: transformationId + in: path + description: Stable identifier of a reusable transformation between resource descriptors. + required: true + schema: + $ref: '#/components/schemas/TransformationId' + example: 0e60abcc-41b5-4cc5-bec2-f0047f129341 + RouteId: + name: routeId + in: path + description: Stable identifier of a connector route that composes a source operation, destination operation, optional transformation, and trigger policy. + required: true + schema: + $ref: '#/components/schemas/ConnectorRouteId' + example: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + RunId: + name: runId + in: path + description: Stable identifier of a connector route or operation execution. + required: true + schema: + $ref: '#/components/schemas/ConnectorRunId' + example: 9a785884-63ea-4b07-9976-264a1fc595f1 + InvocationBindingId: + name: invocationBindingId + in: path + description: Stable identifier of a connector invocation binding. + required: true + schema: + $ref: '#/components/schemas/ConnectorInvocationBindingId' + example: issuer-config-1:post-issuance:proof-vault + LogicalConnectionBindingId: + name: logicalConnectionBindingId + in: path + description: Stable identifier of a logical connection binding. + required: true + schema: + $ref: '#/components/schemas/LogicalConnectionBindingId' + example: brand-a-proof-vault + ExposureDescriptorId: + name: exposureDescriptorId + in: path + description: Stable identifier of a route exposure descriptor. + required: true + schema: + $ref: '#/components/schemas/RouteExposureDescriptorId' + example: proof-vault-read-exposure + DataProductId: + name: dataProductId + in: path + description: Stable identifier of a connector data product descriptor. + required: true + schema: + $ref: '#/components/schemas/ConnectorDataProductId' + example: dp-proof-status + Role: + name: role + in: query + description: Filters connectors or attached resources by data-flow role. + required: false + schema: + $ref: '#/components/schemas/DataFlowRole' + example: SOURCE + OperationKind: + name: operationKind + in: query + description: Filters by the logical operation taxonomy, independent of the transport-specific operation name. + required: false + schema: + $ref: '#/components/schemas/OperationKind' + example: READ + ResourceKind: + name: resourceKind + in: query + description: Filters by logical resource kind. This does not imply a transport or serialization format. + required: false + schema: + $ref: '#/components/schemas/ResourceKind' + example: TABULAR + ConnectorType: + name: connectorType + in: query + description: Filters by extensible connector runtime family, for example http.openapi, sql.postgresql, identity.oidc, storage.vault, storage.blob, interaction.form, or internal.party-semantic-store. CSV remains a representation kind, not a connector type. + required: false + schema: + $ref: '#/components/schemas/ConnectorType' + example: http.openapi + ConnectorRunStatus: + name: status + in: query + description: Filters connector executions by lifecycle status. + required: false + schema: + $ref: '#/components/schemas/ConnectorRunStatus' + example: FAILED + RouteIdQuery: + name: routeId + in: query + description: Filters connector executions by route id. + required: false + schema: + $ref: '#/components/schemas/ConnectorRouteId' + example: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + ConnectorInstanceIdQuery: + name: connectorInstanceId + in: query + description: Filters connector executions by the registry connector instance id. + required: false + schema: + $ref: '#/components/schemas/ConnectorInstanceId' + example: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + InvocationBindingIdQuery: + name: invocationBindingId + in: query + description: Filters connector executions by Phase 5 invocation binding lineage. + required: false + schema: + $ref: '#/components/schemas/ConnectorInvocationBindingId' + example: issuer-config-1:post-issuance:proof-vault + LogicalConnectionBindingIdQuery: + name: logicalConnectionBindingId + in: query + description: Filters connector executions by logical connection binding lineage. + required: false + schema: + $ref: '#/components/schemas/LogicalConnectionBindingId' + example: brand-a-proof-vault + PhysicalConnectorInstanceIdQuery: + name: physicalConnectorInstanceId + in: query + description: Filters connector executions by physical connector instance lineage. + required: false + schema: + $ref: '#/components/schemas/ConnectorInstanceId' + example: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + ConnectorExchangeModeQuery: + name: exchangeMode + in: query + description: Filters connector executions by the Phase 5 data-direction and initiation-side quadrant. + required: false + schema: + $ref: '#/components/schemas/ConnectorExchangeMode' + example: PLATFORM_INITIATED_PUSH + ProtocolSurfaceQuery: + name: protocolSurface + in: query + description: Filters connector executions by the product, protocol, form, portal, workflow, or application surface that initiated the run. + required: false + schema: + $ref: '#/components/schemas/ConnectorOwnerSurface' + example: OID4VCI + CorrelationIdQuery: + name: correlationId + in: query + description: Filters connector executions by durable route-run correlation id. + required: false + schema: + type: string + example: route-correlation-1 + + schemas: + ApiError: + type: object + description: Stable, machine-readable error body content. + required: + - code + - message + properties: + code: + type: string + description: Stable, machine-readable error category. + example: VALIDATION_ERROR + message: + type: string + description: Human-readable error message. + example: Request validation failed. + details: + type: object + additionalProperties: true + description: Additional error context or field-level details. + ErrorResponse: + type: object + description: Standard error envelope. + required: + - error + properties: + error: + $ref: '#/components/schemas/ApiError' + ConnectorInstanceId: + type: string + format: uuid + description: Stable platform identifier for a configured connector instance. + example: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + ConnectorPartyId: + type: string + format: uuid + description: Party identifier assigned to the connector instance. + example: f9c97b4e-e756-4b70-b230-6f1d9f81b426 + PartyId: + type: string + format: uuid + description: Existing Party model identifier. + example: 7f23f56e-c24d-4cbe-839d-5fc09048a851 + IdentityId: + type: string + format: uuid + description: Existing Identity model identifier. + example: 3a5cf979-2d89-4057-a721-c7ab884f0c68 + IdentifierId: + type: string + format: uuid + description: Existing Identifier model identifier. + example: 6b1c4c89-dfe0-4ce2-b8a4-2e1d57343a6c + ResourceDescriptorId: + type: string + format: uuid + description: Stable identifier for a described external or internal resource shape. + example: 41436f49-040c-4f5f-9c7f-657f43762e2b + FieldDescriptorId: + type: string + format: uuid + description: Stable identifier for a field within a resource descriptor. + example: f00b9edc-5498-483f-9b91-a42ef080b909 + ConnectorResourceId: + type: string + format: uuid + description: Stable identifier for a resource attached to a connector instance. + example: b4cf21b1-0292-4803-8d32-9ebf9f5359a2 + OperationBindingId: + type: string + format: uuid + description: Stable identifier for a connector operation binding. + example: 2777417e-82ce-4d3e-b96c-94e00a4d9a93 + SemanticBindingId: + type: string + format: uuid + description: Stable identifier for a semantic binding between resource data and VDX semantics. + example: 20392e94-3b35-4a77-afc2-5e552a0a4023 + TransformationId: + type: string + format: uuid + description: Stable identifier for a transformation definition. + example: 0e60abcc-41b5-4cc5-bec2-f0047f129341 + ConnectorRouteId: + type: string + format: uuid + description: Stable identifier for a connector route. + example: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + ConnectorRunId: + type: string + format: uuid + description: Stable identifier for a connector route or operation run. + example: 9a785884-63ea-4b07-9976-264a1fc595f1 + ConnectorInvocationBindingId: + type: string + description: Stable identifier of the domain invocation binding that caused a connector call. + example: issuer-config-1:post-issuance:proof-vault + LogicalConnectionBindingId: + type: string + description: Stable identifier of a tenant, OU, brand, legal-entity, or channel usage binding for a physical connector instance. + example: brand-a-proof-vault + RouteExposureDescriptorId: + type: string + description: Stable identifier of an externally callable route exposure descriptor. + example: proof-vault-read-exposure + ConnectorDataProductId: + type: string + description: Stable identifier of a connector data product descriptor. + example: dp-proof-status + ConnectorType: + type: string + description: Extensible connector family identifier. This names the connector implementation or adapter family, not the transport, resource kind, or representation. + example: http.openapi + description: Tenant identifier used by tenant-scoped connector registration, routing, and execution. + example: acme + + DataFlowRole: + type: string + description: How a connector participates in data movement. Use SOURCE for reads and DESTINATION for writes. Connectors that support both roles declare both values in supportedRoles. + enum: + - SOURCE + - DESTINATION + example: SOURCE + ConnectorLifecycleStatus: + type: string + description: Lifecycle state of a connector instance in the connector registry. + enum: + - DRAFT + - ACTIVE + - SUSPENDED + - RETIRED + example: ACTIVE + ConnectorManagementMode: + type: string + description: Indicates whether the platform manages connector runtime/configuration or references an externally managed system. Runtime placement is described separately by runtimeMode. + enum: + - MANAGED + - EXTERNAL + example: EXTERNAL + ConnectorRuntimeMode: + type: string + description: Indicates where execution happens when a connector operation is invoked. + enum: + - HOSTED + - REMOTE_AGENT + - EXTERNAL_CALLBACK + example: REMOTE_AGENT + ConnectorExchangeMode: + type: string + description: Explicit exchange quadrant. Data direction and initiation side remain separate axes in run responses. + enum: + - PLATFORM_INITIATED_PULL + - PLATFORM_INITIATED_PUSH + - EXTERNALLY_INITIATED_READ_FROM_VDX + - EXTERNALLY_INITIATED_WRITE_INTO_VDX + - SUBSCRIPTION_CALLBACK + - BIDIRECTIONAL_SYNC + example: PLATFORM_INITIATED_PUSH + ConnectorDataDirection: + type: string + description: Direction of data movement relative to VDX. + enum: + - INTO_VDX + - OUT_OF_VDX + - BIDIRECTIONAL + example: OUT_OF_VDX + ConnectorInitiationSide: + type: string + description: Side that initiated the exchange. + enum: + - PLATFORM + - EXTERNAL + - SUBSCRIPTION_CALLBACK + - BIDIRECTIONAL_SYNC + example: PLATFORM + ConnectorOwnerSurface: + type: string + description: Product, protocol, form, portal, workflow, or application surface that owns a connector invocation binding. + enum: + - OID4VCI + - OID4VP + - FORM + - PORTAL + - WORKFLOW + - APPLICATION + example: OID4VCI + ConnectorInvocationStage: + type: string + description: Product or protocol lifecycle stage at which a connector invocation can run. + enum: + - OID4VCI_AUTHORIZATION + - OID4VCI_PRE_AUTHORIZED + - OID4VCI_TOKEN + - OID4VCI_CREDENTIAL_REQUEST + - OID4VCI_DEFERRED + - OID4VCI_PRE_ISSUE + - OID4VCI_POST_ISSUANCE + - OID4VCI_NOTIFICATION_RECEIPT + - OID4VP_AFTER_VALIDATION + - OID4VP_PRE_REQUEST_ENRICHMENT + - FORM_LIFECYCLE + - FORM_ACTION_START + - FORM_ACTION_COMPLETE + - FORM_FIELD_LOOKUP + - FORM_SUBMIT + - PORTAL_FLOW + - WORKFLOW_STEP_EXECUTION + example: OID4VCI_POST_ISSUANCE + ConnectorInvocationRole: + type: string + description: Role the connector performs for a lifecycle invocation. + enum: + - ENRICHMENT_SOURCE + - EXPORT_DESTINATION + - VAULT_RETENTION + - NOTIFICATION + - BIDIRECTIONAL_SYNC + - ROUTE_ORCHESTRATION + example: VAULT_RETENTION + ConnectorExecutionTiming: + type: string + description: Timing contract for connector invocation execution. + enum: + - INLINE_REQUIRED + - INLINE_OPTIONAL + - DEFERRED_ASYNC + - DURABLE_OUTBOX + example: INLINE_REQUIRED + ConnectorFailureEffect: + type: string + description: How connector invocation failure affects the owning protocol, form, portal, or workflow. + enum: + - FAIL_PROTOCOL + - CONTINUE_WITHOUT_EFFECT + - DEAD_LETTER + - QUARANTINE + - RETRY_ONLY + example: FAIL_PROTOCOL + ConnectorDiscriminatorSource: + type: string + description: Source of a logical connection discriminator value. + enum: + - LOGICAL_CONTEXT + - AUTHENTICATED_CONTEXT + - PAYLOAD_FIELD + - STATIC_VALUE + example: LOGICAL_CONTEXT + ConnectorDiscriminatorPlacement: + type: string + description: Where a logical connection discriminator is applied to an outbound connector request. + enum: + - HEADER + - QUERY + - BODY_FIELD + - CONFIG + - METADATA + example: HEADER + ConnectorAuthOverlayMode: + type: string + description: Authentication overlay mode for a logical connection binding. + enum: + - USE_PHYSICAL_BASE + - TENANT_SECRET_REF + - DELEGATED_OAUTH_CLIENT + - MTLS_IDENTITY + - CONNECTOR_CREDENTIAL_SELECTOR + example: TENANT_SECRET_REF + ConnectorDeploymentMode: + type: string + description: Deployment mode projected into the system catalog for a logical connection binding. + enum: + - MANAGED + - EXTERNAL + - HYBRID + example: HYBRID + ConnectorAuditCategory: + type: string + description: Audit category used by governed connector invocations, runs, and externally callable route exposures. + enum: + - PROTOCOL_ISSUANCE + - PROTOCOL_VERIFICATION + - FORM + - PORTAL + - WORKFLOW + - DATASPACE + - INDUSTRIAL + - EXTERNAL_EXCHANGE + - VAULT + - SYSTEM_CATALOG + example: EXTERNAL_EXCHANGE + OperationKind: + type: string + description: Reusable operation taxonomy shared by connectors, inventory, policy, and workflows. The operation kind is logical; connector-local details live in operationName. + enum: + - READ + - WRITE + - UPDATE + - DELETE + - UPSERT + - QUERY + - SEARCH + - IMPORT + - EXPORT + - INVOKE + - DISCOVER + - VALIDATE + example: READ + OperationTransferMode: + type: string + description: Transfer semantics for an operation binding. Streaming and batching are execution modes of a logical operation, not operation kinds. + enum: + - SINGLE + - BATCH + - STREAM + default: SINGLE + example: STREAM + AccessProtocol: + type: string + description: "Transport or access protocol. This is intentionally separate from ResourceKind and RepresentationKind: for example, CSV data can be read over HTTPS, S3, SFTP, FILE, or VAULT." + enum: + - HTTP + - HTTPS + - JDBC + - ODBC + - SFTP + - FILE + - S3 + - AZURE_BLOB + - GCS + - KAFKA + - AMQP + - MQTT + - OIDC + - DIDCOMM + - VAULT + - INTERNAL + - CUSTOM + example: HTTPS + ResourceKind: + type: string + description: Logical kind of resource being accessed, independent of transport and serialization. For example, a CSV file with rows is ResourceKind TABULAR and RepresentationKind CSV. + enum: + - OBJECT + - TABULAR + - DOCUMENT + - CLAIM_SET + - GRAPH + - EVENT_STREAM + - FILE + - SECRET + - CONFIGURATION + - CREDENTIAL + - PRESENTATION + - CUSTOM + example: TABULAR + RepresentationKind: + type: string + description: Data representation or serialization format, independent of transport. This is the data shape on the wire or at rest, not the connector implementation. + enum: + - JSON + - JSON_LD + - XML + - CSV + - PARQUET + - AVRO + - RDF + - JWT + - SD_JWT + - CBOR + - BINARY + - TEXT + - CUSTOM + example: CSV + ShapeKind: + type: string + description: Type of structural shape information used to describe fields and validation rules for a resource. + enum: + - SCHEMA + - OPENAPI_SCHEMA + - JSON_SCHEMA + - RDF_SHAPE + - SQL_TABLE + - CSV_HEADER + - CLAIMS_SCHEMA + - FREEFORM + example: CSV_HEADER + ContractKind: + type: string + description: Contract or schema source used to describe an external resource. Use this to point at OpenAPI documents, JSON Schema, SQL metadata, RDF shapes, CSV profiles, OIDC discovery, or custom contracts. + enum: + - OPENAPI + - JSON_SCHEMA + - SQL_SCHEMA + - RDF_SCHEMA + - CSV_PROFILE + - OIDC_DISCOVERY + - VAULT_POLICY + - CUSTOM + example: OPENAPI + BindingDirection: + type: string + description: Direction of data movement represented by an operation binding. + enum: + - INBOUND + - OUTBOUND + - BIDIRECTIONAL + example: INBOUND + TransformationLanguage: + type: string + description: Transformation representation used by a transformation definition. + enum: + - ATTRIBUTE_MAPPER + - JSONATA + - JQ + - CEL + - SQL + - TEMPLATE + - CUSTOM + example: ATTRIBUTE_MAPPER + MaterializationMode: + type: string + description: How, if at all, connector data may be retained or projected into platform storage. + enum: + - NONE + - CACHE + - PERSIST + - MIRROR + - INDEX + example: PERSIST + SecretBindingMode: + type: string + description: How credentials are referenced. Secret values are never sent inline through this API. + enum: + - SECRET_REF + - VAULT_KEY + - EXTERNAL_SECRET_REF + example: SECRET_REF + ConnectorRunStatus: + type: string + description: Execution status of a route run or connector operation run. + enum: + - QUEUED + - RUNNING + - SUCCEEDED + - FAILED + - PARTIALLY_FAILED + - CANCELLED + example: SUCCEEDED + RouteAtomicity: + type: string + description: Failure and rollback semantics expected for a route run. + enum: + - BEST_EFFORT + - PER_RECORD + - ALL_OR_NOTHING + example: PER_RECORD + DestinationDeliveryMode: + type: string + description: Delivery timing and batching behavior expected by a destination operation binding. + enum: + - SYNC + - ASYNC + - BATCH + - STREAMING + example: BATCH + DestinationAckMode: + type: string + description: Acknowledgement level a destination must provide before the platform treats delivery as complete. + enum: + - NONE + - ACCEPTED + - COMMITTED + - VERIFIED + example: COMMITTED + RetentionDeleteAction: + type: string + description: Action to apply when retention expires or deletion is required by policy. + enum: + - DELETE + - ANONYMIZE + - PSEUDONYMIZE + - TOMBSTONE + - REVIEW + example: ANONYMIZE + + ConnectorInstanceCreateRequest: + type: object + description: Request to register a connector instance and create or link the backing Party. Identity data is required so the connector aggregate is Party-backed at creation time. + required: + - displayName + - connectorType + - supportedRoles + - identities + properties: + displayName: + type: string + minLength: 1 + description: Human-readable name shown in administrative UIs and audit trails. + example: Workday employee profile API + description: + type: string + description: Operational purpose of the connector instance. + example: Reads employee profile attributes used for employee credential issuance. + connectorType: + $ref: '#/components/schemas/ConnectorType' + managementMode: + $ref: '#/components/schemas/ConnectorManagementMode' + runtimeMode: + $ref: '#/components/schemas/ConnectorRuntimeMode' + partyId: + $ref: '#/components/schemas/PartyId' + supportedRoles: + type: array + description: Data-flow roles supported by this connector instance. + minItems: 1 + uniqueItems: true + items: + $ref: '#/components/schemas/DataFlowRole' + example: [SOURCE] + supportedOperations: + type: array + description: Logical operations this connector instance can perform. + uniqueItems: true + items: + $ref: '#/components/schemas/OperationKind' + example: [READ, QUERY, DISCOVER] + identities: + type: array + description: Identities assigned to the connector Party. Exactly one identity must be marked as default. Each identity must reference an existing identity or include at least one identifier. + minItems: 1 + items: + $ref: '#/components/schemas/ConnectorIdentityInput' + endpoints: + type: array + description: Runtime endpoints exposed or consumed by this connector instance. + items: + $ref: '#/components/schemas/ConnectorEndpointInput' + credentials: + type: array + description: Credential references used by the connector. Secret values are never sent inline. + items: + $ref: '#/components/schemas/ConnectorCredentialRef' + configBindings: + type: array + description: Platform settings bindings that hold non-secret connector configuration and secret reference prefixes. + items: + $ref: '#/components/schemas/ConnectorConfigBindingRef' + defaultAccessProtocol: + $ref: '#/components/schemas/AccessProtocol' + defaultEgressPolicy: + $ref: '#/components/schemas/EgressPolicy' + defaultMaterializationPolicy: + $ref: '#/components/schemas/MaterializationPolicy' + metadata: + $ref: '#/components/schemas/StringMap' + example: + displayName: Workday employee profile API + description: Reads employee profile attributes used for employee credential issuance. + connectorType: http.openapi + managementMode: EXTERNAL + runtimeMode: REMOTE_AGENT + supportedRoles: [SOURCE] + supportedOperations: [READ, QUERY, DISCOVER] + identities: + - identityRole: external-system + displayName: Workday tenant acme-prod + isDefault: true + identifiers: + - identifierType: DNS_NAME + value: hr.example.com + isPrimary: true + isVerified: true + - identifierType: SYSTEM_ID + value: workday:acme-prod + isPrimary: false + isVerified: true + endpoints: + - endpointRole: data + accessProtocol: HTTPS + uri: https://hr.example.com/api/v1 + isPrimary: true + credentials: + - bindingMode: SECRET_REF + secretRef: secret://tenant/acme/connectors/workday/oauth-client + credentialType: oauth2-client + label: Workday OAuth client + configBindings: + - settingsScope: service-instance + settingsKeyPrefix: connector.workday.acme-prod + defaultAccessProtocol: HTTPS + metadata: + owner_team: people-ops + + ConnectorInstanceUpdateRequest: + type: object + description: Partial update for connector instance metadata, lifecycle status, supported operations, and default policies. Omitted fields remain unchanged. + properties: + displayName: + type: string + description: Updated display name. + example: Workday employee profile API + description: + type: string + description: Updated operational description. + example: Reads employee profile attributes through the regional HR integration. + lifecycleStatus: + $ref: '#/components/schemas/ConnectorLifecycleStatus' + managementMode: + $ref: '#/components/schemas/ConnectorManagementMode' + runtimeMode: + $ref: '#/components/schemas/ConnectorRuntimeMode' + supportedRoles: + type: array + minItems: 1 + uniqueItems: true + items: + $ref: '#/components/schemas/DataFlowRole' + supportedOperations: + type: array + uniqueItems: true + items: + $ref: '#/components/schemas/OperationKind' + defaultAccessProtocol: + $ref: '#/components/schemas/AccessProtocol' + defaultEgressPolicy: + $ref: '#/components/schemas/EgressPolicy' + defaultMaterializationPolicy: + $ref: '#/components/schemas/MaterializationPolicy' + metadata: + $ref: '#/components/schemas/StringMap' + example: + lifecycleStatus: ACTIVE + supportedOperations: [READ, QUERY, DISCOVER] + metadata: + owner_team: people-ops + support_queue: hr-integrations + + ConnectorInstance: + type: object + description: Registered connector instance with its own stable id and a backing Party id. Runtime credentials are represented only as references. + required: + - connectorInstanceId + - partyId + - displayName + - connectorType + - lifecycleStatus + - supportedRoles + - createdAt + - updatedAt + properties: + connectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + partyId: + $ref: '#/components/schemas/ConnectorPartyId' + displayName: + type: string + description: Human-readable name of the connector instance. + example: Workday employee profile API + description: + type: string + description: Operational purpose of the connector instance. + example: Reads employee profile attributes used for employee credential issuance. + connectorType: + $ref: '#/components/schemas/ConnectorType' + lifecycleStatus: + $ref: '#/components/schemas/ConnectorLifecycleStatus' + managementMode: + $ref: '#/components/schemas/ConnectorManagementMode' + runtimeMode: + $ref: '#/components/schemas/ConnectorRuntimeMode' + defaultAccessProtocol: + $ref: '#/components/schemas/AccessProtocol' + supportedRoles: + type: array + items: + $ref: '#/components/schemas/DataFlowRole' + supportedOperations: + type: array + items: + $ref: '#/components/schemas/OperationKind' + identities: + type: array + items: + $ref: '#/components/schemas/ConnectorIdentity' + endpoints: + type: array + items: + $ref: '#/components/schemas/ConnectorEndpoint' + credentials: + type: array + items: + $ref: '#/components/schemas/ConnectorCredentialRef' + configBindings: + type: array + items: + $ref: '#/components/schemas/ConnectorConfigBindingRef' + defaultEgressPolicy: + $ref: '#/components/schemas/EgressPolicy' + defaultMaterializationPolicy: + $ref: '#/components/schemas/MaterializationPolicy' + metadata: + $ref: '#/components/schemas/StringMap' + createdAt: + type: string + format: date-time + description: Creation timestamp. + example: '2026-06-18T08:30:00Z' + updatedAt: + type: string + format: date-time + description: Last update timestamp. + example: '2026-06-18T08:45:00Z' + example: + connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + partyId: f9c97b4e-e756-4b70-b230-6f1d9f81b426 + displayName: Workday employee profile API + description: Reads employee profile attributes used for employee credential issuance. + connectorType: http.openapi + lifecycleStatus: ACTIVE + managementMode: EXTERNAL + runtimeMode: REMOTE_AGENT + defaultAccessProtocol: HTTPS + supportedRoles: [SOURCE] + supportedOperations: [READ, QUERY, DISCOVER] + identities: + - identityId: 3a5cf979-2d89-4057-a721-c7ab884f0c68 + identityRole: external-system + displayName: Workday tenant acme-prod + isDefault: true + identifiers: + - identifierId: 6b1c4c89-dfe0-4ce2-b8a4-2e1d57343a6c + identifierType: DNS_NAME + value: hr.example.com + isPrimary: true + isVerified: true + endpoints: + - endpointId: 27d8bfc5-6c75-4e4e-a78a-63ad7a924cb1 + endpointRole: data + accessProtocol: HTTPS + uri: https://hr.example.com/api/v1 + isPrimary: true + credentials: + - bindingMode: SECRET_REF + secretRef: secret://tenant/acme/connectors/workday/oauth-client + credentialType: oauth2-client + label: Workday OAuth client + configBindings: + - settingsScope: service-instance + settingsKeyPrefix: connector.workday.acme-prod + metadata: + owner_team: people-ops + createdAt: '2026-06-18T08:30:00Z' + updatedAt: '2026-06-18T08:45:00Z' + + ConnectorIdentityInput: + type: object + description: Identity assignment for the connector Party. Use existingIdentityId to link an existing Identity, or provide displayName and identifiers to create a connector-specific Identity. + required: + - identityRole + properties: + identityRole: + type: string + description: Role of this Identity for the connector Party, for example technical-account, issuer, relying-party, or external-system. + displayName: + type: string + description: Display name for the connector identity. + example: Workday tenant acme-prod + existingIdentityId: + $ref: '#/components/schemas/IdentityId' + isDefault: + type: boolean + description: Whether this identity is the default identity for connector operations that do not select a specific identity. + default: false + example: true + identifiers: + type: array + description: Identifiers attached to this Identity. Identifiers are not attached directly to the connector. + minItems: 1 + items: + $ref: '#/components/schemas/ConnectorIdentifierInput' + example: + identityRole: external-system + displayName: Workday tenant acme-prod + isDefault: true + identifiers: + - identifierType: DNS_NAME + value: hr.example.com + isPrimary: true + isVerified: true + - identifierType: SYSTEM_ID + value: workday:acme-prod + isPrimary: false + isVerified: true + + ConnectorIdentity: + type: object + description: Identity assigned to the connector Party, including its nested identifiers. + required: + - identityId + - identityRole + - isDefault + properties: + identityId: + $ref: '#/components/schemas/IdentityId' + identityRole: + type: string + description: Role of this Identity for the connector Party. + example: external-system + displayName: + type: string + description: Display name for the connector identity. + example: Workday tenant acme-prod + isDefault: + type: boolean + description: Whether this is the default identity for the connector. + example: true + identifiers: + type: array + description: Identifiers attached to this Identity. + items: + $ref: '#/components/schemas/ConnectorIdentifier' + example: + identityId: 3a5cf979-2d89-4057-a721-c7ab884f0c68 + identityRole: external-system + displayName: Workday tenant acme-prod + isDefault: true + identifiers: + - identifierId: 6b1c4c89-dfe0-4ce2-b8a4-2e1d57343a6c + identifierType: DNS_NAME + value: hr.example.com + isPrimary: true + isVerified: true + + ConnectorIdentifierInput: + type: object + description: Identifier attached to a connector Identity. Use this for DNS names, URLs, DID identifiers, OIDC issuers, client ids, system ids, or other Party identifier types. + required: + - identifierType + - value + properties: + identifierType: + type: string + description: Existing Party Identifier type, for example DNS_NAME, URL, DID, OIDC_ISSUER, EMAIL, CLIENT_ID, or SYSTEM_ID. + value: + type: string + description: Identifier value. + example: hr.example.com + isPrimary: + type: boolean + description: Whether this is the preferred identifier for its type on the Identity. + default: false + example: true + isVerified: + type: boolean + description: Whether the platform has verified or administratively accepted this identifier. + default: false + example: true + metadata: + $ref: '#/components/schemas/StringMap' + example: + identifierType: DNS_NAME + value: hr.example.com + isPrimary: true + isVerified: true + metadata: + verification_method: dns-control + + ConnectorIdentifier: + description: Stored identifier attached to a connector Identity. + allOf: + - $ref: '#/components/schemas/ConnectorIdentifierInput' + - type: object + required: + - identifierId + properties: + identifierId: + $ref: '#/components/schemas/IdentifierId' + example: + identifierId: 6b1c4c89-dfe0-4ce2-b8a4-2e1d57343a6c + identifierType: DNS_NAME + value: hr.example.com + isPrimary: true + isVerified: true + + ConnectorEndpointInput: + type: object + description: Endpoint or address used by a connector. The endpoint says how to reach the connector; resource descriptors say what data is exchanged. + required: + - accessProtocol + properties: + endpointRole: + type: string + description: Role of this endpoint, for example management, data, discovery, callback, token, or webhook. + accessProtocol: + $ref: '#/components/schemas/AccessProtocol' + uri: + type: string + description: Endpoint URI, JDBC URL, bucket URI, file root, queue address, or connector-specific locator. + example: https://hr.example.com/api/v1 + isPrimary: + type: boolean + description: Whether this endpoint is the default endpoint for its role. + default: false + example: true + metadata: + $ref: '#/components/schemas/StringMap' + example: + endpointRole: data + accessProtocol: HTTPS + uri: https://hr.example.com/api/v1 + isPrimary: true + metadata: + region: eu-west + + ConnectorEndpoint: + description: Stored connector endpoint. + allOf: + - $ref: '#/components/schemas/ConnectorEndpointInput' + - type: object + required: + - endpointId + properties: + endpointId: + type: string + format: uuid + description: Stable endpoint identifier. + example: 27d8bfc5-6c75-4e4e-a78a-63ad7a924cb1 + example: + endpointId: 27d8bfc5-6c75-4e4e-a78a-63ad7a924cb1 + endpointRole: data + accessProtocol: HTTPS + uri: https://hr.example.com/api/v1 + isPrimary: true + + ConnectorCredentialRef: + type: object + description: Reference to credential material used by a connector. The referenced secret can live in platform settings, vault, KMS-backed storage, or an external secret manager. + required: + - bindingMode + properties: + bindingMode: + $ref: '#/components/schemas/SecretBindingMode' + credentialId: + type: string + format: uuid + description: Optional platform credential identifier when credentials are first-class resources. + example: 8cd48897-9fb2-4a1a-a044-bd71a3e86e61 + secretRef: + type: string + description: Opaque platform secret reference, not a secret value. + example: secret://tenant/acme/connectors/workday/oauth-client + externalSecretRef: + type: string + description: External secret-manager reference when the platform does not own the secret. + example: aws-secretsmanager://prod/acme/workday/oauth-client + credentialType: + type: string + description: Connector-specific credential type, for example oauth2-client, api-key, username-password, ssh-key, certificate, or service-account. + example: oauth2-client + label: + type: string + description: Administrative label for the credential reference. + example: Workday OAuth client + keyAlias: + type: string + description: Optional KMS or vault key alias used by the connector. + example: tenant-acme-workday-client-key + metadata: + $ref: '#/components/schemas/StringMap' + example: + bindingMode: SECRET_REF + secretRef: secret://tenant/acme/connectors/workday/oauth-client + credentialType: oauth2-client + label: Workday OAuth client + metadata: + rotation: managed-by-security + + ConnectorConfigBindingRef: + type: object + description: Reference to platform settings used by the connector. Use this for non-secret configuration and as the durable pointer to secret key prefixes. + properties: + configBindingId: + type: string + format: uuid + description: Stable settings/configuration binding identifier. + example: 5724bdf7-a83f-42c6-b336-bf5ee98be529 + settingsScope: + type: string + description: Platform settings scope used by the connector, for example tenant, service, instance, or route. + example: service-instance + settingsKeyPrefix: + type: string + description: Prefix under which connector settings are stored. + example: connector.workday.acme-prod + metadata: + $ref: '#/components/schemas/StringMap' + example: + configBindingId: 5724bdf7-a83f-42c6-b336-bf5ee98be529 + settingsScope: service-instance + settingsKeyPrefix: connector.workday.acme-prod + + ResourceDescriptorCreateRequest: + type: object + description: Request to describe a resource shape independently from any connector instance or transport. A descriptor can later be attached to one or more connectors. + required: + - displayName + - resourceKind + - representationKind + properties: + displayName: + type: string + description: Human-readable resource descriptor name. + example: Employee profile CSV row + description: + type: string + description: Description of the logical resource and intended use. + example: Tabular employee profile data used for employee credential claim mapping. + resourceKind: + $ref: '#/components/schemas/ResourceKind' + representationKind: + $ref: '#/components/schemas/RepresentationKind' + shapeKind: + $ref: '#/components/schemas/ShapeKind' + contract: + $ref: '#/components/schemas/ContractRef' + fields: + type: array + description: Field-level shape, validation, semantic, and retention information. + items: + $ref: '#/components/schemas/FieldDescriptorInput' + metadata: + $ref: '#/components/schemas/StringMap' + example: + displayName: Employee profile CSV row + description: Tabular employee profile data used for employee credential claim mapping. + resourceKind: TABULAR + representationKind: CSV + shapeKind: CSV_HEADER + contract: + contractKind: CSV_PROFILE + uri: vault://imports/license-batches/employee-license-v1.csv.profile.json + version: '1.0' + fields: + - fieldPath: employee_id + displayName: Employee id + valueType: string + required: true + - fieldPath: email + displayName: Work email + valueType: string + required: true + semanticAttributeId: 3cb996ce-9d68-4959-b8c4-c97e39258fae + - fieldPath: license_type + displayName: License type + valueType: string + required: true + metadata: + domain: employee-licensing + + ResourceDescriptorUpdateRequest: + type: object + description: Partial update for a resource descriptor. Omitted fields remain unchanged. + properties: + displayName: + type: string + description: Updated resource descriptor name. + example: Employee profile CSV row + description: + type: string + description: Updated resource descriptor description. + example: Employee profile rows imported from a customer CSV upload. + resourceKind: + $ref: '#/components/schemas/ResourceKind' + representationKind: + $ref: '#/components/schemas/RepresentationKind' + shapeKind: + $ref: '#/components/schemas/ShapeKind' + contract: + $ref: '#/components/schemas/ContractRef' + metadata: + $ref: '#/components/schemas/StringMap' + example: + description: Employee profile rows imported from a customer CSV upload. + metadata: + domain: employee-licensing + steward: people-ops + + ResourceDescriptor: + description: Stored resource descriptor with field definitions and audit timestamps. + allOf: + - $ref: '#/components/schemas/ResourceDescriptorCreateRequest' + - type: object + required: + - resourceDescriptorId + - createdAt + - updatedAt + properties: + resourceDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + fields: + type: array + description: Stored field descriptors for this resource descriptor. + items: + $ref: '#/components/schemas/FieldDescriptor' + createdAt: + type: string + format: date-time + description: Creation timestamp. + example: '2026-06-18T09:00:00Z' + updatedAt: + type: string + format: date-time + description: Last update timestamp. + example: '2026-06-18T09:10:00Z' + example: + resourceDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b + displayName: Employee profile CSV row + description: Tabular employee profile data used for employee credential claim mapping. + resourceKind: TABULAR + representationKind: CSV + shapeKind: CSV_HEADER + contract: + contractKind: CSV_PROFILE + uri: vault://imports/license-batches/employee-license-v1.csv.profile.json + version: '1.0' + fields: + - fieldDescriptorId: f00b9edc-5498-483f-9b91-a42ef080b909 + fieldPath: email + displayName: Work email + valueType: string + required: true + multiValued: false + semanticAttributeId: 3cb996ce-9d68-4959-b8c4-c97e39258fae + sensitivity: personal-data + metadata: + domain: employee-licensing + createdAt: '2026-06-18T09:00:00Z' + updatedAt: '2026-06-18T09:10:00Z' + + FieldDescriptorInput: + type: object + description: Field definition for a resource descriptor. A field can carry semantic meaning, validation hints, sensitivity, and retention metadata. + required: + - fieldPath + - valueType + properties: + fieldPath: + type: string + description: Path or column name within the resource representation. + example: email + displayName: + type: string + description: Human-readable field name. + example: Work email + valueType: + type: string + description: Logical value type, for example string, number, boolean, date, datetime, object, array, or binary. + example: string + required: + type: boolean + description: Whether the field is required for validation and mapping. + default: false + example: true + multiValued: + type: boolean + description: Whether the field can hold multiple values. + default: false + example: false + semanticAttributeId: + type: string + format: uuid + description: Optional semantic attribute binding used for validation, governance, and policy. + example: 3cb996ce-9d68-4959-b8c4-c97e39258fae + sensitivity: + type: string + description: Optional sensitivity or classification label used by governance and policy checks. + example: personal-data + retention: + $ref: '#/components/schemas/RetentionSpec' + metadata: + $ref: '#/components/schemas/StringMap' + example: + fieldPath: email + displayName: Work email + valueType: string + required: true + multiValued: false + semanticAttributeId: 3cb996ce-9d68-4959-b8c4-c97e39258fae + sensitivity: personal-data + retention: + purpose: credential-issuance + legalBasis: contract + retentionPeriod: P30D + deleteAction: DELETE + + FieldDescriptor: + description: Stored field descriptor. + allOf: + - $ref: '#/components/schemas/FieldDescriptorInput' + - type: object + required: + - fieldDescriptorId + properties: + fieldDescriptorId: + $ref: '#/components/schemas/FieldDescriptorId' + example: + fieldDescriptorId: f00b9edc-5498-483f-9b91-a42ef080b909 + fieldPath: email + displayName: Work email + valueType: string + required: true + multiValued: false + semanticAttributeId: 3cb996ce-9d68-4959-b8c4-c97e39258fae + sensitivity: personal-data + + ContractRef: + type: object + description: Reference to the schema, contract, or discovery document that defines or constrains a resource. The contract is descriptive; transport is still represented by AccessProtocol. + required: + - contractKind + properties: + contractKind: + $ref: '#/components/schemas/ContractKind' + uri: + type: string + description: URI or locator for the contract document. + example: https://hr.example.com/.well-known/openapi.json + version: + type: string + description: Contract version understood by the connector. + example: '2026-06' + contentHash: + type: string + description: Optional hash of the contract content for integrity and drift detection. + example: sha256:9a0adf3e15f6c8c9b30b41f34f92de2c4f41ceea6c4e9c027c9f8f83f6a741b7 + metadata: + $ref: '#/components/schemas/StringMap' + example: + contractKind: OPENAPI + uri: https://hr.example.com/.well-known/openapi.json + version: '2026-06' + contentHash: sha256:9a0adf3e15f6c8c9b30b41f34f92de2c4f41ceea6c4e9c027c9f8f83f6a741b7 + + AttachConnectorResourceRequest: + type: object + description: Request to attach a resource descriptor to a connector instance for a specific data-flow role. + required: + - resourceDescriptorId + - role + properties: + resourceDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + role: + $ref: '#/components/schemas/DataFlowRole' + externalResourceName: + type: string + description: Connector-local table, endpoint, bucket, object, claim set, form, topic, or collection name. + accessProtocol: + $ref: '#/components/schemas/AccessProtocol' + endpointId: + type: string + format: uuid + description: Optional connector endpoint used to access this resource. + example: 27d8bfc5-6c75-4e4e-a78a-63ad7a924cb1 + metadata: + $ref: '#/components/schemas/StringMap' + example: + resourceDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b + role: SOURCE + externalResourceName: /employees/{employee_id} + accessProtocol: HTTPS + endpointId: 27d8bfc5-6c75-4e4e-a78a-63ad7a924cb1 + metadata: + operation_group: employee-profile + + ConnectorResource: + description: Resource descriptor attached to a connector instance. This creates the bridge between a durable connector and a logical resource shape. + allOf: + - $ref: '#/components/schemas/AttachConnectorResourceRequest' + - type: object + required: + - connectorResourceId + - connectorInstanceId + properties: + connectorResourceId: + $ref: '#/components/schemas/ConnectorResourceId' + connectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + example: + connectorResourceId: b4cf21b1-0292-4803-8d32-9ebf9f5359a2 + connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + resourceDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b + role: SOURCE + externalResourceName: /employees/{employee_id} + accessProtocol: HTTPS + endpointId: 27d8bfc5-6c75-4e4e-a78a-63ad7a924cb1 + + OperationBindingCreateRequest: + type: object + description: Request to bind a connector resource to a logical operation. The binding connects connector instance, attached resource, logical operation, transfer mode, protocol, operation name, optional transformation, and destination delivery policy. + required: + - connectorInstanceId + - connectorResourceId + - operationKind + properties: + connectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + connectorResourceId: + $ref: '#/components/schemas/ConnectorResourceId' + operationKind: + $ref: '#/components/schemas/OperationKind' + transferMode: + $ref: '#/components/schemas/OperationTransferMode' + direction: + $ref: '#/components/schemas/BindingDirection' + accessProtocol: + $ref: '#/components/schemas/AccessProtocol' + operationName: + type: string + description: Connector-local operation name, for example OpenAPI operationId, SQL statement name, file action, or vault operation. + example: getEmployeeProfile + requestDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + responseDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + transformationId: + $ref: '#/components/schemas/TransformationId' + delivery: + $ref: '#/components/schemas/DestinationDelivery' + egressPolicy: + $ref: '#/components/schemas/EgressPolicy' + metadata: + $ref: '#/components/schemas/StringMap' + example: + connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + connectorResourceId: b4cf21b1-0292-4803-8d32-9ebf9f5359a2 + operationKind: READ + transferMode: SINGLE + direction: INBOUND + accessProtocol: HTTPS + operationName: getEmployeeProfile + responseDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b + egressPolicy: + allowedHosts: [hr.example.com] + allowedProtocols: [HTTPS] + maxPayloadBytes: 1048576 + requiresTenantBoundary: true + metadata: + source_lookup_key: employee_id + + OperationBindingUpdateRequest: + type: object + description: Partial update for an operation binding. Use this to adjust operation metadata, transformation, delivery, or policy without changing unrelated fields. + properties: + operationKind: + $ref: '#/components/schemas/OperationKind' + transferMode: + $ref: '#/components/schemas/OperationTransferMode' + direction: + $ref: '#/components/schemas/BindingDirection' + accessProtocol: + $ref: '#/components/schemas/AccessProtocol' + operationName: + type: string + description: Updated connector-local operation name. + example: getEmployeeProfile + requestDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + responseDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + transformationId: + $ref: '#/components/schemas/TransformationId' + delivery: + $ref: '#/components/schemas/DestinationDelivery' + egressPolicy: + $ref: '#/components/schemas/EgressPolicy' + metadata: + $ref: '#/components/schemas/StringMap' + example: + transformationId: 0e60abcc-41b5-4cc5-bec2-f0047f129341 + egressPolicy: + allowedHosts: [hr.example.com] + allowedProtocols: [HTTPS] + maxPayloadBytes: 1048576 + + OperationBinding: + description: Stored operation binding. A route composes one source binding and one destination binding. + allOf: + - $ref: '#/components/schemas/OperationBindingCreateRequest' + - type: object + required: + - bindingId + - createdAt + - updatedAt + properties: + bindingId: + $ref: '#/components/schemas/OperationBindingId' + createdAt: + type: string + format: date-time + description: Creation timestamp. + example: '2026-06-18T09:20:00Z' + updatedAt: + type: string + format: date-time + description: Last update timestamp. + example: '2026-06-18T09:25:00Z' + example: + bindingId: 2777417e-82ce-4d3e-b96c-94e00a4d9a93 + connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + connectorResourceId: b4cf21b1-0292-4803-8d32-9ebf9f5359a2 + operationKind: READ + transferMode: SINGLE + direction: INBOUND + accessProtocol: HTTPS + operationName: getEmployeeProfile + responseDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b + createdAt: '2026-06-18T09:20:00Z' + updatedAt: '2026-06-18T09:25:00Z' + + SemanticConnectorBindingCreateRequest: + type: object + description: Request to bind connector resource data to a semantic model reference. Bindings may apply to a resource, a field, or a connector-specific view of a resource. + required: + - resourceDescriptorId + - bindingKind + properties: + connectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + resourceDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + fieldDescriptorId: + $ref: '#/components/schemas/FieldDescriptorId' + bindingKind: + type: string + description: Binding type, for example ATTRIBUTE, ATTRIBUTE_PROFILE, PARTY_ROLE, RELATIONSHIP_TYPE, POLICY_CLASSIFICATION, or VOCABULARY_TERM. + example: ATTRIBUTE + semanticReference: + $ref: '#/components/schemas/SemanticReference' + validationMode: + type: string + description: Whether semantic validation is advisory, enforced, or disabled for this binding. + enum: + - NONE + - WARN + - ENFORCE + example: ENFORCE + metadata: + $ref: '#/components/schemas/StringMap' + example: + connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + resourceDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b + fieldDescriptorId: f00b9edc-5498-483f-9b91-a42ef080b909 + bindingKind: ATTRIBUTE + semanticReference: + referenceType: semantic-attribute + referenceId: employee.email + iri: https://vocab.example.com/employee#email + version: '1.0' + validationMode: ENFORCE + + SemanticConnectorBinding: + description: Stored semantic binding for connector resource data. + allOf: + - $ref: '#/components/schemas/SemanticConnectorBindingCreateRequest' + - type: object + required: + - semanticBindingId + - createdAt + - updatedAt + properties: + semanticBindingId: + $ref: '#/components/schemas/SemanticBindingId' + createdAt: + type: string + format: date-time + description: Creation timestamp. + example: '2026-06-18T09:30:00Z' + updatedAt: + type: string + format: date-time + description: Last update timestamp. + example: '2026-06-18T09:30:00Z' + example: + semanticBindingId: 20392e94-3b35-4a77-afc2-5e552a0a4023 + connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + resourceDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b + fieldDescriptorId: f00b9edc-5498-483f-9b91-a42ef080b909 + bindingKind: ATTRIBUTE + semanticReference: + referenceType: semantic-attribute + referenceId: employee.email + iri: https://vocab.example.com/employee#email + version: '1.0' + validationMode: ENFORCE + createdAt: '2026-06-18T09:30:00Z' + updatedAt: '2026-06-18T09:30:00Z' + + SemanticReference: + type: object + description: Reference to a semantic catalog, profile, attribute, relationship type, policy classification, or vocabulary term. + required: + - referenceType + - referenceId + properties: + referenceType: + type: string + description: Semantic model reference type. + example: semantic-attribute + referenceId: + type: string + description: Stable semantic reference id. + example: employee.email + iri: + type: string + description: Optional IRI for RDF/JSON-LD and vocabulary alignment. + example: https://vocab.example.com/employee#email + version: + type: string + description: Optional semantic reference version. + example: '1.0' + example: + referenceType: semantic-attribute + referenceId: employee.email + iri: https://vocab.example.com/employee#email + version: '1.0' + + ConnectorInvocationBindingCreateRequest: + type: object + description: Request to persist a connector invocation binding. + required: + - binding + properties: + binding: + $ref: '#/components/schemas/ConnectorInvocationBinding' + example: + binding: + invocationBindingId: issuer-config-1:post-issuance:proof-vault + ownerSurface: OID4VCI + ownerReference: issuer-config-1 + stage: OID4VCI_POST_ISSUANCE + role: VAULT_RETENTION + target: + routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + exchangeMode: PLATFORM_INITIATED_PUSH + dataDirection: OUT_OF_VDX + initiationSide: PLATFORM + logicalContext: + tenantId: acme + organizationUnitId: nl-ops + brandId: brand-a + logicalConnectionBindingId: brand-a-proof-vault + physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + + ConnectorInvocationBinding: + type: object + description: Persisted binding from an owning product/protocol lifecycle stage to a connector target, logical context, governance envelope, and execution policy. + required: + - invocationBindingId + - ownerSurface + - ownerReference + - stage + - role + - target + - exchangeMode + - logicalContext + properties: + invocationBindingId: + $ref: '#/components/schemas/ConnectorInvocationBindingId' + ownerSurface: + $ref: '#/components/schemas/ConnectorOwnerSurface' + ownerReference: + type: string + description: Owner-specific reference such as issuer configuration id, verifier profile id, form id, portal flow id, or workflow id. + example: issuer-config-1 + stage: + $ref: '#/components/schemas/ConnectorInvocationStage' + role: + $ref: '#/components/schemas/ConnectorInvocationRole' + target: + $ref: '#/components/schemas/ConnectorInvocationTarget' + exchangeMode: + $ref: '#/components/schemas/ConnectorExchangeMode' + dataDirection: + $ref: '#/components/schemas/ConnectorDataDirection' + initiationSide: + $ref: '#/components/schemas/ConnectorInitiationSide' + subsetMapping: + $ref: '#/components/schemas/ConnectorSubsetMapping' + logicalContext: + $ref: '#/components/schemas/ConnectorLogicalContext' + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + physicalConnectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + executionPolicy: + $ref: '#/components/schemas/ConnectorInvocationExecutionPolicy' + governance: + $ref: '#/components/schemas/ConnectorGovernanceEnvelope' + partyAnchors: + $ref: '#/components/schemas/ConnectorPartyAnchorSet' + materializationPolicy: + $ref: '#/components/schemas/MaterializationPolicy' + metadata: + $ref: '#/components/schemas/StringMap' + example: + invocationBindingId: issuer-config-1:post-issuance:proof-vault + ownerSurface: OID4VCI + ownerReference: issuer-config-1 + stage: OID4VCI_POST_ISSUANCE + role: VAULT_RETENTION + target: + routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + exchangeMode: PLATFORM_INITIATED_PUSH + dataDirection: OUT_OF_VDX + initiationSide: PLATFORM + logicalContext: + tenantId: acme + organizationUnitId: nl-ops + brandId: brand-a + logicalConnectionBindingId: brand-a-proof-vault + physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + + ConnectorInvocationTarget: + type: object + description: Registry target selected by an invocation binding. + properties: + routeId: + $ref: '#/components/schemas/ConnectorRouteId' + connectorId: + $ref: '#/components/schemas/ConnectorInstanceId' + operationBindingId: + $ref: '#/components/schemas/OperationBindingId' + example: + routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + + ConnectorLogicalContext: + type: object + description: Tenant, OU, brand, legal entity, channel, product, and discriminator context used to resolve a logical connector binding. + required: + - tenantId + properties: + tenantId: + $ref: '#/components/schemas/TenantId' + organizationUnitId: + type: string + example: nl-ops + brandId: + type: string + example: brand-a + legalEntityId: + type: string + example: legal-entity-a + channel: + type: string + example: web + productId: + type: string + example: employee-license + discriminators: + $ref: '#/components/schemas/StringMap' + example: + tenantId: acme + organizationUnitId: nl-ops + brandId: brand-a + discriminators: + jurisdiction: NL + + ConnectorSubsetMapping: + type: object + description: Field selection, lookup, output mapping, provenance, and minimization rules used by an invocation or exposure. + properties: + lookupInputs: + type: array + items: + $ref: '#/components/schemas/ConnectorFieldSelector' + selectedFields: + type: array + items: + $ref: '#/components/schemas/ConnectorFieldSelector' + producedFields: + type: array + description: Fields an invocation is expected to produce for later connector or protocol stages. + items: + $ref: '#/components/schemas/ConnectorFieldSelector' + outputMappings: + type: array + items: + $ref: '#/components/schemas/ConnectorFieldMapping' + sourceProvenanceFields: + type: array + items: + $ref: '#/components/schemas/ConnectorFieldSelector' + qualityStatusFields: + type: array + items: + $ref: '#/components/schemas/ConnectorFieldSelector' + redactionProfileId: + type: string + example: redact-proof-source + minimizationProfileId: + type: string + example: min-proof-source + example: + lookupInputs: + - protocolClaimPath: credential_subject.id + selectedFields: + - canonicalFieldPath: proof.status + minimizationProfileId: min-proof-source + + ConnectorFieldSelector: + type: object + description: Selector for a canonical, protocol, form, proof, status, source, data product, or semantic field. + properties: + canonicalFieldPath: + type: string + example: proof.status + lookupKey: + type: string + example: employee_id + protocolClaimPath: + type: string + example: credential_subject.email + dcqlCredentialQueryId: + type: string + example: employeeCredential + dcqlClaimId: + type: string + example: email + formFieldPath: + type: string + example: applicant.email + proofRef: + type: string + example: proof://presentation/1 + statusRef: + type: string + example: status://credential/1 + tokenRef: + type: string + example: token://access/1 + sourceFieldPath: + type: string + example: worker.email + dataProductFieldScope: + type: string + example: dpp.asset.serial + contractAgreementTargetRef: + type: string + example: contract-target-1 + semanticReference: + $ref: '#/components/schemas/SemanticReference' + required: + type: boolean + default: true + example: true + + ConnectorFieldMapping: + type: object + description: Mapping from a source selector to a target selector. + required: + - source + - target + properties: + source: + $ref: '#/components/schemas/ConnectorFieldSelector' + target: + $ref: '#/components/schemas/ConnectorFieldSelector' + required: + type: boolean + default: true + example: true + + ConnectorInvocationExecutionPolicy: + type: object + description: Timing, retry, idempotency, and correlation policy for an invocation binding. + properties: + timing: + $ref: '#/components/schemas/ConnectorExecutionTiming' + failureEffect: + $ref: '#/components/schemas/ConnectorFailureEffect' + timeoutMillis: + type: integer + format: int64 + minimum: 0 + example: 30000 + syncWaitWindowMillis: + type: integer + format: int64 + minimum: 0 + example: 5000 + retryPolicy: + $ref: '#/components/schemas/RetryPolicy' + idempotencyKey: + type: string + example: issuer-config-1:offer-123 + correlationId: + type: string + example: protocol-correlation-1 + example: + timing: INLINE_REQUIRED + failureEffect: FAIL_PROTOCOL + timeoutMillis: 30000 + + LogicalConnectionBindingCreateRequest: + type: object + description: Request to persist a logical connection binding. + required: + - binding + properties: + binding: + $ref: '#/components/schemas/LogicalConnectionBinding' + example: + binding: + logicalConnectionBindingId: brand-a-proof-vault + physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + logicalContext: + tenantId: acme + organizationUnitId: nl-ops + brandId: brand-a + + LogicalConnectionBinding: + type: object + description: Logical usage binding for a physical connector instance, including caller context, discriminator rules, auth overlay, grants, governance defaults, and system catalog projection metadata. + required: + - logicalConnectionBindingId + - physicalConnectorInstanceId + - logicalContext + properties: + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + physicalConnectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + logicalContext: + $ref: '#/components/schemas/ConnectorLogicalContext' + callerParty: + $ref: '#/components/schemas/PartyRef' + beneficiaryParty: + $ref: '#/components/schemas/PartyRef' + discriminatorRules: + type: array + items: + $ref: '#/components/schemas/ConnectorDiscriminatorRule' + authOverlay: + $ref: '#/components/schemas/ConnectorAuthOverlay' + grants: + type: array + items: + $ref: '#/components/schemas/LogicalConnectionGrant' + allowedOperations: + type: array + items: + $ref: '#/components/schemas/OperationKind' + defaultSubsetMapping: + $ref: '#/components/schemas/ConnectorSubsetMapping' + defaultGovernance: + $ref: '#/components/schemas/ConnectorGovernanceEnvelope' + defaultMaterializationPolicy: + $ref: '#/components/schemas/MaterializationPolicy' + systemCatalog: + $ref: '#/components/schemas/SystemCatalogProjectionMetadata' + example: + logicalConnectionBindingId: brand-a-proof-vault + physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + logicalContext: + tenantId: acme + organizationUnitId: nl-ops + brandId: brand-a + authOverlay: + mode: TENANT_SECRET_REF + secretRef: vault://tenant/acme/connectors/proof-vault + allowedOperations: [READ, WRITE] + + ConnectorDiscriminatorRule: + type: object + description: Rule for deriving and placing a discriminator value when resolving or invoking a logical connector binding. + required: + - source + - sourceKey + - targetKey + - placement + properties: + source: + $ref: '#/components/schemas/ConnectorDiscriminatorSource' + sourceKey: + type: string + example: brandId + targetKey: + type: string + example: X-Brand-Id + placement: + $ref: '#/components/schemas/ConnectorDiscriminatorPlacement' + required: + type: boolean + default: true + example: true + staticValue: + type: string + example: brand-a + + ConnectorAuthOverlay: + type: object + description: Logical authentication overlay applied on top of the physical connector configuration. + properties: + mode: + $ref: '#/components/schemas/ConnectorAuthOverlayMode' + secretRef: + type: string + example: vault://tenant/acme/connectors/proof-vault + oauthClientRef: + type: string + example: oauth-client://issuer-proof-vault + mtlsIdentityRef: + type: string + example: mtls://identity/issuer-proof-vault + credentialSelector: + type: string + example: tenant-default + example: + mode: TENANT_SECRET_REF + secretRef: vault://tenant/acme/connectors/proof-vault + + LogicalConnectionGrant: + type: object + description: Grant that allows another tenant or caller context to use a logical connection binding. + required: + - grantId + - grantedToTenantId + properties: + grantId: + type: string + example: grant-proof-vault-to-supplier + grantedToTenantId: + $ref: '#/components/schemas/TenantId' + grantedBy: + $ref: '#/components/schemas/PartyRef' + allowedOperations: + type: array + items: + $ref: '#/components/schemas/OperationKind' + active: + type: boolean + default: true + example: true + + SystemCatalogProjectionMetadata: + type: object + description: Party and deployment metadata projected from a logical connection binding into system catalog or governance views. + properties: + operatorParty: + $ref: '#/components/schemas/PartyRef' + vendorSupplierParty: + $ref: '#/components/schemas/PartyRef' + deploymentRegion: + type: string + example: eu-west-1 + managementMode: + $ref: '#/components/schemas/ConnectorManagementMode' + runtimeMode: + $ref: '#/components/schemas/ConnectorRuntimeMode' + deploymentMode: + $ref: '#/components/schemas/ConnectorDeploymentMode' + dataCategoriesTouched: + type: array + items: + type: string + example: [proof-status] + downstreamRecipients: + type: array + items: + $ref: '#/components/schemas/PartyRef' + processorRefs: + type: array + items: + $ref: '#/components/schemas/PartyRef' + + RouteExposureDescriptorCreateRequest: + type: object + description: Request to persist a route exposure descriptor. + required: + - exposure + properties: + exposure: + $ref: '#/components/schemas/RouteExposureDescriptor' + example: + exposure: + exposureDescriptorId: proof-vault-read-exposure + exposedCapabilityId: proof-vault-read + owningTenantId: acme + logicalConnectionBindingId: brand-a-proof-vault + exchangeMode: EXTERNALLY_INITIATED_READ_FROM_VDX + allowedOperation: READ + acceptedAuthMethods: [bearer, mtls] + + RouteExposureDescriptor: + type: object + description: Externally callable connector route capability and its caller, schema, subset, payload, rate, and audit constraints. + required: + - exposureDescriptorId + - exposedCapabilityId + - owningTenantId + - logicalConnectionBindingId + - exchangeMode + - allowedOperation + - acceptedAuthMethods + properties: + exposureDescriptorId: + $ref: '#/components/schemas/RouteExposureDescriptorId' + exposedCapabilityId: + type: string + example: proof-vault-read + owningTenantId: + $ref: '#/components/schemas/TenantId' + organizationUnitId: + type: string + example: nl-ops + brandId: + type: string + example: brand-a + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + exchangeMode: + $ref: '#/components/schemas/ConnectorExchangeMode' + allowedOperation: + $ref: '#/components/schemas/OperationKind' + acceptedAuthMethods: + type: array + items: + type: string + example: [bearer, mtls] + callerPartyConstraints: + type: array + items: + $ref: '#/components/schemas/PartyRef' + callerRelationshipConstraints: + type: array + items: + $ref: '#/components/schemas/RelationshipRef' + requestSchemaRef: + type: string + example: schema://proof-vault/read-request + responseSchemaRef: + type: string + example: schema://proof-vault/read-response + subsetMapping: + $ref: '#/components/schemas/ConnectorSubsetMapping' + cursorStrategy: + type: string + example: opaque-page-token + idempotencyKeyStrategy: + type: string + example: header:X-Idempotency-Key + payloadLimitBytes: + type: integer + format: int64 + minimum: 0 + example: 1048576 + rateLimitKey: + type: string + example: tenant:caller + auditCategory: + $ref: '#/components/schemas/ConnectorAuditCategory' + example: + exposureDescriptorId: proof-vault-read-exposure + exposedCapabilityId: proof-vault-read + owningTenantId: acme + organizationUnitId: nl-ops + brandId: brand-a + logicalConnectionBindingId: brand-a-proof-vault + exchangeMode: EXTERNALLY_INITIATED_READ_FROM_VDX + allowedOperation: READ + acceptedAuthMethods: [bearer, mtls] + payloadLimitBytes: 1048576 + auditCategory: EXTERNAL_EXCHANGE + + RouteExposureExternalReadRequest: + type: object + description: Governed request envelope for an externally initiated read through a route exposure descriptor. + required: + - authMethod + - callerParty + - canonicalFields + - policyDecision + properties: + authMethod: + type: string + description: Auth or trust method accepted by the exposure descriptor. + example: bearer + callerParty: + $ref: '#/components/schemas/PartyRef' + canonicalFields: + type: object + description: Canonical field values eligible for projection through the governed exposure. + additionalProperties: true + example: + proof.status: valid + governance: + $ref: '#/components/schemas/ConnectorGovernanceEnvelope' + policyDecision: + $ref: '#/components/schemas/ConnectorPolicyDecision' + cursor: + $ref: '#/components/schemas/ConnectorCursor' + example: + authMethod: bearer + callerParty: + partyId: party-consumer + canonicalFields: + proof.status: valid + governance: + classification: confidential + legalBasis: dpv:Contract + purpose: dpv:Audit + auditCategory: EXTERNAL_EXCHANGE + policyDecision: + decisionId: policy-external-read + outcome: PERMIT + cursor: + value: page-1 + + RouteExposureExternalWriteRequest: + type: object + description: Governed request envelope for an externally initiated write through a route exposure descriptor. + required: + - authMethod + - callerParty + - payload + - fieldMappings + - policyDecision + properties: + authMethod: + type: string + description: Auth or trust method accepted by the exposure descriptor. + example: bearer + callerParty: + $ref: '#/components/schemas/PartyRef' + payload: + type: object + description: External payload values supplied by the caller. + additionalProperties: true + example: + supplierStatus: valid + fieldMappings: + type: array + items: + $ref: '#/components/schemas/ConnectorFieldMapping' + governance: + $ref: '#/components/schemas/ConnectorGovernanceEnvelope' + policyDecision: + $ref: '#/components/schemas/ConnectorPolicyDecision' + idempotencyKey: + type: string + example: supplier-status-1 + partyProjectionCandidates: + type: array + items: + $ref: '#/components/schemas/PartyProjectionCandidate' + example: + authMethod: bearer + callerParty: + partyId: party-supplier + payload: + supplierStatus: valid + fieldMappings: + - source: + sourceFieldPath: supplierStatus + target: + canonicalFieldPath: evidence.status + governance: + classification: confidential + legalBasis: dpv:Contract + purpose: dpv:Audit + auditCategory: EXTERNAL_EXCHANGE + policyDecision: + decisionId: policy-external-write + outcome: PERMIT + idempotencyKey: supplier-status-1 + + ConnectorExternalReadResponse: + type: object + description: Approved governed view returned by an externally initiated read exposure. + required: + - state + - exposureDescriptorId + - logicalConnectionBindingId + - policyDecisionId + - selectedFieldPaths + - manifest + properties: + state: + type: string + example: APPROVED_VIEW + runId: + $ref: '#/components/schemas/ConnectorRunId' + exposureDescriptorId: + $ref: '#/components/schemas/RouteExposureDescriptorId' + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + policyDecisionId: + type: string + example: policy-external-read + selectedFieldPaths: + type: array + items: + type: string + example: [proof.status] + manifest: + $ref: '#/components/schemas/ConnectorExportManifest' + cursor: + $ref: '#/components/schemas/ConnectorCursor' + sourceSurface: + type: string + example: route-exposure + + ConnectorExternalWriteReceipt: + type: object + description: Governed-ingress receipt returned by an externally initiated write exposure. + required: + - state + - exposureDescriptorId + - logicalConnectionBindingId + - canonicalFields + - projectionCandidateIds + - policyDecisionId + - idempotencyResult + - payloadHash + - laterUseAvailabilityScope + properties: + state: + $ref: '#/components/schemas/ConnectorGovernedIngressStatus' + runId: + $ref: '#/components/schemas/ConnectorRunId' + exposureDescriptorId: + $ref: '#/components/schemas/RouteExposureDescriptorId' + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + canonicalFields: + type: object + description: Canonical fields produced after mapping the external payload. + additionalProperties: true + example: + evidence.status: valid + projectionCandidateIds: + type: array + items: + type: string + example: [supplier-party-1] + policyDecisionId: + type: string + example: policy-external-write + idempotencyResult: + type: string + example: accepted:supplier-status-1 + payloadHash: + type: string + example: stable64:external-write + laterUseAvailabilityScope: + type: array + items: + $ref: '#/components/schemas/ConnectorOwnerSurface' + example: [FORM, OID4VCI, OID4VP, WORKFLOW] + + ConnectorPolicyDecision: + type: object + description: Policy decision supplied to governed connector ingress, egress, and external exposure execution. + required: + - decisionId + - outcome + properties: + decisionId: + type: string + example: policy-external-read + outcome: + $ref: '#/components/schemas/ConnectorPolicyOutcome' + reason: + type: string + example: Purpose, agreement, and caller constraints permit the external exchange. + metadata: + $ref: '#/components/schemas/StringMap' + + ConnectorPolicyOutcome: + type: string + description: Outcome returned by the governing policy layer for a connector exchange. + enum: + - PERMIT + - DENY + - MINIMIZE + - REDACT + - QUARANTINE + - REQUIRE_SECOND_SOURCE + - REQUIRE_HUMAN_REVIEW + - REQUIRE_WALLET_PROOF + - REQUIRE_STEP_UP + example: PERMIT + + ConnectorGovernedIngressStatus: + type: string + description: Result state for governed external write ingress. + enum: + - ACCEPTED + - MINIMIZED + - REDACTED + - QUARANTINED + - REJECTED + example: ACCEPTED + + ConnectorCursor: + type: object + description: Opaque cursor or watermark returned by connector runtimes and external exposure reads. + required: + - value + properties: + value: + type: string + example: page-1 + metadata: + $ref: '#/components/schemas/StringMap' + + ConnectorExportedField: + type: object + description: A field included in an external-read manifest, with minimization and integrity metadata. + required: + - fieldPath + - integrityHash + properties: + fieldPath: + type: string + example: proof.status + value: + type: object + additionalProperties: true + nullable: true + redacted: + type: boolean + default: false + example: false + minimized: + type: boolean + default: false + example: false + integrityHash: + type: string + example: stable64:proof-status + + ConnectorExportManifest: + type: object + description: Governed egress manifest for an external-read response. + required: + - manifestId + - destinationIdentity + - selectedFields + - mappingVersion + - policyDecisionId + - retentionProfileId + - manifestHash + properties: + manifestId: + type: string + example: manifest-external-read + destinationIdentity: + type: string + example: party-consumer + selectedFields: + type: array + items: + $ref: '#/components/schemas/ConnectorExportedField' + mappingVersion: + type: string + example: external-read:proof-vault-read + mappingProvenance: + type: string + example: route-exposure-subset + policyDecisionId: + type: string + example: policy-external-read + retentionProfileId: + type: string + example: retention-proof + agreementRef: + type: object + additionalProperties: true + participantIdentity: + type: object + additionalProperties: true + transferProcess: + type: object + additionalProperties: true + obligations: + type: array + items: + type: object + additionalProperties: true + manifestHash: + type: string + example: stable64:manifest-external-read + + PartyProjectionCandidate: + type: object + description: Candidate Party or relationship projection emitted by governed external write ingress. + required: + - candidateId + - entityKind + properties: + candidateId: + type: string + example: supplier-party-1 + entityKind: + type: string + example: supplier + party: + $ref: '#/components/schemas/PartyRef' + relationships: + type: array + items: + type: object + additionalProperties: true + materializationIntent: + $ref: '#/components/schemas/ConnectorEntityMaterializationIntent' + semanticClassifications: + type: array + items: + type: object + additionalProperties: true + canonicalFields: + type: object + additionalProperties: true + + ConnectorEntityMaterializationIntent: + type: string + description: How a governed external write or discovery record may materialize into durable Party, relationship, semantic, event, or DPP records. + enum: + - REFERENCE_ONLY + - EXISTING_PARTY + - NEW_PARTY_CANDIDATE + - RELATIONSHIP_CANDIDATE + - SEMANTIC_VALUE + - EVENT + - DPP_RECORD + example: NEW_PARTY_CANDIDATE + + ConnectorDataProductDescriptorCreateRequest: + type: object + description: Request to persist a connector data product descriptor. + required: + - descriptor + properties: + descriptor: + $ref: '#/components/schemas/ConnectorDataProductDescriptor' + example: + descriptor: + dataProductId: dp-proof-status + providerParty: + partyId: party-provider + displayName: Proof provider + physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + logicalConnectionBindingId: brand-a-proof-vault + datasetResourceIds: [41436f49-040c-4f5f-9c7f-657f43762e2b] + title: Proof status product + canonicalFieldScopes: [proof.status] + distributionTransferTypes: [HTTPS_PULL] + catalogOfferRefs: + - offerId: offer-proof-status + policy: + profileId: dpv-odrl + policyType: OFFER + policyUid: policy-proof-status + + ConnectorDataProductDescriptor: + type: object + description: Dataspace/data-use-contract-ready descriptor for a product exposed from a connector route or logical binding. It carries provider/consumer Party refs, dataset resource refs, field scopes, governance scope, transfer type, and catalog offer/policy refs without implementing DSP/DCAT wire behavior. + required: + - dataProductId + - providerParty + - physicalConnectorInstanceId + - logicalConnectionBindingId + - datasetResourceIds + - title + - distributionTransferTypes + - catalogOfferRefs + properties: + dataProductId: + $ref: '#/components/schemas/ConnectorDataProductId' + providerParty: + $ref: '#/components/schemas/PartyRef' + consumerParty: + $ref: '#/components/schemas/PartyRef' + physicalConnectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + datasetResourceIds: + type: array + minItems: 1 + items: + $ref: '#/components/schemas/ResourceDescriptorId' + title: + type: string + minLength: 1 + example: Proof status product + description: + type: string + example: Governed proof status view exposed from the proof-vault route. + version: + type: string + example: '1.0' + canonicalFieldScopes: + type: array + items: + type: string + example: [proof.status] + schemaRefs: + type: array + items: + type: string + example: [schema://proof-status] + freshness: + type: string + example: PT5M + quality: + type: string + example: verified + distributionTransferTypes: + type: array + minItems: 1 + items: + type: string + example: [HTTPS_PULL] + residency: + type: string + example: EU + classification: + type: string + example: confidential + governanceScope: + type: string + example: proof-status + catalogOfferRefs: + type: array + minItems: 1 + items: + $ref: '#/components/schemas/ConnectorCatalogOfferRef' + partyAnchors: + $ref: '#/components/schemas/ConnectorPartyAnchorSet' + example: + dataProductId: dp-proof-status + providerParty: + partyId: party-provider + displayName: Proof provider + physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + logicalConnectionBindingId: brand-a-proof-vault + datasetResourceIds: [41436f49-040c-4f5f-9c7f-657f43762e2b] + title: Proof status product + canonicalFieldScopes: [proof.status] + distributionTransferTypes: [HTTPS_PULL] + governanceScope: proof-status + catalogOfferRefs: + - offerId: offer-proof-status + policy: + profileId: dpv-odrl + policyType: OFFER + policyUid: policy-proof-status + + ConnectorCatalogOfferRef: + type: object + description: Reference to a catalog offer and the ODRL policy attached to it. + required: + - offerId + - policy + properties: + offerId: + $ref: '#/components/schemas/ConnectorCatalogOfferId' + policy: + $ref: '#/components/schemas/ConnectorOdrlPolicyRef' + projectionHint: + type: string + example: public-catalog + + ConnectorCatalogOfferId: + type: string + description: Stable catalog offer identifier associated with a connector data product. + example: offer-proof-status + + ConnectorOdrlPolicyType: + type: string + description: ODRL policy reference type. + enum: + - SET + - OFFER + - AGREEMENT + example: OFFER + + ConnectorOdrlPolicyRef: + type: object + description: ODRL policy reference associated with a data product catalog offer. + required: + - profileId + - policyType + - policyUid + properties: + profileId: + type: string + example: dpv-odrl + policyType: + $ref: '#/components/schemas/ConnectorOdrlPolicyType' + policyUid: + type: string + example: policy-proof-status + targetRefs: + type: array + items: + type: string + example: [proof.status] + assigner: + $ref: '#/components/schemas/PartyRef' + assignee: + $ref: '#/components/schemas/PartyRef' + permissionRefs: + type: array + items: + type: string + prohibitionRefs: + type: array + items: + type: string + dutyRefs: + type: array + items: + type: string + + TransformationCreateRequest: + type: object + description: Request to define a reusable transformation from one resource descriptor to another. Attribute mapper steps can coexist with expression-based transformations. + required: + - displayName + - language + properties: + displayName: + type: string + description: Human-readable transformation name. + example: Employee profile to license invitation + description: + type: string + description: Transformation purpose and scope. + example: Maps HR employee attributes into the invitation payload used by the license issuance flow. + language: + $ref: '#/components/schemas/TransformationLanguage' + sourceDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + targetDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + steps: + type: array + description: Ordered transformation steps for step-based languages. + items: + $ref: '#/components/schemas/TransformationStep' + expression: + type: string + description: Transformation expression for expression-based languages. + example: 'employee.{ "email": email, "subject": givenName & " " & familyName }' + metadata: + $ref: '#/components/schemas/StringMap' + example: + displayName: Employee profile to license invitation + description: Maps HR employee attributes into the invitation payload used by the license issuance flow. + language: ATTRIBUTE_MAPPER + sourceDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b + targetDescriptorId: 7a44f0de-e4d9-44ef-9211-372433933a88 + steps: + - stepType: MAP + sourcePath: email + targetPath: recipient.email + - stepType: MAP + sourcePath: license_type + targetPath: credential.licenseType + - stepType: CONSTANT + targetPath: invitation.channel + value: email + metadata: + mapper_version: '1' + + TransformationUpdateRequest: + type: object + description: Partial update for a transformation definition. + properties: + displayName: + type: string + description: Updated transformation name. + example: Employee profile to license invitation + description: + type: string + description: Updated transformation description. + example: Maps employee profile rows into the current license invitation payload. + language: + $ref: '#/components/schemas/TransformationLanguage' + sourceDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + targetDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + steps: + type: array + items: + $ref: '#/components/schemas/TransformationStep' + expression: + type: string + description: Updated expression for expression-based transformations. + example: $.employee + metadata: + $ref: '#/components/schemas/StringMap' + example: + description: Maps employee profile rows into the current license invitation payload. + steps: + - stepType: MAP + sourcePath: email + targetPath: recipient.email + - stepType: DEFAULT + targetPath: invitation.locale + value: en-US + + TransformationDefinition: + description: Stored transformation definition. + allOf: + - $ref: '#/components/schemas/TransformationCreateRequest' + - type: object + required: + - transformationId + - createdAt + - updatedAt + properties: + transformationId: + $ref: '#/components/schemas/TransformationId' + createdAt: + type: string + format: date-time + description: Creation timestamp. + example: '2026-06-18T09:35:00Z' + updatedAt: + type: string + format: date-time + description: Last update timestamp. + example: '2026-06-18T09:40:00Z' + example: + transformationId: 0e60abcc-41b5-4cc5-bec2-f0047f129341 + displayName: Employee profile to license invitation + description: Maps HR employee attributes into the invitation payload used by the license issuance flow. + language: ATTRIBUTE_MAPPER + sourceDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b + targetDescriptorId: 7a44f0de-e4d9-44ef-9211-372433933a88 + steps: + - stepType: MAP + sourcePath: email + targetPath: recipient.email + - stepType: MAP + sourcePath: license_type + targetPath: credential.licenseType + createdAt: '2026-06-18T09:35:00Z' + updatedAt: '2026-06-18T09:40:00Z' + + TransformationStep: + type: object + description: One step in a transformation pipeline. Step semantics are intentionally generic so existing attribute mappers and future expression engines can share the route model. + required: + - stepType + properties: + stepType: + type: string + description: Transformation step operation. + enum: + - MAP + - CONSTANT + - DEFAULT + - REQUIRE + - REDACT + - HASH + - LOOKUP + - CUSTOM + example: MAP + sourcePath: + type: string + description: Source path or field used by this step. + example: email + targetPath: + type: string + description: Target path or field written by this step. + example: recipient.email + value: + description: Literal value used by CONSTANT or DEFAULT steps. + nullable: true + example: email + expression: + type: string + description: Optional expression used by LOOKUP, CUSTOM, or expression-based steps. + example: lower($.email) + metadata: + $ref: '#/components/schemas/StringMap' + example: + stepType: MAP + sourcePath: email + targetPath: recipient.email + + ConnectorRouteCreateRequest: + type: object + description: Request to compose one or more source operation bindings, one or more destination operation bindings, optional transformation, trigger, and execution policies. + required: + - displayName + - sourceBindingIds + - destinationBindingIds + properties: + displayName: + type: string + description: Human-readable route name. + example: Employee CSV to license invitations + description: + type: string + description: Route purpose and operational boundaries. + example: Imports employee rows, maps them to invitation payloads, and writes them to the invitation service. + sourceBindingIds: + type: array + minItems: 1 + description: Source operation bindings that feed this route. More than one source supports enrichment and reference-data joins. + items: + $ref: '#/components/schemas/OperationBindingId' + destinationBindingIds: + type: array + minItems: 1 + description: Destination operation bindings written by this route. More than one destination supports fan-out. + items: + $ref: '#/components/schemas/OperationBindingId' + transformationId: + $ref: '#/components/schemas/TransformationId' + trigger: + $ref: '#/components/schemas/ConnectorTrigger' + atomicity: + $ref: '#/components/schemas/RouteAtomicity' + purpose: + type: string + description: Processing purpose captured at route design time for audit and future governance checks. + example: credential-issuance + legalBasis: + type: string + description: Legal, contractual, or policy basis for the route's data movement. + example: contract + enabled: + type: boolean + description: Whether this route is eligible for scheduled, event, webhook, or on-demand execution. + default: true + example: true + egressPolicy: + $ref: '#/components/schemas/EgressPolicy' + materializationPolicy: + description: | + Route-level materialization policy. When omitted by the caller, the platform applies the + safe default `mode: NONE`, meaning values are not retained unless a route explicitly opts in. + $ref: '#/components/schemas/MaterializationPolicy' + metadata: + $ref: '#/components/schemas/StringMap' + example: + displayName: Employee CSV to license invitations + description: Imports employee rows, maps them to invitation payloads, and writes them to the invitation service. + sourceBindingIds: + - 2777417e-82ce-4d3e-b96c-94e00a4d9a93 + destinationBindingIds: + - b1313b55-ee8c-41d1-8f4f-f4fe2c15e3be + transformationId: 0e60abcc-41b5-4cc5-bec2-f0047f129341 + trigger: + triggerType: ON_DEMAND + atomicity: PER_RECORD + purpose: credential-issuance + legalBasis: contract + enabled: true + materializationPolicy: + mode: NONE + + ConnectorRouteUpdateRequest: + type: object + description: Partial update for a connector route. Use this to adjust bindings, transformation, trigger, or policy. + properties: + displayName: + type: string + description: Updated route name. + example: Employee CSV to license invitations + description: + type: string + description: Updated route description. + example: Imports employee rows from the latest customer CSV upload. + sourceBindingIds: + type: array + minItems: 1 + description: Replacement list of source operation bindings. + items: + $ref: '#/components/schemas/OperationBindingId' + destinationBindingIds: + type: array + minItems: 1 + description: Replacement list of destination operation bindings. + items: + $ref: '#/components/schemas/OperationBindingId' + transformationId: + $ref: '#/components/schemas/TransformationId' + trigger: + $ref: '#/components/schemas/ConnectorTrigger' + atomicity: + $ref: '#/components/schemas/RouteAtomicity' + purpose: + type: string + description: Updated processing purpose. + example: credential-issuance + legalBasis: + type: string + description: Updated legal, contractual, or policy basis. + example: contract + enabled: + type: boolean + description: Whether this route is eligible for execution. + example: true + egressPolicy: + $ref: '#/components/schemas/EgressPolicy' + materializationPolicy: + $ref: '#/components/schemas/MaterializationPolicy' + metadata: + $ref: '#/components/schemas/StringMap' + example: + trigger: + triggerType: SCHEDULE + schedule: 0 2 * * * + atomicity: ALL_OR_NOTHING + + ConnectorRoute: + description: Stored connector route definition. + allOf: + - $ref: '#/components/schemas/ConnectorRouteCreateRequest' + - type: object + required: + - routeId + - materializationPolicy + - createdAt + - updatedAt + properties: + routeId: + $ref: '#/components/schemas/ConnectorRouteId' + createdAt: + type: string + format: date-time + description: Creation timestamp. + example: '2026-06-18T10:00:00Z' + updatedAt: + type: string + format: date-time + description: Last update timestamp. + example: '2026-06-18T10:05:00Z' + createdByUserId: + type: string + description: Optional user id that created the route. + example: platform-admin + updatedByUserId: + type: string + description: Optional user id that last updated the route. + example: platform-admin + deletedAt: + type: string + format: date-time + description: Soft-delete timestamp. Deleted routes are hidden from normal route lookup and listing but retained for run lineage. + example: '2026-06-19T10:05:00Z' + example: + routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + displayName: Employee CSV to license invitations + description: Imports employee rows, maps them to invitation payloads, and writes them to the invitation service. + sourceBindingIds: + - 2777417e-82ce-4d3e-b96c-94e00a4d9a93 + destinationBindingIds: + - b1313b55-ee8c-41d1-8f4f-f4fe2c15e3be + transformationId: 0e60abcc-41b5-4cc5-bec2-f0047f129341 + trigger: + triggerType: ON_DEMAND + atomicity: PER_RECORD + purpose: credential-issuance + legalBasis: contract + enabled: true + materializationPolicy: + mode: NONE + createdAt: '2026-06-18T10:00:00Z' + updatedAt: '2026-06-18T10:05:00Z' + + ConnectorTrigger: + type: object + description: Trigger policy for starting a route. Triggers are declarative; actual scheduling, event subscriptions, and pipeline wiring are runtime concerns. + required: + - triggerType + properties: + triggerType: + type: string + description: Trigger mechanism for the route. + enum: + - ON_DEMAND + - SCHEDULE + - EVENT + - WEBHOOK + - PIPELINE + example: ON_DEMAND + schedule: + type: string + description: Cron expression for scheduled triggers. + example: 0 2 * * * + eventType: + type: string + description: Event type that starts an event-triggered route. + example: connector.import.uploaded + pipelineRef: + type: string + description: Reference to a platform pipeline, workflow, or orchestration definition that starts the route. + example: pipeline://issuance/employee-license + metadata: + $ref: '#/components/schemas/StringMap' + example: + triggerType: ON_DEMAND + metadata: + initiated_by: platform-admin + + DestinationDelivery: + type: object + description: Delivery requirements for destination bindings, including acknowledgement and retry behavior. + properties: + deliveryMode: + $ref: '#/components/schemas/DestinationDeliveryMode' + ackMode: + $ref: '#/components/schemas/DestinationAckMode' + idempotencyKeyPath: + type: string + description: Path in the outgoing payload used as idempotency key. + example: recipient.email + retryPolicy: + $ref: '#/components/schemas/RetryPolicy' + example: + deliveryMode: BATCH + ackMode: COMMITTED + idempotencyKeyPath: recipient.email + retryPolicy: + maxAttempts: 5 + backoffMillis: 30000 + deadLetterEnabled: true + + RetryPolicy: + type: object + description: Retry and dead-letter behavior for connector operations. + properties: + maxAttempts: + type: integer + description: Maximum number of attempts, including the initial attempt. Zero means no retry after the initial failure. + minimum: 0 + example: 5 + backoffMillis: + type: integer + format: int64 + description: Delay between attempts in milliseconds. Runtime implementations may apply jitter. + minimum: 0 + example: 30000 + deadLetterEnabled: + type: boolean + description: Whether failed items should be written to the route dead-letter store when retries are exhausted. + default: true + example: true + example: + maxAttempts: 5 + backoffMillis: 30000 + deadLetterEnabled: true + + EgressPolicy: + type: object + description: | + Network and payload egress limits for connector operations. This is the connector policy + hook for SSRF protection, tenant boundary checks, and later semantic/compliance checks. + Runtime adapters should resolve names before connecting and pass the resolved address to + the evaluator when DNS pinning is enabled. + properties: + allowedHosts: + type: array + description: Hostnames or wildcard host patterns the connector is allowed to contact. Use `*.example.com` for one-or-more subdomains. + items: + type: string + example: [hr.example.com] + blockedHosts: + type: array + description: Hostnames or wildcard host patterns that are always denied, even when they also match an allowed host pattern. + items: + type: string + example: [metadata.example.com, localhost] + allowedCidrs: + type: array + description: IPv4 CIDR ranges the connector may contact when the target or resolved address is an IP address. + items: + type: string + example: [203.0.113.0/24] + allowedProtocols: + type: array + description: Access protocols allowed by this connector or operation. + items: + $ref: '#/components/schemas/AccessProtocol' + example: [HTTPS] + allowedPorts: + type: array + description: Network ports allowed by this connector or operation. Empty means protocol defaults are allowed unless another policy blocks the target. + items: + type: integer + minimum: 1 + maximum: 65535 + example: [443] + blockPrivateNetworks: + type: boolean + description: Whether private, loopback, link-local, local, multicast, and cloud metadata targets are denied by default. + default: true + example: true + pinResolvedAddress: + type: boolean + description: Whether runtime adapters should connect to the already-validated resolved address to reduce DNS rebinding risk. + default: true + example: true + maxPayloadBytes: + type: integer + format: int64 + description: Maximum allowed request or response payload size in bytes. + minimum: 0 + example: 1048576 + requiresTenantBoundary: + type: boolean + description: Whether route execution must enforce tenant boundary checks before egress. + default: true + example: true + metadata: + $ref: '#/components/schemas/StringMap' + example: + allowedHosts: [hr.example.com] + blockedHosts: [localhost, 169.254.169.254] + allowedCidrs: [203.0.113.0/24] + allowedProtocols: [HTTPS] + allowedPorts: [443] + blockPrivateNetworks: true + pinResolvedAddress: true + maxPayloadBytes: 1048576 + requiresTenantBoundary: true + + MaterializationPolicy: + type: object + description: Policy for retaining, caching, indexing, or mirroring data touched by connector routes. + properties: + mode: + $ref: '#/components/schemas/MaterializationMode' + ttlSeconds: + type: integer + format: int64 + description: Time to live for materialized data in seconds. + minimum: 0 + example: 2592000 + storageResourceDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + retention: + $ref: '#/components/schemas/RetentionSpec' + metadata: + $ref: '#/components/schemas/StringMap' + example: + mode: PERSIST + ttlSeconds: 2592000 + retention: + purpose: credential-issuance + legalBasis: contract + retentionPeriod: P30D + deleteAction: DELETE + + RetentionSpec: + type: object + description: Retention metadata used by governance and future compliance checks. It can be applied to fields, resources, materialized data, or dead-letter payloads. + properties: + purpose: + type: string + description: Processing purpose. + example: credential-issuance + legalBasis: + type: string + description: Legal or contractual basis for retention. + example: contract + retentionPeriod: + type: string + description: ISO-8601 duration, for example P30D or P7Y. + example: P30D + deleteAction: + $ref: '#/components/schemas/RetentionDeleteAction' + metadata: + $ref: '#/components/schemas/StringMap' + example: + purpose: credential-issuance + legalBasis: contract + retentionPeriod: P30D + deleteAction: DELETE + + DiscoverResourcesRequest: + type: object + description: Request to ask a connector to discover available resources, fields, and operations. Discovery is advisory and returns suggested descriptors that still need to be persisted explicitly. + properties: + includeFields: + type: boolean + description: Whether discovery should include field-level descriptors when available. + default: true + example: true + includeOperations: + type: boolean + description: Whether discovery should include operation hints such as OpenAPI operation ids or database read/write capabilities. + default: true + example: true + schemaDriftPolicy: + $ref: '#/components/schemas/SchemaDriftPolicy' + filters: + $ref: '#/components/schemas/StringMap' + example: + includeFields: true + includeOperations: true + schemaDriftPolicy: WARN + filters: + path_prefix: /employees + + SchemaDriftPolicy: + type: string + description: Action to apply when a live discovered contract hash differs from the persisted resource descriptor contract hash. IGNORE suppresses drift findings, WARN returns findings, and FAIL rejects discovery. + enum: + - IGNORE + - WARN + - FAIL + default: WARN + example: WARN + + SchemaDriftFinding: + type: object + description: Governance fact emitted when a discovered resource contract no longer matches the pinned resource descriptor contract hash. + required: + - resourceDescriptorId + - expectedContentHash + - discoveredContentHash + properties: + resourceDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + externalResourceName: + type: string + description: Connector-local resource name associated with the drift, when available. + example: /employees/{employee_id} + expectedContentHash: + type: string + description: Persisted/pinned contract hash from the resource descriptor. + example: sha256:pinned + discoveredContentHash: + type: string + description: Hash reported by live connector discovery. + example: sha256:runtime + expectedContractVersion: + type: string + description: Version from the persisted contract reference. + example: '2026-06' + discoveredContractVersion: + type: string + description: Version from the live discovered contract reference. + example: '2026-07' + policy: + $ref: '#/components/schemas/SchemaDriftPolicy' + detectedAt: + type: string + format: date-time + description: Timestamp when drift was detected. + example: '2026-06-18T10:10:00Z' + message: + type: string + description: Human-readable drift summary. + example: Discovered contract hash differs from the pinned resource descriptor contract hash. + metadata: + $ref: '#/components/schemas/StringMap' + example: + resourceDescriptorId: 9f70b114-35a6-4700-a8a3-7ad0c2d81202 + externalResourceName: /employees/{employee_id} + expectedContentHash: sha256:pinned + discoveredContentHash: sha256:runtime + expectedContractVersion: '2026-06' + discoveredContractVersion: '2026-07' + policy: WARN + detectedAt: '2026-06-18T10:10:00Z' + + DiscoveryResult: + type: object + description: Discovery result returned by a connector. Suggested descriptors are not persisted until the caller creates them through the resource descriptor API. + required: + - connectorInstanceId + - resources + properties: + connectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + resources: + type: array + description: Resources discovered from the connector. + items: + $ref: '#/components/schemas/DiscoveredResource' + schemaDrift: + type: array + description: Contract-hash drift findings detected while comparing live discovery with persisted resource descriptors. + items: + $ref: '#/components/schemas/SchemaDriftFinding' + metadata: + $ref: '#/components/schemas/StringMap' + example: + connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + resources: + - externalResourceName: /employees/{employee_id} + resourceKind: OBJECT + representationKind: JSON + supportedOperations: [READ, QUERY] + suggestedDescriptor: + resourceDescriptorId: 9f70b114-35a6-4700-a8a3-7ad0c2d81202 + displayName: Workday employee profile response + resourceKind: OBJECT + representationKind: JSON + shapeKind: OPENAPI_SCHEMA + contract: + contractKind: OPENAPI + uri: https://hr.example.com/.well-known/openapi.json + createdAt: '2026-06-18T10:10:00Z' + updatedAt: '2026-06-18T10:10:00Z' + schemaDrift: [] + metadata: + discovered_at: '2026-06-18T10:10:00Z' + + DiscoveredResource: + type: object + description: One resource discovered from an external system or connector runtime. + properties: + externalResourceName: + type: string + description: Connector-local resource name such as path, table, bucket key, claim set, topic, or collection. + example: /employees/{employee_id} + resourceKind: + $ref: '#/components/schemas/ResourceKind' + representationKind: + $ref: '#/components/schemas/RepresentationKind' + suggestedDescriptor: + $ref: '#/components/schemas/ResourceDescriptor' + supportedOperations: + type: array + description: Logical operations suggested by discovery. + items: + $ref: '#/components/schemas/OperationKind' + example: [READ, QUERY] + schemaDrift: + $ref: '#/components/schemas/SchemaDriftFinding' + metadata: + $ref: '#/components/schemas/StringMap' + example: + externalResourceName: /employees/{employee_id} + resourceKind: OBJECT + representationKind: JSON + supportedOperations: [READ, QUERY] + suggestedDescriptor: + resourceDescriptorId: 9f70b114-35a6-4700-a8a3-7ad0c2d81202 + displayName: Workday employee profile response + resourceKind: OBJECT + representationKind: JSON + shapeKind: OPENAPI_SCHEMA + createdAt: '2026-06-18T10:10:00Z' + updatedAt: '2026-06-18T10:10:00Z' + + HealthCheckRequest: + type: object + description: Request to run a connector health check. The check can be scoped to dependencies or an operation kind. + properties: + includeDependencies: + type: boolean + description: Whether dependency checks such as endpoint reachability, credential validity, and contract availability should be included. + default: true + example: true + operationKind: + $ref: '#/components/schemas/OperationKind' + example: + includeDependencies: true + operationKind: READ + + ConnectorHealth: + type: object + description: Connector health result for one connector instance. + required: + - connectorInstanceId + - status + - checkedAt + properties: + connectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + status: + type: string + description: Overall health status. + enum: + - HEALTHY + - DEGRADED + - UNHEALTHY + - UNKNOWN + example: DEGRADED + checkedAt: + type: string + format: date-time + description: Timestamp when the health check completed. + example: '2026-06-18T10:15:00Z' + details: + type: array + description: Dependency-level health details. + items: + $ref: '#/components/schemas/HealthDetail' + example: + connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + status: DEGRADED + checkedAt: '2026-06-18T10:15:00Z' + details: + - name: openapi-contract + status: HEALTHY + message: Contract document resolved. + - name: oauth-token + status: DEGRADED + message: Token expires within the warning window. + + HealthDetail: + type: object + description: Dependency-level or operation-level health detail. + properties: + name: + type: string + description: Dependency or check name. + example: oauth-token + status: + type: string + description: Status of the dependency or check. + example: DEGRADED + message: + type: string + description: Human-readable health message. + example: Token expires within the warning window. + metadata: + $ref: '#/components/schemas/StringMap' + example: + name: oauth-token + status: DEGRADED + message: Token expires within the warning window. + + StartConnectorRouteRunRequest: + type: object + description: Request to start a route run. The input object is connector- and route-specific; the route's source binding decides how it is interpreted. + properties: + input: + description: Optional input payload, lookup keys, or batch reference passed to the route. + nullable: true + example: + employee_id: E12345 + batch_ref: vault://imports/license-batches/batch-2026-06-18.csv + dryRun: + type: boolean + description: Whether the run should validate and transform without committing destination writes. + default: false + example: false + invocationBindingId: + $ref: '#/components/schemas/ConnectorInvocationBindingId' + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + physicalConnectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + exchangeMode: + $ref: '#/components/schemas/ConnectorExchangeMode' + governance: + $ref: '#/components/schemas/ConnectorGovernanceEnvelope' + partyAnchors: + $ref: '#/components/schemas/ConnectorPartyAnchorSet' + protocolContext: + $ref: '#/components/schemas/ConnectorProtocolEventContext' + correlationId: + type: string + description: Caller-provided correlation id for logs, run events, and downstream traceability. + example: import-2026-06-18-001 + metadata: + $ref: '#/components/schemas/StringMap' + example: + input: + batch_ref: vault://imports/license-batches/batch-2026-06-18.csv + dryRun: false + correlationId: import-2026-06-18-001 + metadata: + initiated_by: admin@example.com + + ConnectorRun: + type: object + description: Execution record for a connector route or operation. Counts are item-level where the connector runtime can report item-level progress. + required: + - runId + - status + - startedAt + properties: + runId: + $ref: '#/components/schemas/ConnectorRunId' + routeId: + $ref: '#/components/schemas/ConnectorRouteId' + bindingId: + $ref: '#/components/schemas/OperationBindingId' + connectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + invocationBindingId: + $ref: '#/components/schemas/ConnectorInvocationBindingId' + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + physicalConnectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + exchangeMode: + $ref: '#/components/schemas/ConnectorExchangeMode' + dataDirection: + $ref: '#/components/schemas/ConnectorDataDirection' + initiationSide: + $ref: '#/components/schemas/ConnectorInitiationSide' + governance: + $ref: '#/components/schemas/ConnectorGovernanceEnvelope' + partyAnchors: + $ref: '#/components/schemas/ConnectorPartyAnchorSet' + protocolContext: + $ref: '#/components/schemas/ConnectorProtocolEventContext' + connectorResourceId: + $ref: '#/components/schemas/ConnectorResourceId' + operationKind: + $ref: '#/components/schemas/OperationKind' + triggerKind: + type: string + description: Mechanism that initiated the run. + enum: + - INLINE + - ON_DEMAND + - SCHEDULED + - EVENT + - WEBHOOK + - PIPELINE + example: ON_DEMAND + status: + $ref: '#/components/schemas/ConnectorRunStatus' + startedAt: + type: string + format: date-time + description: Timestamp when execution started. + example: '2026-06-18T10:20:00Z' + finishedAt: + type: string + format: date-time + description: Timestamp when execution finished, if complete. + example: '2026-06-18T10:21:12Z' + itemCount: + type: integer + format: int64 + description: Number of input items seen by the run. + minimum: 0 + example: 250 + successCount: + type: integer + format: int64 + description: Number of items processed successfully. + minimum: 0 + example: 247 + failureCount: + type: integer + format: int64 + description: Number of items that failed after retries or validation. + minimum: 0 + example: 3 + correlationId: + type: string + description: Caller-provided or runtime-generated correlation id. + example: import-2026-06-18-001 + error: + $ref: '#/components/schemas/ApiError' + metadata: + $ref: '#/components/schemas/StringMap' + updatedAt: + type: string + format: date-time + description: Last update timestamp for this run record. + example: '2026-06-18T10:21:12Z' + createdByUserId: + type: string + description: Optional user id that initiated or created the run record. + example: admin@example.com + updatedByUserId: + type: string + description: Optional user id that last updated the run record. + example: connector-runtime + deletedAt: + type: string + format: date-time + description: Soft-delete timestamp, if the run record is hidden from normal queries. + example: '2026-07-18T10:21:12Z' + example: + runId: 9a785884-63ea-4b07-9976-264a1fc595f1 + routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + connectorResourceId: 8d228f50-a86c-4d5f-9eb4-83fdad7d75fa + operationKind: READ + triggerKind: ON_DEMAND + status: PARTIALLY_FAILED + startedAt: '2026-06-18T10:20:00Z' + finishedAt: '2026-06-18T10:21:12Z' + itemCount: 250 + successCount: 247 + failureCount: 3 + correlationId: import-2026-06-18-001 + metadata: + batch_ref: vault://imports/license-batches/batch-2026-06-18.csv + + ConnectorRunEvent: + type: object + description: Timestamped event emitted during route or operation execution. + required: + - eventId + - runId + - level + - message + - occurredAt + properties: + eventId: + type: string + format: uuid + description: Stable run event identifier. + example: 524d8a98-c4a4-4982-b414-e29679b41eaf + runId: + $ref: '#/components/schemas/ConnectorRunId' + routeId: + $ref: '#/components/schemas/ConnectorRouteId' + connectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + bindingId: + $ref: '#/components/schemas/OperationBindingId' + connectorResourceId: + $ref: '#/components/schemas/ConnectorResourceId' + operationKind: + $ref: '#/components/schemas/OperationKind' + level: + type: string + description: Event severity. + enum: + - DEBUG + - INFO + - WARN + - ERROR + example: WARN + message: + type: string + description: Human-readable event message. + example: Three rows failed validation and were written to dead letters. + occurredAt: + type: string + format: date-time + description: Event timestamp. + example: '2026-06-18T10:21:10Z' + metadata: + $ref: '#/components/schemas/StringMap' + example: + eventId: 524d8a98-c4a4-4982-b414-e29679b41eaf + runId: 9a785884-63ea-4b07-9976-264a1fc595f1 + routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + bindingId: 2777417e-82ce-4d3e-b96c-94e00a4d9a93 + connectorResourceId: 8d228f50-a86c-4d5f-9eb4-83fdad7d75fa + operationKind: READ + level: WARN + message: Three rows failed validation and were written to dead letters. + occurredAt: '2026-06-18T10:21:10Z' + metadata: + failed_rows: '3' + + ConnectorDeadLetter: + type: object + description: Failed item captured after validation, transformation, or destination delivery failure. Payloads are referenced, not necessarily embedded, so retention policy can control storage. + required: + - deadLetterId + - runId + - reason + - createdAt + properties: + deadLetterId: + type: string + format: uuid + description: Stable dead-letter identifier. + example: a7d38149-19d4-4d0e-8af7-f7f8891f73bb + runId: + $ref: '#/components/schemas/ConnectorRunId' + routeId: + $ref: '#/components/schemas/ConnectorRouteId' + connectorInstanceId: + $ref: '#/components/schemas/ConnectorInstanceId' + bindingId: + $ref: '#/components/schemas/OperationBindingId' + connectorResourceId: + $ref: '#/components/schemas/ConnectorResourceId' + operationKind: + $ref: '#/components/schemas/OperationKind' + reason: + type: string + description: Failure reason captured by the connector runtime. + example: Missing required field recipient.email. + payloadRef: + type: string + description: Reference to a retained failed payload, if storage policy allows it. + example: vault://connector-runs/9a785884-63ea-4b07-9976-264a1fc595f1/deadletters/row-42.json + createdAt: + type: string + format: date-time + description: Dead-letter creation timestamp. + example: '2026-06-18T10:21:11Z' + metadata: + $ref: '#/components/schemas/StringMap' + createdByUserId: + type: string + description: Optional user id associated with the failed item capture. + example: connector-runtime + deletedAt: + type: string + format: date-time + description: Soft-delete timestamp, if the dead letter is hidden after retention handling. + example: '2026-07-18T10:21:11Z' + example: + deadLetterId: a7d38149-19d4-4d0e-8af7-f7f8891f73bb + runId: 9a785884-63ea-4b07-9976-264a1fc595f1 + routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + bindingId: 2777417e-82ce-4d3e-b96c-94e00a4d9a93 + connectorResourceId: 8d228f50-a86c-4d5f-9eb4-83fdad7d75fa + operationKind: READ + reason: Missing required field recipient.email. + payloadRef: vault://connector-runs/9a785884-63ea-4b07-9976-264a1fc595f1/deadletters/row-42.json + createdAt: '2026-06-18T10:21:11Z' + metadata: + row_number: '42' + + ConnectorInstancePage: + type: object + description: Page of connector instances. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorInstance' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + partyId: f9c97b4e-e756-4b70-b230-6f1d9f81b426 + displayName: Workday employee profile API + connectorType: http.openapi + lifecycleStatus: ACTIVE + supportedRoles: [SOURCE] + createdAt: '2026-06-18T08:30:00Z' + updatedAt: '2026-06-18T08:45:00Z' + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + description: Page of connector identities. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorIdentity' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - identityId: 3a5cf979-2d89-4057-a721-c7ab884f0c68 + identityRole: external-system + displayName: Workday tenant acme-prod + isDefault: true + identifiers: [] + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + ConnectorResourcePage: + type: object + description: Page of resources attached to connectors. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorResource' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - connectorResourceId: b4cf21b1-0292-4803-8d32-9ebf9f5359a2 + connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + resourceDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b + role: SOURCE + externalResourceName: /employees/{employee_id} + accessProtocol: HTTPS + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + ResourceDescriptorPage: + type: object + description: Page of resource descriptors. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ResourceDescriptor' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - resourceDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b + displayName: Employee profile CSV row + resourceKind: TABULAR + representationKind: CSV + createdAt: '2026-06-18T09:00:00Z' + updatedAt: '2026-06-18T09:10:00Z' + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + FieldDescriptorPage: + type: object + description: Page of field descriptors. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/FieldDescriptor' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - fieldDescriptorId: f00b9edc-5498-483f-9b91-a42ef080b909 + fieldPath: email + displayName: Work email + valueType: string + required: true + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + OperationBindingPage: + type: object + description: Page of operation bindings. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/OperationBinding' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - bindingId: 2777417e-82ce-4d3e-b96c-94e00a4d9a93 + connectorInstanceId: 3f6f4f46-24fb-4c35-a7a4-bc6c7f7861f5 + connectorResourceId: b4cf21b1-0292-4803-8d32-9ebf9f5359a2 + operationKind: READ + direction: INBOUND + accessProtocol: HTTPS + operationName: getEmployeeProfile + createdAt: '2026-06-18T09:20:00Z' + updatedAt: '2026-06-18T09:25:00Z' + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + SemanticConnectorBindingPage: + type: object + description: Page of semantic connector bindings. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/SemanticConnectorBinding' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - semanticBindingId: 20392e94-3b35-4a77-afc2-5e552a0a4023 + resourceDescriptorId: 41436f49-040c-4f5f-9c7f-657f43762e2b + fieldDescriptorId: f00b9edc-5498-483f-9b91-a42ef080b909 + bindingKind: ATTRIBUTE + validationMode: ENFORCE + createdAt: '2026-06-18T09:30:00Z' + updatedAt: '2026-06-18T09:30:00Z' + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + ConnectorInvocationBindingPage: + type: object + description: Page of connector invocation bindings. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorInvocationBinding' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - invocationBindingId: issuer-config-1:post-issuance:proof-vault + ownerSurface: OID4VCI + ownerReference: issuer-config-1 + stage: OID4VCI_POST_ISSUANCE + role: VAULT_RETENTION + target: + routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + exchangeMode: PLATFORM_INITIATED_PUSH + logicalContext: + tenantId: acme + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + LogicalConnectionBindingPage: + type: object + description: Page of logical connection bindings. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/LogicalConnectionBinding' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - logicalConnectionBindingId: brand-a-proof-vault + physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + logicalContext: + tenantId: acme + organizationUnitId: nl-ops + brandId: brand-a + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + RouteExposureDescriptorPage: + type: object + description: Page of route exposure descriptors. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/RouteExposureDescriptor' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - exposureDescriptorId: proof-vault-read-exposure + exposedCapabilityId: proof-vault-read + owningTenantId: acme + logicalConnectionBindingId: brand-a-proof-vault + exchangeMode: EXTERNALLY_INITIATED_READ_FROM_VDX + allowedOperation: READ + acceptedAuthMethods: [bearer, mtls] + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + ConnectorDataProductDescriptorPage: + type: object + description: Page of connector data product descriptors. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorDataProductDescriptor' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - dataProductId: dp-proof-status + providerParty: + partyId: party-provider + physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + logicalConnectionBindingId: brand-a-proof-vault + datasetResourceIds: [41436f49-040c-4f5f-9c7f-657f43762e2b] + title: Proof status product + distributionTransferTypes: [HTTPS_PULL] + catalogOfferRefs: + - offerId: offer-proof-status + policy: + profileId: dpv-odrl + policyType: OFFER + policyUid: policy-proof-status + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + TransformationPage: + type: object + description: Page of transformation definitions. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/TransformationDefinition' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - transformationId: 0e60abcc-41b5-4cc5-bec2-f0047f129341 + displayName: Employee profile to license invitation + language: ATTRIBUTE_MAPPER + createdAt: '2026-06-18T09:35:00Z' + updatedAt: '2026-06-18T09:40:00Z' + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + ConnectorRoutePage: + type: object + description: Page of connector routes. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorRoute' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + displayName: Employee CSV to license invitations + sourceBindingIds: + - 2777417e-82ce-4d3e-b96c-94e00a4d9a93 + destinationBindingIds: + - b1313b55-ee8c-41d1-8f4f-f4fe2c15e3be + atomicity: PER_RECORD + createdAt: '2026-06-18T10:00:00Z' + updatedAt: '2026-06-18T10:05:00Z' + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + ConnectorRunPage: + type: object + description: Page of connector runs. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorRun' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - runId: 9a785884-63ea-4b07-9976-264a1fc595f1 + routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + status: PARTIALLY_FAILED + startedAt: '2026-06-18T10:20:00Z' + finishedAt: '2026-06-18T10:21:12Z' + itemCount: 250 + successCount: 247 + failureCount: 3 + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + ConnectorRunEventPage: + type: object + description: Page of connector run events. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorRunEvent' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - eventId: 524d8a98-c4a4-4982-b414-e29679b41eaf + runId: 9a785884-63ea-4b07-9976-264a1fc595f1 + level: WARN + message: Three rows failed validation and were written to dead letters. + occurredAt: '2026-06-18T10:21:10Z' + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + ConnectorDeadLetterPage: + type: object + description: Page of connector dead letters. + required: [data, pagination] + properties: + data: + type: array + items: + $ref: '#/components/schemas/ConnectorDeadLetter' + pagination: + $ref: '#/components/schemas/Page' + example: + data: + - deadLetterId: a7d38149-19d4-4d0e-8af7-f7f8891f73bb + runId: 9a785884-63ea-4b07-9976-264a1fc595f1 + routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f + reason: Missing required field recipient.email. + createdAt: '2026-06-18T10:21:11Z' + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + + Page: + type: object + description: Pagination metadata emitted with each paged response under the `pagination` property. + required: + - limit + - offset + - page + - size + - total + - totalPages + - hasMore + properties: + limit: + type: integer + description: Maximum number of records requested for this page. + minimum: 0 + example: 20 + offset: + type: integer + description: Zero-based offset of the first record in this page. + minimum: 0 + example: 0 + page: + type: integer + description: Zero-based page index derived from offset and limit. + minimum: 0 + example: 0 + size: + type: integer + description: Effective page size. + minimum: 0 + example: 20 + total: + type: integer + format: int64 + description: Total number of matching records. + minimum: 0 + example: 1 + totalPages: + type: integer + description: Total number of available pages. + minimum: 0 + example: 1 + hasMore: + type: boolean + description: Whether another page is available after this page. + example: false + example: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + + ConnectorIntegrityReference: + type: object + description: Integrity and evidence references carried with governed connector ingress, egress, and run lineage. + properties: + originalPayloadHash: + type: string + example: stable64:0000000000000001 + canonicalPayloadHash: + type: string + example: stable64:0000000000000002 + transformationHash: + type: string + example: stable64:0000000000000003 + evidenceRef: + type: string + example: vault://evidence/connector-run-1 + vaultRef: + type: string + example: vault://proofs/proof-1 + signatureRef: + type: string + example: jades://signature-1 + sealRef: + type: string + example: seal://qualified-seal-1 + timestampRef: + type: string + example: timestamp://tsa-1 + sourceAuthenticityVerdict: + type: string + example: VERIFIED + outputManifestHash: + type: string + example: stable64:0000000000000004 + + ConnectorGovernanceEnvelope: + type: object + description: Governance metadata attached to connector records, invocations, and runs before data crosses a protocol, form, vault, dataspace, or external-exchange boundary. + properties: + classification: + type: string + example: confidential + sensitivity: + type: string + example: high + specialCategory: + type: boolean + default: false + legalBasis: + type: string + example: dpv:Contract + purpose: + type: string + example: dpv:Audit + b2bUsagePurpose: + type: string + description: B2B or dataspace usage purpose, separate from privacy legal basis and processing purpose. + example: predictive-maintenance + frameworkAgreementRef: + type: string + example: catena-x:framework:1 + contractReference: + type: string + example: agreement-2026-001 + minimizationStatus: + type: string + enum: + - NOT_EVALUATED + - MINIMIZED + - REDACTED + - FULL_DATASET + - EXCESSIVE + example: MINIMIZED + retentionProfileId: + type: string + example: retention-proof + retention: + $ref: '#/components/schemas/RetentionSpec' + crossBorderRestriction: + type: string + enum: + - NONE + - SAME_COUNTRY + - EEA_ONLY + - APPROVED_COUNTRIES + - CONTRACT_REQUIRED + - BLOCKED + example: EEA_ONLY + encryptionRequirement: + type: string + enum: + - NONE + - IN_TRANSIT + - AT_REST + - AT_REST_AND_IN_TRANSIT + - CUSTOMER_MANAGED_KEY + example: AT_REST_AND_IN_TRANSIT + dpiaRequired: + type: boolean + default: false + integrity: + $ref: '#/components/schemas/ConnectorIntegrityReference' + policyDecisionId: + type: string + example: policy-connector-run + relianceVerdict: + type: string + enum: + - NOT_EVALUATED + - RELIABLE + - CONDITIONAL + - NOT_RELIABLE + example: RELIABLE + auditCategory: + type: string + enum: + - PROTOCOL_ISSUANCE + - PROTOCOL_VERIFICATION + - FORM + - PORTAL + - WORKFLOW + - DATASPACE + - INDUSTRIAL + - EXTERNAL_EXCHANGE + - VAULT + - SYSTEM_CATALOG + example: PROTOCOL_ISSUANCE + + PartyRef: + type: object + description: Neutral Party reference carried by EDK connector envelopes without importing the VDX Party repository. + properties: + partyId: + type: string + example: party-subject + externalId: + type: string + example: urn:external:asset:press-1 + partyType: + type: string + example: organization + displayName: + type: string + example: Example BV + metadata: + $ref: '#/components/schemas/StringMap' + + RelationshipRef: + type: object + description: Neutral Party relationship reference used by connector exposure caller constraints without importing the VDX Party repository. + required: + - relationshipType + - fromParty + - toParty + properties: + relationshipId: + type: string + example: rel-supplier-acme + relationshipType: + type: string + example: supplierOf + fromParty: + $ref: '#/components/schemas/PartyRef' + toParty: + $ref: '#/components/schemas/PartyRef' + + ConnectorPartyAnchor: + type: object + description: Role-specific Party anchor used for governed durable connector entities. + properties: + role: + type: string + example: SUBJECT + party: + $ref: '#/components/schemas/PartyRef' + relationships: + type: array + items: + type: object + additionalProperties: true + + ConnectorPartyAnchorSet: + type: object + description: Party, relationship, and projection candidates attached to connector invocation/run lineage. + properties: + anchors: + type: array + items: + $ref: '#/components/schemas/ConnectorPartyAnchor' + relationshipCandidates: + type: array + items: + type: object + additionalProperties: true + projectionCandidates: + type: array + items: + type: object + additionalProperties: true + + ConnectorProtocolEventContext: + type: object + description: Canonical protocol, form, portal, or workflow event context mapped into connector run lineage. + properties: + tenantId: + type: string + example: acme + organizationUnitId: + type: string + example: nl-ops + brandId: + type: string + example: brand-a + legalEntityId: + type: string + example: legal-entity-a + actor: + $ref: '#/components/schemas/PartyRef' + protocolSurface: + type: string + enum: + - OID4VCI + - OID4VP + - FORM + - PORTAL + - WORKFLOW + - APPLICATION + example: OID4VCI + ownerReference: + type: string + example: issuer-config-1 + stage: + type: string + example: OID4VCI_POST_ISSUANCE + sessionId: + type: string + example: protocol-session-1 + transactionId: + type: string + example: protocol-transaction-1 + correlationId: + type: string + example: protocol-correlation-1 + + ConnectorInvocationRequest: + type: object + description: Runtime request passed from a protocol, form, portal, or workflow stage into a connector invocation binding. + required: + - binding + properties: + binding: + $ref: '#/components/schemas/ConnectorInvocationBinding' + fields: + type: object + description: Canonical and protocol field values available to the connector invocation. + additionalProperties: true + protocolContext: + $ref: '#/components/schemas/ConnectorProtocolEventContext' + record: + $ref: '#/components/schemas/ConnectorRecord' + + ConnectorRunCorrelation: + type: object + description: Route-run lineage produced by connector invocation execution. + properties: + runId: + $ref: '#/components/schemas/ConnectorRunId' + externalRunRef: + type: string + example: run-issuer-config-1-proof-vault + routeId: + $ref: '#/components/schemas/ConnectorRouteId' + + ConnectorVaultRetentionProfile: + type: string + description: Vault retention profile requested by a connector invocation result. + enum: + - ISSUANCE_PROOF + - CANONICAL_SUBJECT_DATA + - RECEIVED_CUSTOMER_DATA + example: ISSUANCE_PROOF + + ConnectorVaultWrite: + type: object + description: Idempotent vault write requested by a connector invocation after protocol completion. + required: + - vaultProfile + - idempotentUpsertKey + - governance + properties: + vaultProfile: + $ref: '#/components/schemas/ConnectorVaultRetentionProfile' + idempotentUpsertKey: + type: string + example: proof:offer-123:E-100 + subjectCorrelationHandle: + type: string + example: subject:E-100 + revocationReissueLookupKey: + type: string + example: reissue:E-100 + selectedFields: + type: object + additionalProperties: true + proofRef: + type: string + example: proof-ref + statusHandle: + type: string + example: status-ref + auditLineage: + $ref: '#/components/schemas/ConnectorRunCorrelation' + governance: + $ref: '#/components/schemas/ConnectorGovernanceEnvelope' + + ConnectorInvocationResult: + type: object + description: Runtime result emitted by a connector invocation, including produced fields, written records, route lineage, and vault writes. + properties: + producedFields: + type: object + additionalProperties: true + records: + type: array + items: + $ref: '#/components/schemas/ConnectorRecord' + writeResult: + $ref: '#/components/schemas/ConnectorWriteResult' + runCorrelation: + $ref: '#/components/schemas/ConnectorRunCorrelation' + vaultWrites: + type: array + items: + $ref: '#/components/schemas/ConnectorVaultWrite' + + Oid4vciConnectorPipelineRequest: + type: object + description: EDK-neutral OID4VCI connector pipeline request used to run connector-native enrichment, export, or vault-retention bindings. + required: + - protocolContext + - initialFields + - bindings + - stages + properties: + protocolContext: + $ref: '#/components/schemas/ConnectorProtocolEventContext' + initialFields: + type: object + additionalProperties: true + bindings: + type: array + items: + $ref: '#/components/schemas/ConnectorInvocationBinding' + stages: + type: array + items: + $ref: '#/components/schemas/ConnectorInvocationStage' + + Oid4vciConnectorPipelineResult: + type: object + description: Result of an OID4VCI connector pipeline run, including accumulated fields and post-issuance vault writes. + required: + - fields + - invocationResults + properties: + fields: + type: object + additionalProperties: true + invocationResults: + type: array + items: + $ref: '#/components/schemas/ConnectorInvocationResult' + vaultWrites: + type: array + items: + $ref: '#/components/schemas/ConnectorVaultWrite' + + StringMap: + type: object + description: Small string-only metadata map for labels, ownership, routing hints, and implementation-specific annotations. Use first-class fields for contractually significant data. + additionalProperties: + type: string + example: + owner_team: people-ops + domain: employee-licensing diff --git a/connector-openapi.yml b/connector-openapi.yml index 5095ab6..1396845 100644 --- a/connector-openapi.yml +++ b/connector-openapi.yml @@ -2,12 +2,18 @@ openapi: 3.0.4 info: title: Connector Registry API version: 0.1.0 + x-contract-version: v1 + x-contract-stability: stable x-products: [vdx] description: | Register and operate connector instances that can act as sources, destinations, or both. The API is mounted as a singular product API at `/api/connector/v1`; resources inside the API use plural REST paths. + The connector REST contract is v1-stable. Compatible additions may appear, but existing + response fields, path names, operation ids, and request shapes are governed as public + integration and SDK-facing contract surface. + The model deliberately separates transport from data: - `AccessProtocol` describes how a connector reaches a system, such as HTTPS, JDBC, S3, @@ -49,7 +55,7 @@ tags: - name: Connectors description: Register connector instances as durable Party-backed integration endpoints. - name: ConnectorIdentities - description: Assign Party identities and nested identifiers to connector instances. + description: Read Party identities and nested identifiers assigned through connector create/update or Party APIs. - name: ConnectorResources description: Attach described resources to connector instances. - name: ResourceDescriptors @@ -58,6 +64,14 @@ tags: description: Bind connector operations to resources, protocols, transformations, and delivery policies. - name: SemanticBindings description: Bind resource fields and connector resources to semantic model references. + - name: ConnectorInvocationBindings + description: Bind product and protocol invocation stages to persisted connector routes, operations, logical context, and governance defaults. + - name: LogicalConnectionBindings + description: Scope physical connector instances to tenant, organization, brand, channel, and caller-specific logical usage contexts. + - name: RouteExposures + description: Describe externally callable route capabilities and their authorization, schema, subset, rate, and audit constraints. + - name: ConnectorDataProducts + description: Describe connector-exposed data products, catalog offers, transfer types, and governance scope without implementing DSP/DCAT wire behavior. - name: Transformations description: Define reusable transformations between resource descriptors. - name: Routes @@ -97,8 +111,9 @@ paths: operationId: createConnectorInstance summary: Create a connector instance description: | - Creates the connector instance and its backing Party. Optional identities and identifiers are - assigned through the Party model; identifiers must be supplied inside an identity. + Creates the connector instance and its backing Party. The request must include the + connector identity data needed to bind or create the Party identity up front. Identifiers + must be supplied inside an identity. tags: [Connectors] requestBody: required: true @@ -210,55 +225,6 @@ paths: $ref: './common-components.yml#/components/responses/Unauthorized' '404': $ref: './common-components.yml#/components/responses/NotFound' - post: - operationId: attachConnectorIdentity - summary: Attach an identity to a connector - description: | - Attaches an existing or new Identity to the connector Party. Use this for external system - identities, technical accounts, issuer identities, relying-party identities, OIDC issuers, - DID identities, client ids, DNS names, and other identifiers that belong under Identity. - tags: [ConnectorIdentities] - parameters: - - $ref: './connector-components.yml#/components/parameters/ConnectorInstanceId' - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/AttachConnectorIdentityRequest' - responses: - '201': - description: Identity attached to the connector Party. - content: - application/json: - schema: - $ref: '#/components/schemas/ConnectorIdentity' - '400': - $ref: './common-components.yml#/components/responses/ValidationError' - '401': - $ref: './common-components.yml#/components/responses/Unauthorized' - '404': - $ref: './common-components.yml#/components/responses/NotFound' - - /connectors/{connectorInstanceId}/identities/{identityId}: - delete: - operationId: removeConnectorIdentity - summary: Remove an identity from a connector - description: | - Removes the assignment between the connector Party and the Identity. This does not delete - the Identity or its nested Identifiers; retention, audit, and reuse remain governed by the - Party and Identity stores. - tags: [ConnectorIdentities] - parameters: - - $ref: './connector-components.yml#/components/parameters/ConnectorInstanceId' - - $ref: './connector-components.yml#/components/parameters/IdentityId' - responses: - '204': - description: Identity assignment removed. - '401': - $ref: './common-components.yml#/components/responses/Unauthorized' - '404': - $ref: './common-components.yml#/components/responses/NotFound' /connectors/{connectorInstanceId}/resources: get: @@ -316,7 +282,7 @@ paths: '404': $ref: './common-components.yml#/components/responses/NotFound' - /connectors/{connectorInstanceId}/discovery-runs: + /connectors/{connectorInstanceId}/discoveryruns: post: operationId: createConnectorDiscoveryRun summary: Discover connector resources @@ -347,7 +313,7 @@ paths: '404': $ref: './common-components.yml#/components/responses/NotFound' - /connectors/{connectorInstanceId}/health-checks: + /connectors/{connectorInstanceId}/healthchecks: post: operationId: createConnectorHealthCheck summary: Check connector health @@ -376,7 +342,7 @@ paths: '404': $ref: './common-components.yml#/components/responses/NotFound' - /resource-descriptors: + /resource/descriptors: get: operationId: listResourceDescriptors summary: List resource descriptors @@ -426,7 +392,7 @@ paths: '401': $ref: './common-components.yml#/components/responses/Unauthorized' - /resource-descriptors/{resourceDescriptorId}: + /resource/descriptors/{resourceDescriptorId}: get: operationId: getResourceDescriptor summary: Get a resource descriptor @@ -477,7 +443,7 @@ paths: '404': $ref: './common-components.yml#/components/responses/NotFound' - /resource-descriptors/{resourceDescriptorId}/fields: + /resource/descriptors/{resourceDescriptorId}/fields: get: operationId: listFieldDescriptors summary: List resource descriptor fields @@ -531,7 +497,7 @@ paths: '404': $ref: './common-components.yml#/components/responses/NotFound' - /operation-bindings: + /operation/bindings: get: operationId: listOperationBindings summary: List operation bindings @@ -583,7 +549,7 @@ paths: '401': $ref: './common-components.yml#/components/responses/Unauthorized' - /operation-bindings/{bindingId}: + /operation/bindings/{bindingId}: get: operationId: getOperationBinding summary: Get an operation binding @@ -650,7 +616,7 @@ paths: '404': $ref: './common-components.yml#/components/responses/NotFound' - /semantic-bindings: + /semantic/bindings: get: operationId: listSemanticConnectorBindings summary: List semantic connector bindings @@ -701,6 +667,443 @@ paths: '401': $ref: './common-components.yml#/components/responses/Unauthorized' + /invocation/bindings: + get: + operationId: listConnectorInvocationBindings + summary: List connector invocation bindings + description: | + Lists persisted invocation bindings that connect product or protocol lifecycle stages to + connector routes, operations, logical connection bindings, subset mappings, governance, and + execution policies. These records are the registry surface used when an issuer, verifier, + form, portal, or workflow needs a durable connector action at a named stage. + tags: [ConnectorInvocationBindings] + parameters: + - name: ownerSurface + in: query + required: false + description: Filter by the product or protocol surface that owns the invocation. + schema: + $ref: './connector-components.yml#/components/schemas/ConnectorOwnerSurface' + example: OID4VCI + - name: ownerReference + in: query + required: false + description: Filter by owner-specific reference, such as issuer configuration id, verifier profile id, form id, or workflow id. + schema: + type: string + example: issuer-config-1 + - name: stage + in: query + required: false + description: Filter by product or protocol lifecycle stage. + schema: + $ref: './connector-components.yml#/components/schemas/ConnectorInvocationStage' + example: OID4VCI_POST_ISSUANCE + - name: role + in: query + required: false + description: Filter by the connector's invocation role at the lifecycle stage. + schema: + $ref: './connector-components.yml#/components/schemas/ConnectorInvocationRole' + example: VAULT_RETENTION + - name: logicalConnectionBindingId + in: query + required: false + description: Filter by logical connection binding used by the invocation. + schema: + $ref: './connector-components.yml#/components/schemas/LogicalConnectionBindingId' + example: brand-a-proof-vault + - $ref: './common-components.yml#/components/parameters/Page' + - $ref: './common-components.yml#/components/parameters/Size' + responses: + '200': + description: Paged connector invocation bindings. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorInvocationBindingPage' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + post: + operationId: createConnectorInvocationBinding + summary: Create a connector invocation binding + description: | + Creates or replaces a durable invocation binding for a product or protocol lifecycle stage. + The stored binding carries the physical or logical connector target, subset mapping, + governance metadata, Party anchors, materialization policy, and execution policy that the + runtime will attach to resulting connector runs. + tags: [ConnectorInvocationBindings] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorInvocationBindingCreateRequest' + responses: + '201': + description: Connector invocation binding created. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorInvocationBinding' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + + /invocation/bindings/{invocationBindingId}: + get: + operationId: getConnectorInvocationBinding + summary: Get a connector invocation binding + description: Reads one persisted invocation binding by id. + tags: [ConnectorInvocationBindings] + parameters: + - $ref: './connector-components.yml#/components/parameters/InvocationBindingId' + responses: + '200': + description: Connector invocation binding. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorInvocationBinding' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + + /logical/bindings: + get: + operationId: listLogicalConnectionBindings + summary: List logical connection bindings + description: | + Lists logical usage bindings for physical connector instances. Logical bindings let one + connector instance be safely reused across tenants, organization units, brands, legal + entities, channels, and caller contexts while keeping discriminator, auth overlay, + governance, and catalog projection metadata explicit. + tags: [LogicalConnectionBindings] + parameters: + - name: physicalConnectorInstanceId + in: query + required: false + description: Filter by the physical connector instance backing the logical binding. + schema: + $ref: './connector-components.yml#/components/schemas/ConnectorInstanceId' + example: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + - name: organizationUnitId + in: query + required: false + description: Filter by organization unit in the logical context. + schema: + type: string + example: nl-ops + - name: brandId + in: query + required: false + description: Filter by brand in the logical context. + schema: + type: string + example: brand-a + - $ref: './common-components.yml#/components/parameters/Page' + - $ref: './common-components.yml#/components/parameters/Size' + responses: + '200': + description: Paged logical connection bindings. + content: + application/json: + schema: + $ref: '#/components/schemas/LogicalConnectionBindingPage' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + post: + operationId: createLogicalConnectionBinding + summary: Create a logical connection binding + description: | + Creates or replaces a logical connection binding for a physical connector instance. Use this + resource to declare tenant, OU, brand, channel, caller, auth overlay, grant, governance, and + system-catalog projection metadata without duplicating the physical connector registration. + tags: [LogicalConnectionBindings] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/LogicalConnectionBindingCreateRequest' + responses: + '201': + description: Logical connection binding created. + content: + application/json: + schema: + $ref: '#/components/schemas/LogicalConnectionBinding' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + + /logical/bindings/{logicalConnectionBindingId}: + get: + operationId: getLogicalConnectionBinding + summary: Get a logical connection binding + description: Reads one logical connection binding by id. + tags: [LogicalConnectionBindings] + parameters: + - $ref: './connector-components.yml#/components/parameters/LogicalConnectionBindingId' + responses: + '200': + description: Logical connection binding. + content: + application/json: + schema: + $ref: '#/components/schemas/LogicalConnectionBinding' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + + /route/exposures: + get: + operationId: listRouteExposureDescriptors + summary: List route exposure descriptors + description: | + Lists externally callable route exposure descriptors. Exposure descriptors are registry + records for external read/write capabilities, including accepted auth methods, caller Party + and relationship constraints, schemas, subset mapping, payload/rate limits, and audit category. + tags: [RouteExposures] + parameters: + - name: logicalConnectionBindingId + in: query + required: false + description: Filter by logical connection binding backing the exposed capability. + schema: + $ref: './connector-components.yml#/components/schemas/LogicalConnectionBindingId' + example: brand-a-proof-vault + - name: exchangeMode + in: query + required: false + description: Filter by the route exposure exchange quadrant. + schema: + $ref: './connector-components.yml#/components/schemas/ConnectorExchangeMode' + example: EXTERNALLY_INITIATED_READ_FROM_VDX + - $ref: './common-components.yml#/components/parameters/Page' + - $ref: './common-components.yml#/components/parameters/Size' + responses: + '200': + description: Paged route exposure descriptors. + content: + application/json: + schema: + $ref: '#/components/schemas/RouteExposureDescriptorPage' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + post: + operationId: createRouteExposureDescriptor + summary: Create a route exposure descriptor + description: | + Creates or replaces a route exposure descriptor for an externally initiated connector + capability. This registers the externally callable surface but does not by itself implement + the runtime endpoint for the external caller. + tags: [RouteExposures] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/RouteExposureDescriptorCreateRequest' + responses: + '201': + description: Route exposure descriptor created. + content: + application/json: + schema: + $ref: '#/components/schemas/RouteExposureDescriptor' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + + /route/exposures/{exposureDescriptorId}: + get: + operationId: getRouteExposureDescriptor + summary: Get a route exposure descriptor + description: Reads one route exposure descriptor by id. + tags: [RouteExposures] + parameters: + - $ref: './connector-components.yml#/components/parameters/ExposureDescriptorId' + responses: + '200': + description: Route exposure descriptor. + content: + application/json: + schema: + $ref: '#/components/schemas/RouteExposureDescriptor' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + + /route/exposures/{exposureDescriptorId}/read: + post: + operationId: executeRouteExposureRead + summary: Execute an externally initiated route exposure read + description: | + Executes an explicitly registered external-read route exposure. The caller supplies the + authenticated Party context, governed canonical fields already eligible for projection, + governance metadata, a policy decision, and optional cursor state. The response is an + approved governed view with manifest, policy lineage, selected fields, and cursor state. + This endpoint does not expose internal connector records, Party tables, vault rows, or + semantic stores directly. + tags: [RouteExposures] + parameters: + - $ref: './connector-components.yml#/components/parameters/ExposureDescriptorId' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/RouteExposureExternalReadRequest' + responses: + '200': + description: Governed external-read view. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorExternalReadResponse' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + + /route/exposures/{exposureDescriptorId}/write: + post: + operationId: executeRouteExposureWrite + summary: Execute an externally initiated route exposure write + description: | + Executes an explicitly registered external-write route exposure. The caller supplies the + authenticated Party context, governed payload envelope, field mappings, governance metadata, + policy decision, optional idempotency key, and optional Party projection candidates. The + response is an accepted, minimized, redacted, quarantined, or rejected governed-ingress + receipt with canonical-field mapping, projection-candidate ids, policy lineage, idempotency + result, payload hash, and later-use availability scope. + tags: [RouteExposures] + parameters: + - $ref: './connector-components.yml#/components/parameters/ExposureDescriptorId' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/RouteExposureExternalWriteRequest' + responses: + '200': + description: Governed external-write receipt. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorExternalWriteReceipt' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + + /data/products: + get: + operationId: listDataProductDescriptors + summary: List connector data product descriptors + description: | + Lists connector data product descriptors. These registry records connect a logical binding + and physical connector instance to dataset resource descriptors, selected field scopes, + transfer types, provider and consumer Party references, governance scope, and catalog offer + references. This is the Phase 5 dataspace/data-use-contract readiness surface; it does not + implement DSP/DCAT runtime behavior by itself. + tags: [ConnectorDataProducts] + parameters: + - name: logicalConnectionBindingId + in: query + required: false + description: Filter by logical connection binding backing the data product. + schema: + $ref: './connector-components.yml#/components/schemas/LogicalConnectionBindingId' + example: brand-a-proof-vault + - name: physicalConnectorInstanceId + in: query + required: false + description: Filter by the physical connector instance backing the data product. + schema: + $ref: './connector-components.yml#/components/schemas/ConnectorInstanceId' + example: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b + - $ref: './common-components.yml#/components/parameters/Page' + - $ref: './common-components.yml#/components/parameters/Size' + responses: + '200': + description: Paged connector data product descriptors. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorDataProductDescriptorPage' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + post: + operationId: createDataProductDescriptor + summary: Create a connector data product descriptor + description: | + Creates or replaces a connector data product descriptor. The descriptor must reference an + existing logical connection binding, matching physical connector instance, known dataset + resource descriptors, at least one transfer type, and at least one catalog offer policy ref. + tags: [ConnectorDataProducts] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorDataProductDescriptorCreateRequest' + responses: + '201': + description: Connector data product descriptor created. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorDataProductDescriptor' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + + /data/products/{dataProductId}: + get: + operationId: getDataProductDescriptor + summary: Get a connector data product descriptor + description: Reads one connector data product descriptor by id. + tags: [ConnectorDataProducts] + parameters: + - $ref: './connector-components.yml#/components/parameters/DataProductId' + responses: + '200': + description: Connector data product descriptor. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorDataProductDescriptor' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + /transformations: get: operationId: listTransformations @@ -936,6 +1339,39 @@ paths: $ref: './common-components.yml#/components/responses/NotFound' /routes/{routeId}/runs: + get: + operationId: listConnectorRouteRuns + summary: List connector route runs + description: | + Lists execution history for one connector route. Use this route-scoped view when a route + detail screen or orchestrator needs only runs belonging to the selected route. Tenant-wide + operational dashboards should use `/runs` and its filters. + tags: [Runs] + parameters: + - $ref: './connector-components.yml#/components/parameters/RouteId' + - $ref: './connector-components.yml#/components/parameters/ConnectorRunStatus' + - $ref: './connector-components.yml#/components/parameters/ConnectorInstanceIdQuery' + - $ref: './connector-components.yml#/components/parameters/InvocationBindingIdQuery' + - $ref: './connector-components.yml#/components/parameters/LogicalConnectionBindingIdQuery' + - $ref: './connector-components.yml#/components/parameters/PhysicalConnectorInstanceIdQuery' + - $ref: './connector-components.yml#/components/parameters/ConnectorExchangeModeQuery' + - $ref: './connector-components.yml#/components/parameters/ProtocolSurfaceQuery' + - $ref: './connector-components.yml#/components/parameters/CorrelationIdQuery' + - $ref: './common-components.yml#/components/parameters/Page' + - $ref: './common-components.yml#/components/parameters/Size' + responses: + '200': + description: Paged connector runs for the route. + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectorRunPage' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '404': + $ref: './common-components.yml#/components/responses/NotFound' post: operationId: createConnectorRouteRun summary: Start a connector route run @@ -971,12 +1407,21 @@ paths: operationId: listConnectorRuns summary: List connector runs description: | - Lists route and operation runs for the tenant. Use this for operational dashboards, - customer support, audit trails, retry decisions, and monitoring failed or partially failed - imports and exports. + Lists route and operation runs across the tenant. Use this direct tenant-wide run resource + for operational dashboards, customer support, audit trails, retry decisions, and monitoring + failed or partially failed imports and exports. Use `/routes/{routeId}/runs` for + route-scoped history. tags: [Runs] parameters: - $ref: './connector-components.yml#/components/parameters/ConnectorRunStatus' + - $ref: './connector-components.yml#/components/parameters/RouteIdQuery' + - $ref: './connector-components.yml#/components/parameters/ConnectorInstanceIdQuery' + - $ref: './connector-components.yml#/components/parameters/InvocationBindingIdQuery' + - $ref: './connector-components.yml#/components/parameters/LogicalConnectionBindingIdQuery' + - $ref: './connector-components.yml#/components/parameters/PhysicalConnectorInstanceIdQuery' + - $ref: './connector-components.yml#/components/parameters/ConnectorExchangeModeQuery' + - $ref: './connector-components.yml#/components/parameters/ProtocolSurfaceQuery' + - $ref: './connector-components.yml#/components/parameters/CorrelationIdQuery' - $ref: './common-components.yml#/components/parameters/Page' - $ref: './common-components.yml#/components/parameters/Size' responses: @@ -1037,7 +1482,7 @@ paths: '404': $ref: './common-components.yml#/components/responses/NotFound' - /runs/{runId}/dead-letters: + /runs/{runId}/deadletters: get: operationId: listConnectorDeadLetters summary: List connector dead letters @@ -1073,6 +1518,8 @@ components: $ref: './connector-components.yml#/components/schemas/ResourceKind' OperationKind: $ref: './connector-components.yml#/components/schemas/OperationKind' + OperationTransferMode: + $ref: './connector-components.yml#/components/schemas/OperationTransferMode' ConnectorInstanceCreateRequest: $ref: './connector-components.yml#/components/schemas/ConnectorInstanceCreateRequest' ConnectorInstanceUpdateRequest: @@ -1085,8 +1532,6 @@ components: $ref: './connector-components.yml#/components/schemas/ConnectorIdentity' ConnectorIdentityPage: $ref: './connector-components.yml#/components/schemas/ConnectorIdentityPage' - AttachConnectorIdentityRequest: - $ref: './connector-components.yml#/components/schemas/AttachConnectorIdentityRequest' ConnectorResource: $ref: './connector-components.yml#/components/schemas/ConnectorResource' ConnectorResourcePage: @@ -1121,6 +1566,62 @@ components: $ref: './connector-components.yml#/components/schemas/SemanticConnectorBinding' SemanticConnectorBindingPage: $ref: './connector-components.yml#/components/schemas/SemanticConnectorBindingPage' + ConnectorInvocationBindingCreateRequest: + $ref: './connector-components.yml#/components/schemas/ConnectorInvocationBindingCreateRequest' + ConnectorInvocationBinding: + $ref: './connector-components.yml#/components/schemas/ConnectorInvocationBinding' + ConnectorInvocationBindingPage: + $ref: './connector-components.yml#/components/schemas/ConnectorInvocationBindingPage' + ConnectorInvocationRequest: + $ref: './connector-components.yml#/components/schemas/ConnectorInvocationRequest' + ConnectorInvocationResult: + $ref: './connector-components.yml#/components/schemas/ConnectorInvocationResult' + ConnectorRunCorrelation: + $ref: './connector-components.yml#/components/schemas/ConnectorRunCorrelation' + ConnectorVaultWrite: + $ref: './connector-components.yml#/components/schemas/ConnectorVaultWrite' + ConnectorVaultRetentionProfile: + $ref: './connector-components.yml#/components/schemas/ConnectorVaultRetentionProfile' + Oid4vciConnectorPipelineRequest: + $ref: './connector-components.yml#/components/schemas/Oid4vciConnectorPipelineRequest' + Oid4vciConnectorPipelineResult: + $ref: './connector-components.yml#/components/schemas/Oid4vciConnectorPipelineResult' + LogicalConnectionBindingCreateRequest: + $ref: './connector-components.yml#/components/schemas/LogicalConnectionBindingCreateRequest' + LogicalConnectionBinding: + $ref: './connector-components.yml#/components/schemas/LogicalConnectionBinding' + LogicalConnectionBindingPage: + $ref: './connector-components.yml#/components/schemas/LogicalConnectionBindingPage' + RouteExposureDescriptorCreateRequest: + $ref: './connector-components.yml#/components/schemas/RouteExposureDescriptorCreateRequest' + RouteExposureDescriptor: + $ref: './connector-components.yml#/components/schemas/RouteExposureDescriptor' + RouteExposureDescriptorPage: + $ref: './connector-components.yml#/components/schemas/RouteExposureDescriptorPage' + RouteExposureExternalReadRequest: + $ref: './connector-components.yml#/components/schemas/RouteExposureExternalReadRequest' + RouteExposureExternalWriteRequest: + $ref: './connector-components.yml#/components/schemas/RouteExposureExternalWriteRequest' + ConnectorExternalReadResponse: + $ref: './connector-components.yml#/components/schemas/ConnectorExternalReadResponse' + ConnectorExternalWriteReceipt: + $ref: './connector-components.yml#/components/schemas/ConnectorExternalWriteReceipt' + ConnectorDataProductId: + $ref: './connector-components.yml#/components/schemas/ConnectorDataProductId' + ConnectorDataProductDescriptorCreateRequest: + $ref: './connector-components.yml#/components/schemas/ConnectorDataProductDescriptorCreateRequest' + ConnectorDataProductDescriptor: + $ref: './connector-components.yml#/components/schemas/ConnectorDataProductDescriptor' + ConnectorDataProductDescriptorPage: + $ref: './connector-components.yml#/components/schemas/ConnectorDataProductDescriptorPage' + ConnectorCatalogOfferRef: + $ref: './connector-components.yml#/components/schemas/ConnectorCatalogOfferRef' + ConnectorCatalogOfferId: + $ref: './connector-components.yml#/components/schemas/ConnectorCatalogOfferId' + ConnectorOdrlPolicyRef: + $ref: './connector-components.yml#/components/schemas/ConnectorOdrlPolicyRef' + ConnectorOdrlPolicyType: + $ref: './connector-components.yml#/components/schemas/ConnectorOdrlPolicyType' TransformationCreateRequest: $ref: './connector-components.yml#/components/schemas/TransformationCreateRequest' TransformationUpdateRequest: diff --git a/credential-design-components.yml b/credential-design-components.yml index 2c7b72e..cae9db1 100644 --- a/credential-design-components.yml +++ b/credential-design-components.yml @@ -96,8 +96,9 @@ components: Hosting intent for an SD-JWT VC type identifier in a design binding. - `HOSTED`: the issuer derives and serves the VCT metadata document at `/public/schema/vct/{vctId}`. - `EXTERNAL`: the `vct` is an externally hosted URI and must not be served by this issuer. + - `REGISTERED`: the `vct` is a standards or registry identifier, such as an EUDI PID or age attestation URN, that this issuer does not host. - `NONE`: the `vct` is a regular string or otherwise non-hosted identifier. - enum: [HOSTED, EXTERNAL, NONE] + enum: [HOSTED, EXTERNAL, REGISTERED, NONE] DesignSourceType: type: string diff --git a/credential-design-openapi.yml b/credential-design-openapi.yml index 49ed1e7..ed61757 100644 --- a/credential-design-openapi.yml +++ b/credential-design-openapi.yml @@ -303,15 +303,10 @@ paths: tags: [CredentialDesigns] summary: Delete a credential design operationId: deleteCredentialDesign - description: Deletes a credential design. Returns `true` when a design was removed. + description: Deletes a credential design and returns no response body when successful. responses: - '200': - description: Whether a design was deleted. - content: - application/json: - schema: - type: boolean - example: true + '204': + description: The credential design was deleted. '401': $ref: './common-components.yml#/components/responses/Unauthorized' '404': @@ -639,15 +634,10 @@ paths: tags: [IssuerDesigns] summary: Delete an issuer design operationId: deleteIssuerDesign - description: Deletes an issuer design. Returns `true` when a design was removed. + description: Deletes an issuer design and returns no response body when successful. responses: - '200': - description: Whether a design was deleted. - content: - application/json: - schema: - type: boolean - example: true + '204': + description: The issuer design was deleted. '401': $ref: './common-components.yml#/components/responses/Unauthorized' '404': @@ -889,15 +879,10 @@ paths: tags: [VerifierDesigns] summary: Delete a verifier design operationId: deleteVerifierDesign - description: Deletes a verifier design. Returns `true` when a design was removed. + description: Deletes a verifier design and returns no response body when successful. responses: - '200': - description: Whether a design was deleted. - content: - application/json: - schema: - type: boolean - example: true + '204': + description: The verifier design was deleted. '401': $ref: './common-components.yml#/components/responses/Unauthorized' '404': @@ -1028,15 +1013,10 @@ paths: tags: [RenderVariants] summary: Delete a render variant operationId: deleteRenderVariant - description: Deletes a render variant. Returns `true` when a variant was removed. + description: Deletes a render variant and returns no response body when successful. responses: - '200': - description: Whether a variant was deleted. - content: - application/json: - schema: - type: boolean - example: true + '204': + description: Render variant deleted. '401': $ref: './common-components.yml#/components/responses/Unauthorized' '404': @@ -1131,6 +1111,10 @@ paths: schema: type: string format: binary + application/pdf: + schema: + type: string + format: binary '404': $ref: './common-components.yml#/components/responses/NotFound' @@ -1191,6 +1175,18 @@ paths: schema: type: string format: binary + image/png: + schema: + type: string + format: binary + image/svg+xml: + schema: + type: string + format: binary + application/pdf: + schema: + type: string + format: binary responses: '201': description: A reference to the stored asset. @@ -1227,6 +1223,18 @@ paths: schema: type: string format: binary + image/png: + schema: + type: string + format: binary + image/svg+xml: + schema: + type: string + format: binary + application/pdf: + schema: + type: string + format: binary responses: '201': description: A reference to the stored asset. @@ -1257,6 +1265,22 @@ paths: schema: type: string format: binary + image/png: + schema: + type: string + format: binary + image/jpeg: + schema: + type: string + format: binary + image/svg+xml: + schema: + type: string + format: binary + application/pdf: + schema: + type: string + format: binary '401': $ref: './common-components.yml#/components/responses/Unauthorized' '404': diff --git a/platform-config-components.yml b/platform-config-components.yml index ca45dda..c81b11b 100644 --- a/platform-config-components.yml +++ b/platform-config-components.yml @@ -3372,6 +3372,17 @@ components: nullable: true description: Action taken for the accompanying credential design. example: created + designDraft: + type: object + allOf: + - $ref: './credential-design-components.yml#/components/schemas/CreateCredentialDesignInput' + nullable: true + description: Credential-design create body planned from the imported OID4VCI metadata. + renderVariantDrafts: + type: array + description: Render variants planned from OID4VCI display colors and assets. The admin console creates these before attaching their ids to the credential design. + items: + $ref: './credential-design-components.yml#/components/schemas/CreateRenderVariantInput' CredentialConfigurationImportResult: type: object description: Result of a credential-configuration import, listing the per-configuration action taken. diff --git a/redocly.yaml b/redocly.yaml index 8e18253..3ae0842 100644 --- a/redocly.yaml +++ b/redocly.yaml @@ -73,6 +73,8 @@ apis: root: attribute-source-openapi.yml vdx-connector: root: connector-openapi.yml + vdx-connector-integration: + root: connector-integration-openapi.yml vdx-resource-manager: root: resource-manager-openapi.yml vdx-user-manager: From e57829f6567cc19cbacd9eb4364d209d01e1adb7 Mon Sep 17 00:00:00 2001 From: Niels Klomp Date: Sun, 5 Jul 2026 03:48:48 +0200 Subject: [PATCH 4/8] chore: fixes --- credential-design-components.yml | 176 +++++++++++++++++++++++-------- credential-design-openapi.yml | 4 +- did-openapi.yml | 4 +- 3 files changed, 136 insertions(+), 48 deletions(-) diff --git a/credential-design-components.yml b/credential-design-components.yml index cae9db1..04be591 100644 --- a/credential-design-components.yml +++ b/credential-design-components.yml @@ -279,6 +279,7 @@ components: properties: vct: type: string + nullable: true description: | SD-JWT VC type identifier. With `vctHostingMode: HOSTED`, callers may provide a plain string and let the issuer derive the hosted URI. With `EXTERNAL`, this must be @@ -288,42 +289,49 @@ components: $ref: '#/components/schemas/VctHostingMode' credentialConfigurationId: type: string + nullable: true description: OID4VCI credential configuration id. example: IdentityCredential schemaId: type: string + nullable: true description: JSON Schema `$id` the credential validates against. docType: type: string + nullable: true description: ISO mdoc doctype. example: org.iso.18013.5.1.mDL type: type: string + nullable: true description: W3C VC type value. '@context': type: string + nullable: true description: W3C VC JSON-LD `@context` URL. issuerId: type: string + nullable: true description: Logical issuer identifier. issuerDid: type: string + nullable: true description: Issuer DID. example: did:web:issuer.example.com issuerUri: type: string + nullable: true description: Issuer base URL. verifierClientId: type: string + nullable: true description: OID4VP verifier `client_id`. ocaSaid: type: string + nullable: true description: Self-addressing identifier (SAID) of a bound OCA bundle. credentialType: - type: object - allOf: - - $ref: '#/components/schemas/CredentialTypeDescriptor' - nullable: true + $ref: '#/components/schemas/NullableCredentialTypeDescriptor' description: Optional binding-side type hint. If present it must match the credential design's `credentialType`. credentialDesignId: type: string @@ -716,6 +724,104 @@ components: items: type: string + NullableCredentialTypeDescriptor: + type: object + nullable: true + description: Nullable credential type descriptor as serialized on optional binding hints. + required: [format] + properties: + format: + $ref: '#/components/schemas/CredentialTypeFormat' + vct: + type: string + nullable: true + docType: + type: string + nullable: true + type: + type: string + nullable: true + '@context': + type: string + nullable: true + + NullableAssetReference: + type: object + nullable: true + description: Nullable asset reference as serialized by the runtime for unset render variant fields. + required: [uri] + properties: + uri: + type: string + description: Resolvable URI of the asset. For locally stored assets this is the asset download URL. + integrity: + type: string + nullable: true + altText: + type: string + nullable: true + contentType: + type: string + nullable: true + localBlob: + type: object + nullable: true + + NullableSvgTemplate: + type: object + nullable: true + description: Nullable SVG render template reference as serialized by the runtime. + required: [uri] + properties: + uri: + type: string + integrity: + type: string + nullable: true + orientation: + type: string + nullable: true + colorScheme: + type: string + nullable: true + contrast: + type: string + nullable: true + localBlob: + type: object + nullable: true + + NullableW3cRenderMethodReference: + type: object + nullable: true + description: Nullable W3C render method reference as serialized by the runtime. + required: [type, uri] + properties: + type: + type: string + renderSuite: + type: string + nullable: true + uri: + type: string + mediaType: + type: string + nullable: true + name: + type: string + nullable: true + description: + type: string + nullable: true + digestMultibase: + type: string + nullable: true + renderProperties: + type: array + nullable: true + items: + type: string + ExternalDesignMetadata: type: object description: | @@ -832,6 +938,18 @@ components: nullable: true description: Pinned bundle version; null resolves the current version. + NullableSemanticAttributeSetRef: + type: object + nullable: true + description: Nullable semantic attribute set reference as serialized on credential design records. + required: [bundleId] + properties: + bundleId: + type: string + version: + type: string + nullable: true + FieldRenderHint: type: object description: A derived per-field rendering hint, computed from imported source layers. @@ -984,10 +1102,7 @@ components: nullable: true description: Hash of the canonical design content, used for change detection and ETags. semanticAttributeSetRef: - type: object - allOf: - - $ref: '#/components/schemas/SemanticAttributeSetRef' - nullable: true + $ref: '#/components/schemas/NullableSemanticAttributeSetRef' attributeProfileId: type: string format: uuid @@ -1189,15 +1304,9 @@ components: format: uuid nullable: true logo: - type: object - allOf: - - $ref: '#/components/schemas/AssetReference' - nullable: true + $ref: '#/components/schemas/NullableAssetReference' backgroundImage: - type: object - allOf: - - $ref: '#/components/schemas/AssetReference' - nullable: true + $ref: '#/components/schemas/NullableAssetReference' backgroundColor: type: string nullable: true @@ -1211,20 +1320,11 @@ components: type: string nullable: true svgTemplate: - type: object - allOf: - - $ref: '#/components/schemas/SvgTemplate' - nullable: true + $ref: '#/components/schemas/NullableSvgTemplate' w3cRenderMethod: - type: object - allOf: - - $ref: '#/components/schemas/W3cRenderMethodReference' - nullable: true + $ref: '#/components/schemas/NullableW3cRenderMethodReference' pdfTemplate: - type: object - allOf: - - $ref: '#/components/schemas/AssetReference' - nullable: true + $ref: '#/components/schemas/NullableAssetReference' example: id: 4f5e6d7c-8b9a-0f1e-2d3c-4b5a6978abcd tenantId: 6b1f0c2a-7d3e-4a9b-8c5d-1e2f3a4b5c6d @@ -1791,15 +1891,9 @@ components: items: type: string logo: - type: object - allOf: - - $ref: '#/components/schemas/AssetReference' - nullable: true + $ref: '#/components/schemas/NullableAssetReference' backgroundImage: - type: object - allOf: - - $ref: '#/components/schemas/AssetReference' - nullable: true + $ref: '#/components/schemas/NullableAssetReference' backgroundColor: type: string nullable: true @@ -1810,15 +1904,9 @@ components: type: string nullable: true svgTemplate: - type: object - allOf: - - $ref: '#/components/schemas/SvgTemplate' - nullable: true + $ref: '#/components/schemas/NullableSvgTemplate' w3cRenderMethod: - type: object - allOf: - - $ref: '#/components/schemas/W3cRenderMethodReference' - nullable: true + $ref: '#/components/schemas/NullableW3cRenderMethodReference' example: kind: SIMPLE_CARD alias: identity-card-blue diff --git a/credential-design-openapi.yml b/credential-design-openapi.yml index ed61757..05c7bcf 100644 --- a/credential-design-openapi.yml +++ b/credential-design-openapi.yml @@ -169,7 +169,7 @@ paths: '500': $ref: './common-components.yml#/components/responses/Error' - /designs/credential-bindings/{bindingKey}/{bindingValue}: + /designs/credentials/bindings/{bindingKey}/{bindingValue}: parameters: - $ref: './credential-design-components.yml#/components/parameters/BindingKey' - $ref: './credential-design-components.yml#/components/parameters/BindingValue' @@ -1016,7 +1016,7 @@ paths: description: Deletes a render variant and returns no response body when successful. responses: '204': - description: Render variant deleted. + description: The render variant was deleted. '401': $ref: './common-components.yml#/components/responses/Unauthorized' '404': diff --git a/did-openapi.yml b/did-openapi.yml index 49078e5..04d9e6f 100644 --- a/did-openapi.yml +++ b/did-openapi.yml @@ -326,7 +326,7 @@ paths: content: application/json: schema: - $ref: './did-components.yml#/components/schemas/DidDetail' + $ref: './did-components.yml#/components/schemas/Did' '401': $ref: './common-components.yml#/components/responses/Unauthorized' '403': @@ -2304,7 +2304,7 @@ components: items: type: array items: - $ref: './did-components.yml#/components/schemas/DidDetail' + $ref: './did-components.yml#/components/schemas/Did' page: $ref: './common-components.yml#/components/schemas/PageMeta' From f322c514d21f08014f3955df612971478704c080 Mon Sep 17 00:00:00 2001 From: Niels Klomp Date: Sun, 5 Jul 2026 03:59:05 +0200 Subject: [PATCH 5/8] chore: fixes --- .redocly.lint-ignore.yaml | 19 +++ credential-design-openapi.yml | 85 ++++++++++++++ did-openapi.yml | 43 +++++-- forms-components.yml | 13 +++ forms-openapi.yml | 18 ++- identity-manager-components.yml | 9 ++ kms-openapi.yml | 140 ++++++----------------- license-portal-openapi.yaml | 38 ------ oid4vci-issuance-template-openapi.yml | 54 +++++++++ oid4vp-universal-openapi.yml | 28 ----- oid4vp-verification-template-openapi.yml | 46 ++++++++ platform-admin-openapi.yaml | 33 ++++-- redocly.yaml | 6 +- resource-manager-openapi.yml | 7 ++ semantic-binding-components.yml | 2 + semantic-binding-openapi.yml | 2 + semantic-model-authoring-components.yml | 36 ++++-- semantic-model-authoring-openapi.yml | 3 + semantic-vocabulary-openapi.yml | 1 + software-manager-openapi.yml | 6 + statuslist-management-openapi.yml | 120 ++++++++++--------- user-manager-openapi.yml | 7 ++ 22 files changed, 458 insertions(+), 258 deletions(-) create mode 100644 .redocly.lint-ignore.yaml diff --git a/.redocly.lint-ignore.yaml b/.redocly.lint-ignore.yaml new file mode 100644 index 0000000..0a8dd51 --- /dev/null +++ b/.redocly.lint-ignore.yaml @@ -0,0 +1,19 @@ +# This file instructs Redocly's linter to ignore the rules contained for specific parts of your API. +# See https://redocly.com/docs/cli/ for more information. +connector-components.yml: + struct: + - '#/components/schemas/TransformationStep/properties/value/nullable' + - >- + #/components/schemas/StartConnectorRouteRunRequest/properties/input/nullable +oid4vci-issuer-components.yml: + struct: + - '#/components/schemas/SdJwtVcClaimInformation/properties/path/items/nullable' +credential-design-openapi.yml: + no-ambiguous-paths: + - '#/paths/~1designs~1credentials~1{designId}~1versions~1{version}' +forms-openapi.yml: + no-ambiguous-paths: + - '#/paths/~1forms~1sessions~1{sessionId}' +invitation-openapi.yml: + no-ambiguous-paths: + - '#/paths/~1invitations~1batches~1{batchId}' diff --git a/credential-design-openapi.yml b/credential-design-openapi.yml index 05c7bcf..a144a9d 100644 --- a/credential-design-openapi.yml +++ b/credential-design-openapi.yml @@ -100,6 +100,9 @@ paths: application/json: schema: $ref: '#/components/schemas/CreateCredentialDesignInput' + examples: + createIdentityCredentialDesign: + $ref: '#/components/examples/CreateIdentityCredentialDesignRequest' responses: '201': description: The created credential design. @@ -107,6 +110,9 @@ paths: application/json: schema: $ref: '#/components/schemas/CredentialDesignRecord' + examples: + identityCredentialDesign: + $ref: '#/components/examples/IdentityCredentialDesignRecord' '400': $ref: './common-components.yml#/components/responses/ValidationError' '401': @@ -1281,6 +1287,22 @@ paths: schema: type: string format: binary + image/png: + schema: + type: string + format: binary + image/jpeg: + schema: + type: string + format: binary + image/svg+xml: + schema: + type: string + format: binary + application/pdf: + schema: + type: string + format: binary '401': $ref: './common-components.yml#/components/responses/Unauthorized' '404': @@ -1336,6 +1358,69 @@ components: schema: $ref: './credential-design-components.yml#/components/schemas/DesignSourceType' + examples: + CreateIdentityCredentialDesignRequest: + summary: Create an SD-JWT VC identity credential design + value: + credentialType: + format: SD_JWT_VC + vct: https://issuer.example.com/identity + bindings: + - vct: https://issuer.example.com/identity + credentialConfigurationId: IdentityCredential + alias: identity-credential + hostingMode: LOCAL + displays: + - locale: en + name: Identity Credential + description: Government-issued digital identity + - locale: nl + name: Identiteitsbewijs + claims: + - path: + - { type: property, name: given_name } + labels: + - { locale: en, label: First name } + - { locale: nl, label: Voornaam } + mandatory: true + order: 1 + valueKind: STRING + widgetHint: TEXT + IdentityCredentialDesignRecord: + summary: Stored SD-JWT VC identity credential design + value: + id: 9a4f6b2e-3c1d-4e8a-9f7b-2c1d4e8a9f7b + tenantId: 6b1f0c2a-7d3e-4a9b-8c5d-1e2f3a4b5c6d + alias: identity-credential + hostingMode: LOCAL + credentialType: + format: SD_JWT_VC + vct: https://issuer.example.com/identity + bindings: + - vct: https://issuer.example.com/identity + credentialConfigurationId: IdentityCredential + displays: + - locale: en + name: Identity Credential + description: Government-issued digital identity + - locale: nl + name: Identiteitsbewijs + claims: + - path: + - { type: property, name: given_name } + labels: + - { locale: en, label: First name } + - { locale: nl, label: Voornaam } + mandatory: true + order: 1 + valueKind: STRING + widgetHint: TEXT + renderVariantIds: + - 4f5e6d7c-8b9a-0f1e-2d3c-4b5a6978abcd + contentHash: sha256-8f3a1c2b9d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8 + createdAt: '2026-06-08T10:15:00Z' + updatedAt: '2026-06-08T10:15:00Z' + schemas: # ---- Re-exported entity / value schemas --------------------------------- DesignBinding: diff --git a/did-openapi.yml b/did-openapi.yml index 04d9e6f..5547102 100644 --- a/did-openapi.yml +++ b/did-openapi.yml @@ -80,17 +80,9 @@ paths: application/json: schema: $ref: '#/components/schemas/DidCreateRequest' - example: - method: "web" - keyInfo: - providerId: "softwaretest" - alias: "issuer-signing-key" - didAlias: "acme-issuer" - controllers: - - "did:web:controller-a.example.com" - options: - domain: "issuer.example.com" - path: "did/acme" + examples: + createWebDid: + $ref: '#/components/examples/CreateWebDidRequest' responses: '201': description: DID created successfully. @@ -105,6 +97,9 @@ paths: application/json: schema: $ref: './did-components.yml#/components/schemas/Did' + examples: + createdWebDid: + $ref: '#/components/examples/CreatedWebDid' '400': $ref: './common-components.yml#/components/responses/ValidationError' '401': @@ -1721,6 +1716,32 @@ components: bearer: $ref: './common-components.yml#/components/securitySchemes/bearer' + examples: + CreateWebDidRequest: + summary: Create a managed did:web identifier + value: + method: "web" + keyInfo: + providerId: "softwaretest" + alias: "issuer-signing-key" + didAlias: "acme-issuer" + controllers: + - "did:web:controller-a.example.com" + options: + domain: "issuer.example.com" + path: "did/acme" + CreatedWebDid: + summary: Managed did:web identifier + value: + did: "did:web:issuer.example.com:did:acme" + method: "web" + alias: "acme-issuer" + role: "MANAGED" + alsoKnownAs: [] + equivalentIds: [] + createdAt: "2026-06-06T09:00:00Z" + updatedAt: "2026-06-06T09:00:00Z" + schemas: # -- Re-exported entity schemas from did-components.yml -- Did: diff --git a/forms-components.yml b/forms-components.yml index bb2ee5c..c0bcdb1 100644 --- a/forms-components.yml +++ b/forms-components.yml @@ -323,6 +323,7 @@ components: defaultValue: allOf: - $ref: '#/components/schemas/FieldValue' + type: object nullable: true placeholders: type: object @@ -332,10 +333,12 @@ components: visibilityCondition: allOf: - $ref: '#/components/schemas/FieldCondition' + type: object nullable: true qualificationCondition: allOf: - $ref: '#/components/schemas/FieldCondition' + type: object nullable: true disqualificationBehavior: $ref: '#/components/schemas/DisqualificationBehavior' @@ -345,6 +348,7 @@ components: widgetHintOverride: allOf: - $ref: '#/components/schemas/AttributeWidgetHint' + type: string nullable: true mandatoryOverride: $ref: '#/components/schemas/MandatoryOverride' @@ -497,6 +501,7 @@ components: defaultValue: allOf: - $ref: '#/components/schemas/FieldValue' + type: object nullable: true validationRules: type: array @@ -507,10 +512,12 @@ components: visibilityCondition: allOf: - $ref: '#/components/schemas/FieldCondition' + type: object nullable: true qualificationCondition: allOf: - $ref: '#/components/schemas/FieldCondition' + type: object nullable: true disqualificationBehavior: $ref: '#/components/schemas/DisqualificationBehavior' @@ -754,6 +761,7 @@ components: presentedCredential: allOf: - $ref: '#/components/schemas/PresentedCredentialClaims' + type: object nullable: true description: | Raw presented credential payload. When non-null the credential bridge projects @@ -1023,6 +1031,7 @@ components: operation: allOf: - $ref: '#/components/schemas/FormSessionOperation' + type: string nullable: true activeStepIndex: type: integer @@ -1487,6 +1496,7 @@ components: credential: allOf: - $ref: '#/components/schemas/CredentialClaimProvenance' + type: object nullable: true FieldLockReason: @@ -1684,10 +1694,12 @@ components: lockReason: allOf: - $ref: '#/components/schemas/FieldLockReason' + type: string nullable: true valueProvenance: allOf: - $ref: '#/components/schemas/FieldValueProvenance' + type: object nullable: true FieldValidationState: @@ -1729,6 +1741,7 @@ components: result: allOf: - $ref: '#/components/schemas/StepActionResult' + type: object nullable: true startedAt: type: string diff --git a/forms-openapi.yml b/forms-openapi.yml index 288f93e..6c6a74e 100644 --- a/forms-openapi.yml +++ b/forms-openapi.yml @@ -20,6 +20,10 @@ info: servers: - url: http://localhost:8080/api/v1 description: Local development. + +security: + - bearer: [] + tags: - name: Forms description: Form definitions, sessions, and step actions. @@ -815,6 +819,9 @@ paths: $ref: '#/components/responses/Error' components: + securitySchemes: + bearer: + $ref: './common-components.yml#/components/securitySchemes/bearer' parameters: IfMatch: $ref: './forms-components.yml#/components/parameters/IfMatch' @@ -867,12 +874,6 @@ components: application/json: schema: $ref: '#/components/schemas/ErrorResponse' - Forbidden: - description: Insufficient permissions. - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' Conflict: description: | Idempotency or policy-gate conflict. The `code` field distinguishes @@ -1082,6 +1083,7 @@ components: defaultValue: allOf: - $ref: '#/components/schemas/FieldValue' + type: object nullable: true placeholders: type: object @@ -1091,10 +1093,12 @@ components: visibilityCondition: allOf: - $ref: '#/components/schemas/FieldCondition' + type: object nullable: true qualificationCondition: allOf: - $ref: '#/components/schemas/FieldCondition' + type: object nullable: true disqualificationBehavior: $ref: '#/components/schemas/DisqualificationBehavior' @@ -1104,6 +1108,7 @@ components: widgetHintOverride: allOf: - $ref: '#/components/schemas/AttributeWidgetHint' + type: string nullable: true mandatoryOverride: $ref: '#/components/schemas/MandatoryOverride' @@ -1124,6 +1129,7 @@ components: status: allOf: - $ref: '#/components/schemas/FormStatus' + type: string nullable: true steps: type: array diff --git a/identity-manager-components.yml b/identity-manager-components.yml index f6c9e31..8e3d825 100644 --- a/identity-manager-components.yml +++ b/identity-manager-components.yml @@ -211,6 +211,7 @@ components: identityRole: allOf: - $ref: '#/components/schemas/IdentityRole' + type: string nullable: true isDefault: type: boolean @@ -219,6 +220,7 @@ components: privacyMode: allOf: - $ref: '#/components/schemas/IdentityPrivacyMode' + type: string nullable: true example: partyId: "4c7e79f0-9f6d-4a38-8455-6e0b3f4f5a10" @@ -304,6 +306,7 @@ components: protectionMode: allOf: - $ref: '#/components/schemas/IdentifierProtectionMode' + type: string nullable: true isPrimary: type: boolean @@ -358,14 +361,17 @@ components: x509Extension: allOf: - $ref: '#/components/schemas/X509ExtensionData' + type: object nullable: true registrationExtension: allOf: - $ref: '#/components/schemas/RegistrationExtensionData' + type: object nullable: true electronicExtension: allOf: - $ref: '#/components/schemas/ElectronicExtensionData' + type: object nullable: true example: id: "6c36e57d-2c46-4a53-a8ff-b60e47f97f11" @@ -444,14 +450,17 @@ components: x509Extension: allOf: - $ref: '#/components/schemas/IdentifierX509CreateInput' + type: object nullable: true registrationExtension: allOf: - $ref: '#/components/schemas/IdentifierRegistrationCreateInput' + type: object nullable: true electronicExtension: allOf: - $ref: '#/components/schemas/IdentifierElectronicCreateInput' + type: object nullable: true example: identifierType: "email" diff --git a/kms-openapi.yml b/kms-openapi.yml index c4ba266..2961e6c 100644 --- a/kms-openapi.yml +++ b/kms-openapi.yml @@ -198,6 +198,9 @@ paths: application/json: schema: $ref: '#/components/schemas/GenerateKeyResponse' + examples: + generatedSigningKey: + $ref: '#/components/examples/GenerateSigningKeyResponse' '400': $ref: '#/components/responses/BadRequest' '404': @@ -1727,23 +1730,38 @@ components: description: KMS key assignment id. style: simple example: "assignment-001" + examples: + GenerateSigningKeyRequest: + summary: Generate a tenant signing key + value: + alias: "my-signing-key" + use: "sig" + alg: "ECDSA_SHA256" + keyOperations: [ "sign" ] + GenerateSigningKeyResponse: + summary: Generated tenant signing key + value: + keyPair: + kid: "00-qTBov6GxjPSuMNxnk876cMP0JKjbwl4ZyN_sY2tE" + providerId: "testsoftware" + alias: "my-signing-key" + jose: + publicJwk: + kty: "EC" + kid: "00-qTBov6GxjPSuMNxnk876cMP0JKjbwl4ZyN_sY2tE" + alg: "ES256" + use: "sig" + crv: "P-256" + x: "HFL67WWh6PYWKOy1mzt9Y2ANs-CWFIyVtouR-Jx_mAM" + y: "9f_1x7fwUuEbEwxSNTYE3jQF-zForWpKkEMpiUp1MNI" + cose: + publicCoseKey: + kty: 2 + crv: 1 + alg: -7 + x: "HFL67WWh6PYWKOy1mzt9Y2ANs-CWFIyVtouR-Jx_mAM" + y: "9f_1x7fwUuEbEwxSNTYE3jQF-zForWpKkEMpiUp1MNI" requestBodies: - CreateKeyProviderRequest: - description: Request body for creating a new Key Provider. - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/CreateKeyProvider' - - UpdateKeyProviderRequest: - description: Request body for updating an existing Key Provider. - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/UpdateKeyProvider' - GenerateKeyRequest: description: Request body for generating a new key in a specific provider. required: true @@ -1751,27 +1769,9 @@ components: application/json: schema: $ref: '#/components/schemas/GenerateKey' - example: - alias: "my-signing-key" - use: "sig" - alg: "ECDSA_SHA256" - keyOperations: [ "sign" ] - - CreateSimpleSignatureRequest: - description: Request body for creating a digital signature. - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/CreateSimpleSignature' - - VerifySimpleSignatureRequest: - description: Request body for verifying a digital signature. - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/VerifySimpleSignature' + examples: + generateSigningKey: + $ref: '#/components/examples/GenerateSigningKeyRequest' CreateRawSignatureRequest: description: > @@ -2742,29 +2742,6 @@ components: $ref: './kms-components.yml#/components/schemas/AzureKeyVaultSetting' CoseKeyPair: $ref: './kms-components.yml#/components/schemas/CoseKeyPair' - CreateKeyProvider: - description: Request body for creating a new Key Provider instance. - type: object - required: - - type - properties: - type: - $ref: '#/components/schemas/KeyProviderType' - azureKeyvaultSettings: - $ref: '#/components/schemas/AzureKeyVaultSetting' - awsKmsSettings: - $ref: '#/components/schemas/AwsKmsSetting' - cacheEnabled: - type: boolean - description: Whether to enable caching for keys retrieved from this provider. - default: false - cacheTTLInSeconds: - type: integer - format: int32 - description: Time-to-live for cached keys in seconds (if cacheEnabled is true). - default: 300 - minimum: 0 - CreateRawSignature: description: Request body for creating a raw signature. type: object @@ -2780,20 +2757,6 @@ components: description: The bytes to sign, base64-encoded. The example is the string "hello". example: "aGVsbG8=" - CreateSimpleSignature: - description: Request body for creating a digital signature. - type: object - required: - - signInput - - keyInfo - properties: - signInput: - $ref: '#/components/schemas/SignInput' - keyInfo: - $ref: '#/components/schemas/KeyInfo' - signatureAlgorithm: - $ref: '#/components/schemas/SignatureAlgorithm' - CryptoAlg: $ref: './kms-components.yml#/components/schemas/CryptoAlg' Curve: @@ -3806,23 +3769,6 @@ components: description: Optional boolean indicating whether the X.509 certificate chain should be verified. default: false - UpdateKeyProvider: - description: Request body for updating an existing Key Provider instance. - type: object - properties: - azureKeyvaultSettings: - $ref: '#/components/schemas/AzureKeyVaultSetting' - awsKmsSettings: - $ref: '#/components/schemas/AwsKmsSetting' - cacheEnabled: - type: boolean - description: Whether to enable caching for keys retrieved from this provider. - cacheTTLInSeconds: - type: integer - format: int32 - description: Time-to-live for cached keys in seconds (if cacheEnabled is true). - minimum: 0 - VerifyRawSignature: description: Request body for verifying a raw signature. type: object @@ -3844,18 +3790,6 @@ components: description: The signature to verify, base64-encoded (as returned by POST /signatures/raw/create). example: "ZXhhbXBsZS1zaWduYXR1cmUtYnl0ZXM=" - VerifySimpleSignature: - description: Request body for verifying a digital signature. - type: object - required: - - signInput - - signature - properties: - signInput: - $ref: '#/components/schemas/SignInput' - signature: - $ref: '#/components/schemas/Signature' - Resolver: $ref: './kms-components.yml#/components/schemas/Resolver' KeyResolver: diff --git a/license-portal-openapi.yaml b/license-portal-openapi.yaml index a53f437..effcd18 100644 --- a/license-portal-openapi.yaml +++ b/license-portal-openapi.yaml @@ -1637,44 +1637,6 @@ components: type: array items: $ref: '#/components/schemas/IssuedLicenseSummary' - LicenseDownloadResult: - type: object - required: [licenseId, fileName, contentType, digest] - properties: - licenseId: - type: string - fileName: - type: string - contentType: - type: string - digest: - type: string - platformCertificate: - $ref: '#/components/schemas/ImportedPlatformLicenseRequestCertificate' - licenseRootCaPem: - type: string - customerPartyInfo: - $ref: '#/components/schemas/LicenseBundleCustomerPartyInfo' - LicenseBundleCustomerPartyInfo: - type: object - required: [schema, licenseId, customerPartyId, customerName, softwarePartyId, installationId, installationName] - properties: - schema: - type: string - licenseId: - type: string - customerPartyId: - type: string - customerName: - type: string - softwarePartyId: - type: string - installationId: - type: string - installationName: - type: string - installationBaseDomain: - type: string RevokeLicenseArgs: type: object properties: diff --git a/oid4vci-issuance-template-openapi.yml b/oid4vci-issuance-template-openapi.yml index 9e4cb2c..45bad64 100644 --- a/oid4vci-issuance-template-openapi.yml +++ b/oid4vci-issuance-template-openapi.yml @@ -51,6 +51,9 @@ paths: application/json: schema: $ref: '#/components/schemas/CreateIssuanceTemplateRequest' + examples: + createEmployeeBadgeTemplate: + $ref: '#/components/examples/CreateEmployeeBadgeIssuanceTemplateRequest' responses: '201': description: Created issuance template. @@ -58,6 +61,9 @@ paths: application/json: schema: $ref: '#/components/schemas/IssuanceTemplateRecord' + examples: + employeeBadgeTemplate: + $ref: '#/components/examples/EmployeeBadgeIssuanceTemplateRecord' '400': $ref: './common-components.yml#/components/responses/ValidationError' @@ -163,6 +169,54 @@ components: refreshUrl: http://localhost:8082/realms/oid4vci/protocol/openid-connect/token scopes: {} + examples: + CreateEmployeeBadgeIssuanceTemplateRequest: + summary: Create an employee badge issuance template + value: + issuerId: "hr-issuer" + name: "Employee onboarding" + description: "Pre-authorized offer used by the HR onboarding kiosk." + enabled: true + spec: + credential_configuration_ids: + - "EmployeeBadge" + credential_designs: + - designId: "7a4fd7c3-4c15-4fe7-936e-39ecbb9f3440" + version: 2 + offer_defaults: + grants: + pre_authorized_code: + tx_code: + input_mode: "numeric" + length: 6 + description: "PIN sent by email" + ttl_seconds: 600 + EmployeeBadgeIssuanceTemplateRecord: + summary: Stored employee badge issuance template + value: + id: "0f4b9837-1d5b-4ef4-a16d-2f504c54e4a1" + tenantId: "tenant-acme" + issuerId: "hr-issuer" + name: "Employee onboarding" + description: "Pre-authorized offer used by the HR onboarding kiosk." + enabled: true + spec: + credential_configuration_ids: + - "EmployeeBadge" + credential_designs: + - designId: "7a4fd7c3-4c15-4fe7-936e-39ecbb9f3440" + version: 2 + offer_defaults: + grants: + pre_authorized_code: + tx_code: + input_mode: "numeric" + length: 6 + description: "PIN sent by email" + ttl_seconds: 600 + createdAt: "2026-06-20T09:00:00Z" + updatedAt: "2026-06-25T14:30:00Z" + schemas: CredentialDesignVersionRef: type: object diff --git a/oid4vp-universal-openapi.yml b/oid4vp-universal-openapi.yml index 72d00f9..132c42a 100644 --- a/oid4vp-universal-openapi.yml +++ b/oid4vp-universal-openapi.yml @@ -276,34 +276,6 @@ components: type: string description: Identifier of the verifier instance that owns this request. Used in multi-verifier deployments. - DeleteAuthorizationRequest: - type: object - required: [correlation_id, query_id] - properties: - correlation_id: - type: string - description: Unique identifier for the session - example: 2cc29d1c-7d00-46f8-b0ae-b4779d2ff143 - query_id: - type: string - description: Identifier for the presentation definition that specifies which credentials are required - example: ExampleSdJwtId - - AuthorizationStatusRequest: - type: object - required: [correlation_id, query_id] - properties: - correlation_id: - type: string - description: Unique identifier for the session - example: 2cc29d1c-7d00-46f8-b0ae-b4779d2ff143 - query_id: - type: string - description: Identifier for the presentation definition that specifies which credentials are required - example: ExampleSdJwtId - verified_data: - $ref: '#/components/schemas/VerifiedDataOpts' - VerifiedDataOpts: $ref: './oid4vp-universal-components.yml#/components/schemas/VerifiedDataOpts' diff --git a/oid4vp-verification-template-openapi.yml b/oid4vp-verification-template-openapi.yml index 026699c..3e72845 100644 --- a/oid4vp-verification-template-openapi.yml +++ b/oid4vp-verification-template-openapi.yml @@ -51,6 +51,9 @@ paths: application/json: schema: $ref: '#/components/schemas/CreateVerificationTemplateRequest' + examples: + createAgeCheckTemplate: + $ref: '#/components/examples/CreateAgeCheckVerificationTemplateRequest' responses: '201': description: Created verification template. @@ -58,6 +61,9 @@ paths: application/json: schema: $ref: '#/components/schemas/VerificationTemplateRecord' + examples: + ageCheckTemplate: + $ref: '#/components/examples/AgeCheckVerificationTemplateRecord' /templates/verification/{templateId}: parameters: @@ -161,6 +167,46 @@ components: refreshUrl: http://localhost:8082/realms/oid4vp/protocol/openid-connect/token scopes: {} + examples: + CreateAgeCheckVerificationTemplateRequest: + summary: Create an age-check verification template + value: + verifierId: "age-verifier" + name: "Age over 18" + description: "Reusable verification request for age checks." + enabled: true + spec: + queryRef: + verifierId: "age-verifier" + bindingId: "3df31016-674f-4828-a384-b9acb9d7d346" + queryId: "age-over-18" + version: 1 + verifierDesignId: "97bd1d9d-1390-4c59-a57f-76d7a0e7e913" + request_defaults: + response_mode: "direct_post" + purpose: "Verify the holder is over 18." + AgeCheckVerificationTemplateRecord: + summary: Stored age-check verification template + value: + id: "db24f53b-ea2d-4432-82df-4188f977b2a6" + tenantId: "tenant-acme" + verifierId: "age-verifier" + name: "Age over 18" + description: "Reusable verification request for age checks." + enabled: true + spec: + queryRef: + verifierId: "age-verifier" + bindingId: "3df31016-674f-4828-a384-b9acb9d7d346" + queryId: "age-over-18" + version: 1 + verifierDesignId: "97bd1d9d-1390-4c59-a57f-76d7a0e7e913" + request_defaults: + response_mode: "direct_post" + purpose: "Verify the holder is over 18." + createdAt: "2026-06-20T09:00:00Z" + updatedAt: "2026-06-25T14:30:00Z" + schemas: VerificationTemplateQueryRef: type: object diff --git a/platform-admin-openapi.yaml b/platform-admin-openapi.yaml index 980385c..4ab2514 100644 --- a/platform-admin-openapi.yaml +++ b/platform-admin-openapi.yaml @@ -107,9 +107,9 @@ paths: application/json: schema: $ref: '#/components/schemas/ApplicationTenantBootstrapRequest' - example: - operatorEmail: admin@acme.example - operatorDisplayName: Acme Administrator + examples: + applicationTenantBootstrap: + $ref: '#/components/examples/ApplicationTenantBootstrapRequest' responses: '200': description: Application tenant bootstrap or reconcile result. @@ -117,14 +117,9 @@ paths: application/json: schema: $ref: '#/components/schemas/ApplicationTenantStatus' - example: - tenantId: application - status: ACTIVE - hostedAs: - required: true - available: true - issuerUrl: https://auth.platform.example - canRegisterFirstRealTenant: true + examples: + applicationTenantStatus: + $ref: '#/components/examples/ApplicationTenantStatus' '401': $ref: '#/components/responses/Unauthorized' '403': @@ -1584,6 +1579,22 @@ components: code: RATE_LIMITED message: Too many signup attempts. Try again later. correlationId: 7f12a7c4-1b6d-4038-9a4c-2f9a4c7e1b6d + examples: + ApplicationTenantBootstrapRequest: + summary: Seed the initial platform operator + value: + operatorEmail: admin@acme.example + operatorDisplayName: Acme Administrator + ApplicationTenantStatus: + summary: Application tenant ready for tenant registration + value: + tenantId: application + status: ACTIVE + hostedAs: + required: true + available: true + issuerUrl: https://auth.platform.example + canRegisterFirstRealTenant: true schemas: # ---- PlatformAdmin entity schemas (externalized) ---- ApplicationTenantStatus: diff --git a/redocly.yaml b/redocly.yaml index 3ae0842..0d6e0c4 100644 --- a/redocly.yaml +++ b/redocly.yaml @@ -103,9 +103,9 @@ rules: operation-operationId-unique: error # Deferred to the normalization pass, surfaced, not blocking - struct: warn - no-invalid-parameter-examples: warn - no-invalid-media-type-examples: warn + struct: error + no-invalid-parameter-examples: error + no-invalid-media-type-examples: error no-example-value-and-externalValue: warn operation-4xx-response: off operation-2xx-response: off diff --git a/resource-manager-openapi.yml b/resource-manager-openapi.yml index b3334ff..7fcfa2b 100644 --- a/resource-manager-openapi.yml +++ b/resource-manager-openapi.yml @@ -12,6 +12,10 @@ info: retirement, verification, and cancellation. servers: - url: http://localhost:5011/api/booking/v1 + +security: + - bearer: [] + tags: - name: Resources description: Resource lifecycle and availability. @@ -1187,6 +1191,9 @@ paths: '404': $ref: './common-components.yml#/components/responses/NotFound' components: + securitySchemes: + bearer: + $ref: './common-components.yml#/components/securitySchemes/bearer' parameters: ResourceId: $ref: './resource-manager-components.yml#/components/parameters/ResourceId' diff --git a/semantic-binding-components.yml b/semantic-binding-components.yml index 25cca14..0cfada1 100644 --- a/semantic-binding-components.yml +++ b/semantic-binding-components.yml @@ -224,6 +224,7 @@ components: profileRelationRef: allOf: - $ref: '#/components/schemas/ProfileRelationRef' + type: object nullable: true description: Optional reference to the profile relation this instance realizes. createdAt: @@ -388,6 +389,7 @@ components: transform: allOf: - $ref: '#/components/schemas/AttributeTransform' + type: object nullable: true SourceEntityBinding: diff --git a/semantic-binding-openapi.yml b/semantic-binding-openapi.yml index 2a578c0..8e1eeca 100644 --- a/semantic-binding-openapi.yml +++ b/semantic-binding-openapi.yml @@ -938,6 +938,7 @@ components: profileRelationRef: allOf: - $ref: '#/components/schemas/ProfileRelationRef' + type: object nullable: true subjectPartyType: type: string @@ -970,6 +971,7 @@ components: profileRelationRef: allOf: - $ref: '#/components/schemas/ProfileRelationRef' + type: object nullable: true subjectPartyType: type: string diff --git a/semantic-model-authoring-components.yml b/semantic-model-authoring-components.yml index d5d9c33..3e38b22 100644 --- a/semantic-model-authoring-components.yml +++ b/semantic-model-authoring-components.yml @@ -162,11 +162,13 @@ components: The selected traversal path this override applies to. Together with `roleRef` it must match one of the set's `selected` entries. conformance: + type: string allOf: - $ref: '#/components/schemas/SetConformance' nullable: true description: Overrides the profile member's conformance (mandatory vs optional). cardinality: + type: object allOf: - $ref: '#/components/schemas/SetCardinality' nullable: true @@ -423,13 +425,7 @@ components: occurrence overlay; date-vs-time-vs-datetime precision rides the `formatHint` ISO 8601 pattern on top of `DateTime`, it is not a value type. pattern: '^\[*(Text|Numeric|Boolean|Binary|DateTime|Reference)\]*$' - examples: - - Text - - DateTime - - Reference - - '[Text]' - - '[[Numeric]]' - - '[Reference]' + example: Text AttributeWidgetHint: type: string @@ -612,6 +608,7 @@ components: selective-disclosure / widget extension overlays. default: {} entityType: + type: string allOf: - $ref: '#/components/schemas/SemanticAttributeEntityType' nullable: true @@ -623,6 +620,7 @@ components: items: $ref: '#/components/schemas/SemanticAttribute' entryCodeScheme: + type: object allOf: - $ref: '#/components/schemas/SkosConceptSchemeReference' nullable: true @@ -658,11 +656,13 @@ components: information: "The holder's date of birth in ISO 8601 format" properties: cardinality: + type: object allOf: - $ref: '#/components/schemas/AttributeCardinality' nullable: true description: Occurrence range overlay; absent means the OCA-default single occurrence. conformance: + type: string allOf: - $ref: '#/components/schemas/Conformance' nullable: true @@ -672,6 +672,7 @@ components: nullable: true description: Format pattern overlay (e.g. an ISO 8601 pattern or a regex such as `^[A-Z]{2}$`). entryCodes: + type: object allOf: - $ref: '#/components/schemas/EntryCodes' nullable: true @@ -703,11 +704,13 @@ components: nullable: true description: Whether the attribute holds sensitive data that should be masked in UIs. widgetHint: + type: string allOf: - $ref: '#/components/schemas/AttributeWidgetHint' nullable: true description: The preferred capture widget (extension overlay). sdPolicy: + type: string allOf: - $ref: '#/components/schemas/SdPolicy' nullable: true @@ -811,6 +814,7 @@ components: nullable: true description: Optional handle into the schema registry, when the schema is registered there. schemaType: + type: string allOf: - $ref: '#/components/schemas/SchemaType' nullable: true @@ -953,6 +957,7 @@ components: - $ref: '#/components/schemas/MappingDirection' default: BIDIRECTIONAL equivalence: + type: string allOf: - $ref: '#/components/schemas/EquivalenceStrength' nullable: true @@ -965,6 +970,7 @@ components: type: string nullable: true transform: + type: object allOf: - $ref: '#/components/schemas/AttributeTransform' nullable: true @@ -1069,6 +1075,7 @@ components: The platform party-type this PREDEFINED entity maps to (e.g. natural_person, organization, address). Only meaningful on a PREDEFINED root; must be absent on a SPECIALIZATION. specializes: + type: object allOf: - $ref: '#/components/schemas/EntityRef' nullable: true @@ -1133,6 +1140,7 @@ components: entity: type: string catalog: + type: object allOf: - $ref: '#/components/schemas/CatalogRef' nullable: true @@ -1158,6 +1166,7 @@ components: nullable: true description: Optional role label for this end; null means no role is declared. cardinality: + type: object allOf: - $ref: '#/components/schemas/AttributeCardinality' nullable: true @@ -1250,6 +1259,7 @@ components: type: string nullable: true specializes: + type: object allOf: - $ref: '#/components/schemas/EntityRef' nullable: true @@ -1681,6 +1691,7 @@ components: additionalProperties: $ref: '#/components/schemas/CatalogMetaText' governance: + type: object allOf: - $ref: '#/components/schemas/CatalogGovernance' nullable: true @@ -1735,6 +1746,7 @@ components: type: string nullable: true controller: + type: object allOf: - $ref: '#/components/schemas/GovernanceController' nullable: true @@ -1744,10 +1756,12 @@ components: items: type: string nis2: + type: object allOf: - $ref: '#/components/schemas/Nis2Classification' nullable: true mica: + type: object allOf: - $ref: '#/components/schemas/MicaClassification' nullable: true @@ -1774,10 +1788,12 @@ components: type: string nullable: true residency: + type: object allOf: - $ref: '#/components/schemas/JurisdictionResidency' nullable: true defaultTransfer: + type: object allOf: - $ref: '#/components/schemas/JurisdictionTransfer' nullable: true @@ -1940,16 +1956,19 @@ components: type: string description: The fully-qualified attribute path within that role's entity. conformance: + type: string allOf: - $ref: '#/components/schemas/Conformance' nullable: true description: Overrides the attribute's mandatory/optional conformance for the use case. sdPolicy: + type: string allOf: - $ref: '#/components/schemas/SdPolicy' nullable: true description: Overrides the attribute's selective-disclosure policy. cardinality: + type: object allOf: - $ref: '#/components/schemas/AttributeCardinality' nullable: true @@ -1965,6 +1984,7 @@ components: nullable: true description: Tightens the attribute's sensitivity (false -> true only). retention: + type: object allOf: - $ref: '#/components/schemas/RetentionPolicy' nullable: true @@ -2212,12 +2232,14 @@ components: relation: $ref: '#/components/schemas/SchemaAttributeRelation' equivalence: + type: string allOf: - $ref: '#/components/schemas/EquivalenceStrength' nullable: true direction: $ref: '#/components/schemas/MappingDirection' transform: + type: object allOf: - $ref: '#/components/schemas/AttributeTransform' nullable: true diff --git a/semantic-model-authoring-openapi.yml b/semantic-model-authoring-openapi.yml index ac3bf9f..174e92d 100644 --- a/semantic-model-authoring-openapi.yml +++ b/semantic-model-authoring-openapi.yml @@ -2524,10 +2524,12 @@ components: type: string nullable: true ownerPartyRef: + type: string allOf: - $ref: '#/components/schemas/PartyRef' nullable: true overlays: + type: object allOf: - $ref: '#/components/schemas/CatalogOverlays' nullable: true @@ -3166,6 +3168,7 @@ components: items: $ref: '#/components/schemas/VcClaimMapping' brandingRef: + type: object allOf: - $ref: '#/components/schemas/BrandingRef' nullable: true diff --git a/semantic-vocabulary-openapi.yml b/semantic-vocabulary-openapi.yml index 33cc74d..c1dea6d 100644 --- a/semantic-vocabulary-openapi.yml +++ b/semantic-vocabulary-openapi.yml @@ -461,6 +461,7 @@ components: sourceFormat: allOf: - $ref: '#/components/schemas/SemanticVocabularySourceFormat' + type: string nullable: true description: Required when `content` is non-null; the format of the supplied content. diff --git a/software-manager-openapi.yml b/software-manager-openapi.yml index 20d957e..5abb4b2 100644 --- a/software-manager-openapi.yml +++ b/software-manager-openapi.yml @@ -13,6 +13,9 @@ info: servers: - url: http://localhost:8080/api/services/v1 +security: + - bearer: [] + paths: /services/instances: get: @@ -827,6 +830,9 @@ paths: description: Deleted. components: + securitySchemes: + bearer: + $ref: './common-components.yml#/components/securitySchemes/bearer' schemas: DeploymentListResponse: type: object diff --git a/statuslist-management-openapi.yml b/statuslist-management-openapi.yml index 0957ad5..14979be 100644 --- a/statuslist-management-openapi.yml +++ b/statuslist-management-openapi.yml @@ -35,21 +35,9 @@ paths: application/json: schema: $ref: '#/components/schemas/CreateStatusListArgs' - example: - correlationId: "employee-revocation-2026" - spec: "token_status_list" - purposes: - - "revocation" - proofFormat: "jwt" - hostingMode: "hosted" - issuer: "did:web:issuer.example.com" - statusListUri: "https://issuer.example.com/public/statuslists/employee-revocation-2026" - length: 131072 - bitsPerStatus: 1 - signingKeyAlias: "issuer-statuslist-signing" - signingKeyMode: "did:web" - signingVerificationMethodId: "did:web:issuer.example.com#statuslist-key-1" - ttlSeconds: 300 + examples: + createHostedStatusList: + $ref: '#/components/examples/CreateHostedStatusListRequest' responses: '201': description: Status list created. @@ -57,20 +45,9 @@ paths: application/json: schema: $ref: '#/components/schemas/StatusListResult' - example: - id: "sl-1" - correlationId: "employee-revocation-2026" - spec: "token_status_list" - purposes: - - "revocation" - proofFormat: "jwt" - hostingMode: "hosted" - bitsPerStatus: 1 - length: 131072 - issuer: "did:web:issuer.example.com" - statusListUri: "https://issuer.example.com/public/statuslists/employee-revocation-2026" - signedToken: "eyJhbGciOiJFUzI1NiIsImtpZCI6Ii4uLiJ9.eyJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsdCI6MTMxMDcyLCJsdCI6W119fQ.signature" - contentType: "application/statuslist+jwt" + examples: + hostedStatusList: + $ref: '#/components/examples/HostedStatusListResult' '400': $ref: './common-components.yml#/components/responses/ValidationError' '401': @@ -136,28 +113,9 @@ paths: application/json: schema: $ref: '#/components/schemas/StatusListSummaryPageResponse' - example: - data: - - id: "sl-1" - correlationId: "employee-revocation-2026" - spec: "token_status_list" - purposes: - - "revocation" - proofFormat: "jwt" - bitsPerStatus: 1 - length: 131072 - issuedCount: 3 - remainingCapacity: 131069 - createdAt: "2026-06-06T09:00:00Z" - updatedAt: "2026-06-06T09:00:00Z" - pagination: - limit: 20 - offset: 0 - page: 0 - size: 20 - total: 1 - totalPages: 1 - hasMore: false + examples: + statusListSummaryPage: + $ref: '#/components/examples/StatusListSummaryPage' '400': $ref: './common-components.yml#/components/responses/ValidationError' '401': @@ -311,6 +269,66 @@ components: StatusListId: $ref: './statuslist-management-components.yml#/components/parameters/StatusListId' + examples: + CreateHostedStatusListRequest: + summary: Create a hosted revocation status list + value: + correlationId: "employee-revocation-2026" + spec: "token_status_list" + purposes: + - "revocation" + proofFormat: "jwt" + hostingMode: "hosted" + issuer: "did:web:issuer.example.com" + statusListUri: "https://issuer.example.com/public/statuslists/employee-revocation-2026" + length: 131072 + bitsPerStatus: 1 + signingKeyAlias: "issuer-statuslist-signing" + signingKeyMode: "did:web" + signingVerificationMethodId: "did:web:issuer.example.com#statuslist-key-1" + ttlSeconds: 300 + HostedStatusListResult: + summary: Hosted revocation status list + value: + id: "sl-1" + correlationId: "employee-revocation-2026" + spec: "token_status_list" + purposes: + - "revocation" + proofFormat: "jwt" + hostingMode: "hosted" + bitsPerStatus: 1 + length: 131072 + issuer: "did:web:issuer.example.com" + statusListUri: "https://issuer.example.com/public/statuslists/employee-revocation-2026" + signedToken: "eyJhbGciOiJFUzI1NiIsImtpZCI6Ii4uLiJ9.eyJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsdCI6MTMxMDcyLCJsdCI6W119fQ.signature" + contentType: "application/statuslist+jwt" + StatusListSummaryPage: + summary: Page of status-list summaries + value: + data: + - id: "sl-1" + correlationId: "employee-revocation-2026" + spec: "token_status_list" + purposes: + - "revocation" + proofFormat: "jwt" + hostingMode: "hosted" + bitsPerStatus: 1 + length: 131072 + issuedCount: 3 + remainingCapacity: 131069 + createdAt: "2026-06-06T09:00:00Z" + updatedAt: "2026-06-06T09:00:00Z" + pagination: + limit: 20 + offset: 0 + page: 0 + size: 20 + total: 1 + totalPages: 1 + hasMore: false + schemas: # -- Re-exported entity schemas and enums from statuslist-management-components.yml -- StatusListSpec: diff --git a/user-manager-openapi.yml b/user-manager-openapi.yml index a4e6f27..03037d5 100644 --- a/user-manager-openapi.yml +++ b/user-manager-openapi.yml @@ -10,6 +10,10 @@ info: information used by operational user-management screens. servers: - url: http://localhost:8091/api/users/v1 + +security: + - bearer: [] + tags: - name: Users description: User lifecycle, role assignment, group membership, and tenant access. @@ -765,6 +769,9 @@ paths: $ref: './common-components.yml#/components/responses/NotFound' components: + securitySchemes: + bearer: + $ref: './common-components.yml#/components/securitySchemes/bearer' parameters: # -- Re-exported path parameters from user-manager-components.yml -- UserId: From 23a6ece5e8b08f1a3b9cbce306d2f02f56b6d92f Mon Sep 17 00:00:00 2001 From: Niels Klomp Date: Sun, 5 Jul 2026 19:41:37 +0200 Subject: [PATCH 6/8] chore: fixes --- attribute-source-components.yml | 491 ------------------ attribute-source-openapi.yml | 430 ---------------- command-types.json | 692 -------------------------- connector-components.yml | 206 +++++++- connector-integration-openapi.yml | 240 +++++++-- connector-openapi.yml | 2 +- credential-design-openapi.yml | 16 - docs-groups.json | 3 +- manifest-catalog.json | 2 - oid4vci-issuer-components.yml | 355 +++++++++---- oid4vci-issuer-openapi.yaml | 127 +++-- oid4vci-issuer-session-components.yml | 52 -- oid4vci-issuer-session-openapi.yml | 3 - platform-admin-components.yml | 43 +- platform-admin-openapi.yaml | 388 +++++++++++---- redocly.yaml | 2 - semantic-binding-components.yml | 8 +- semantic-binding-openapi.yml | 12 +- 18 files changed, 1017 insertions(+), 2055 deletions(-) delete mode 100644 attribute-source-components.yml delete mode 100644 attribute-source-openapi.yml delete mode 100644 command-types.json diff --git a/attribute-source-components.yml b/attribute-source-components.yml deleted file mode 100644 index a59774d..0000000 --- a/attribute-source-components.yml +++ /dev/null @@ -1,491 +0,0 @@ -# ============================================================================ -# Reusable schemas, enums, and parameters for the Attribute Source API. -# -# The attribute-source-openapi.yml root re-exports the entity schemas it needs -# as thin stubs and references these definitions. Shared errors, bearer auth, -# and query pagination parameters live in ./common-components.yml. -# -# Every schema here is grounded in the Kotlin DTOs from the EDK attribute-source -# public module (package com.sphereon.attribute.source). Field names, -# nullability, defaults, and enum values match the serializable data classes. -# ============================================================================ -openapi: 3.0.4 -info: - title: Attribute Source API - Components - version: 0.1.0 - description: Reusable component schemas for tenant-scoped EDK attribute-source definitions exposed by VDX. -paths: {} -components: - parameters: - SourceId: - name: sourceId - in: path - required: true - description: | - Stable EDK attribute-source id. This is the same value used by - `AttributeSourceBinding.sourceInstanceId` in issuer pipeline configuration. - schema: - type: string - example: hr-workday-profile - - schemas: - # ---- Enums -------------------------------------------------------------- - - AttributeSourceKind: - type: string - description: | - Connector family for the source definition. - - `REST_API`: a JSON REST integration with a service-specific endpoint contract. - - `HTTP`: a generic HTTP source where the concrete verb, path, or payload is configured elsewhere. - - `DATABASE`: a relational or queryable store reached through EDK or a remote connector. - - `TABULAR`: a CSV, spreadsheet, batch roster, or other row/column input. - - `VAULT`: a secret or claims vault integration. - - `IAM`: an identity and access management directory or user-info source. - enum: [REST_API, DATABASE, TABULAR, VAULT, IAM, HTTP] - - AttributeSourceLifecycleStatus: - type: string - description: | - Operational status of the source. - - `ACTIVE`: available for new or existing pipeline bindings. - - `SUSPENDED`: retained in the registry but should not be selected for new runs. - - `DECOMMISSIONED`: kept for audit or documentation only. - enum: [ACTIVE, SUSPENDED, DECOMMISSIONED] - - AttributeSourceManagementMode: - type: string - description: | - Who owns the source integration lifecycle. - - `MANAGED`: VDX/EDK owns the integration configuration and lifecycle. - - `EXTERNAL`: the source is operated by another system and only referenced here. - - `HYBRID`: VDX/EDK owns registry metadata while another service owns the runtime connector. - enum: [MANAGED, EXTERNAL, HYBRID] - - AttributeSourceRuntimeMode: - type: string - description: | - Where runtime lookups are expected to execute. - - `VDX_MANAGED`: executed by the VDX deployment. - - `REMOTE_EDK`: executed by a connected EDK runtime. - - `THIRD_PARTY`: executed by a third-party system addressed through a connector reference. - enum: [VDX_MANAGED, REMOTE_EDK, THIRD_PARTY] - - # ---- Source contract ---------------------------------------------------- - - ProducedAttribute: - type: object - description: | - One logical attribute the source can produce. `path` is the pipeline-facing or - credential-facing attribute path. `nativeName` records the field name as it appears in the - source system, so a profile claim such as `employee.givenName` can be traced back to - `first_name` in an HR API response. - required: [path] - example: - path: employee.givenName - nativeName: first_name - nativeType: string - label: Given name - properties: - path: - type: string - description: Logical attribute path used by the pipeline and optional semantic binding. - example: employee.givenName - nativeName: - type: string - nullable: true - description: Field, column, claim, or JSON property name in the source system. - example: first_name - nativeType: - type: string - nullable: true - description: Source-native value type, for example `string`, `varchar`, `date`, or `boolean`. - example: string - label: - type: string - nullable: true - description: Human-readable label for documentation and operator views. - example: Given name - - AttributeSourceConnectionRef: - type: object - description: | - Reference to connection material. Endpoint locations and configuration namespaces may be - recorded here, but credentials and secrets are never inlined. Runtime connectors resolve - `configKeyPrefix` through the deployment's configuration or secret store. - example: - endpointUrl: https://hr.example.com/api/employees - configKeyPrefix: attribute-source.hr-workday - backingSourceId: workday.employee-profile - properties: - endpointUrl: - type: string - nullable: true - format: uri - description: Endpoint template or base URL for the integration when exposing it is safe. - example: https://hr.example.com/api/employees - configKeyPrefix: - type: string - nullable: true - description: Prefix used by the runtime connector to resolve credentials and non-public settings. - example: attribute-source.hr-workday - backingSourceId: - type: string - nullable: true - description: Connector-specific backing id, such as a table, view, dataset, or upstream source name. - example: workday.employee-profile - - AttributeSourceDefinition: - type: object - description: | - Persisted tenant-scoped source definition returned by the EDK attribute-source registry. - The REST layer obtains tenant context from the session; the `tenantId` in the response is - assigned by the command implementation. - required: - - sourceId - - tenantId - - displayName - - kind - - lifecycleStatus - - managementMode - - consumedLookupKeys - - producedAttributes - - createdAt - - updatedAt - example: - sourceId: hr-workday-profile - tenantId: acme - displayName: Workday profile lookup - description: Resolves employee credential claims from the HR profile API by employee_id. - kind: REST_API - lifecycleStatus: ACTIVE - managementMode: EXTERNAL - runtimeMode: THIRD_PARTY - consumedLookupKeys: [employee_id] - producedAttributes: - - path: employee.givenName - nativeName: first_name - nativeType: string - label: Given name - - path: employee.familyName - nativeName: last_name - nativeType: string - label: Family name - - path: employment.department - nativeName: department_code - nativeType: string - label: Department - connectionRef: - endpointUrl: https://hr.example.com/api/employees - configKeyPrefix: attribute-source.hr-workday - createdAt: '2026-06-10T08:30:00Z' - updatedAt: '2026-06-10T08:30:00Z' - properties: - sourceId: - type: string - description: Stable source id used by registry lookups and pipeline bindings. - example: hr-workday-profile - tenantId: - type: string - description: Tenant that owns this source definition. - example: acme - displayName: - type: string - description: Operator-facing source name. - example: Workday profile lookup - description: - type: string - nullable: true - description: Short explanation of what the source contributes and when it is used. - kind: - $ref: '#/components/schemas/AttributeSourceKind' - lifecycleStatus: - $ref: '#/components/schemas/AttributeSourceLifecycleStatus' - managementMode: - $ref: '#/components/schemas/AttributeSourceManagementMode' - runtimeMode: - description: Runtime execution location. Optional in the Kotlin DTO and may be omitted when unknown. - $ref: '#/components/schemas/AttributeSourceRuntimeMode' - consumedLookupKeys: - type: array - description: Lookup keys the pipeline must provide before this source can be queried. - items: - type: string - example: [employee_id] - producedAttributes: - type: array - description: Attribute contract exposed to pipeline steps and optional semantic bindings. - items: - $ref: '#/components/schemas/ProducedAttribute' - connectionRef: - description: Optional pointer to endpoint and connector configuration material. - $ref: '#/components/schemas/AttributeSourceConnectionRef' - createdAt: - type: string - format: date-time - description: Registry creation timestamp assigned by the command implementation. - updatedAt: - type: string - format: date-time - description: Last registry update timestamp assigned by the command implementation. - - CreateAttributeSourceRequest: - type: object - description: | - Input for creating an attribute source. Maps directly to `CreateAttributeSourceArgs`. - Defaults are applied by the Kotlin DTO: `managementMode` defaults to `EXTERNAL`, - `consumedLookupKeys` and `producedAttributes` default to empty lists, and `runtimeMode` and - `connectionRef` may be omitted. - required: [displayName, kind] - example: - sourceId: hr-workday-profile - displayName: Workday profile lookup - description: Resolves employee credential claims from the HR profile API by employee_id. - kind: REST_API - managementMode: EXTERNAL - runtimeMode: THIRD_PARTY - consumedLookupKeys: [employee_id] - producedAttributes: - - path: employee.givenName - nativeName: first_name - nativeType: string - label: Given name - - path: employee.familyName - nativeName: last_name - nativeType: string - label: Family name - connectionRef: - endpointUrl: https://hr.example.com/api/employees - configKeyPrefix: attribute-source.hr-workday - properties: - sourceId: - type: string - nullable: true - description: Optional caller-chosen id. Omit to let the command assign one. - example: hr-workday-profile - displayName: - type: string - description: Operator-facing source name. - example: Workday profile lookup - description: - type: string - nullable: true - description: Short explanation of what the source contributes and when it is used. - kind: - $ref: '#/components/schemas/AttributeSourceKind' - managementMode: - $ref: '#/components/schemas/AttributeSourceManagementMode' - runtimeMode: - description: Runtime execution location. Optional in the Kotlin DTO and may be omitted when unknown. - $ref: '#/components/schemas/AttributeSourceRuntimeMode' - consumedLookupKeys: - type: array - description: Lookup keys required from session, credential, or upstream pipeline context. - items: - type: string - example: [employee_id] - producedAttributes: - type: array - description: Fields the source can contribute to the pipeline. - items: - $ref: '#/components/schemas/ProducedAttribute' - connectionRef: - description: Optional pointer to endpoint and connector configuration material. - $ref: '#/components/schemas/AttributeSourceConnectionRef' - - UpdateAttributeSourceRequest: - type: object - description: | - Input for updating the mutable fields of an attribute source. Maps directly to - `UpdateAttributeSourceArgs`; omitted fields are left unchanged. The path `{sourceId}` is - authoritative and the REST command copies it into the command args. - example: - description: Resolves employee credential and employment claims from the HR profile API by employee_id. - producedAttributes: - - path: employee.givenName - nativeName: first_name - nativeType: string - label: Given name - - path: employment.jobTitle - nativeName: job_title - nativeType: string - label: Job title - properties: - sourceId: - type: string - description: Ignored when present; the path `sourceId` is authoritative. - example: hr-workday-profile - displayName: - type: string - description: Replacement operator-facing source name. - description: - type: string - nullable: true - description: Replacement source description. - lifecycleStatus: - $ref: '#/components/schemas/AttributeSourceLifecycleStatus' - managementMode: - $ref: '#/components/schemas/AttributeSourceManagementMode' - runtimeMode: - description: Runtime execution location. Optional in the Kotlin DTO and may be omitted when unchanged or unknown. - $ref: '#/components/schemas/AttributeSourceRuntimeMode' - consumedLookupKeys: - type: array - description: Replacement lookup key contract. - items: - type: string - producedAttributes: - type: array - description: Replacement produced-attribute contract. - items: - $ref: '#/components/schemas/ProducedAttribute' - connectionRef: - description: Optional pointer to endpoint and connector configuration material. - $ref: '#/components/schemas/AttributeSourceConnectionRef' - - AttributeSourcePage: - type: object - description: | - Direct serialization of `Page` from - `com.sphereon.core.api.pagination.Page`. This endpoint intentionally does not use the VDX - `data`/`pagination` response envelope because the HTTP command delegates the EDK page - result directly. - required: [items, total_count, limit, offset] - example: - items: - - sourceId: hr-workday-profile - tenantId: acme - displayName: Workday profile lookup - description: Resolves employee credential claims from the HR profile API by employee_id. - kind: REST_API - lifecycleStatus: ACTIVE - managementMode: EXTERNAL - runtimeMode: THIRD_PARTY - consumedLookupKeys: [employee_id] - producedAttributes: - - path: employee.givenName - nativeName: first_name - nativeType: string - label: Given name - connectionRef: - endpointUrl: https://hr.example.com/api/employees - configKeyPrefix: attribute-source.hr-workday - createdAt: '2026-06-10T08:30:00Z' - updatedAt: '2026-06-10T08:30:00Z' - total_count: 1 - limit: 20 - offset: 0 - has_more: false - page_number: 0 - total_pages: 1 - properties: - items: - type: array - description: Attribute sources in this page. - items: - $ref: '#/components/schemas/AttributeSourceDefinition' - total_count: - type: integer - format: int64 - description: Total count of matching sources across all pages. - minimum: 0 - limit: - type: integer - description: Page size used by the command. - minimum: 0 - offset: - type: integer - description: Offset used by the command. - minimum: 0 - has_more: - type: boolean - description: True when more items exist after this page. - page_number: - type: integer - description: Zero-based page number derived from `offset / limit`. - minimum: 0 - total_pages: - type: integer - description: Total number of pages derived from `total_count` and `limit`. - minimum: 0 - - # ---- Semantic bindings ------------------------------------------------- - - SemanticBindingInput: - type: object - description: | - Authored semantic binding for one native source field. The source can operate without these - bindings; when present, they describe what semantic catalog/profile/set attribute a native - field contributes. - required: [attributePath] - example: - catalogId: employee-core - profileId: employee-credential-profile - setId: employment-credential-set - attributePath: employee.givenName - nativeField: first_name - properties: - catalogId: - type: string - nullable: true - description: Semantic catalog id that defines the attribute path. - example: employee-core - profileId: - type: string - nullable: true - description: Profile id when the binding is specific to a credential or use-case profile. - example: employee-credential-profile - setId: - type: string - nullable: true - description: Attribute set id within the profile, when applicable. - example: employment-credential-set - attributePath: - type: string - description: Semantic or profile attribute path contributed by the native field. - example: employee.givenName - nativeField: - type: string - nullable: true - description: Source-native field name that produces the semantic attribute. - example: first_name - - AttributeSourceSemanticBinding: - allOf: - - $ref: '#/components/schemas/SemanticBindingInput' - - type: object - description: Persisted semantic binding with registry identity and timestamps assigned by the command. - required: [bindingId, tenantId, sourceId, createdAt, updatedAt] - properties: - bindingId: - type: string - description: Server-assigned binding id. - example: bnd-hr-first-name - tenantId: - type: string - description: Tenant that owns the binding. - example: acme - sourceId: - type: string - description: Source this binding belongs to. - example: hr-workday-profile - createdAt: - type: string - format: date-time - description: Binding creation timestamp assigned by the command implementation. - example: '2026-06-10T08:45:00Z' - updatedAt: - type: string - format: date-time - description: Last binding update timestamp assigned by the command implementation. - example: '2026-06-10T08:45:00Z' - example: - bindingId: bnd-hr-first-name - tenantId: acme - sourceId: hr-workday-profile - catalogId: employee-core - profileId: employee-credential-profile - setId: employment-credential-set - attributePath: employee.givenName - nativeField: first_name - createdAt: '2026-06-10T08:45:00Z' - updatedAt: '2026-06-10T08:45:00Z' diff --git a/attribute-source-openapi.yml b/attribute-source-openapi.yml deleted file mode 100644 index d0c1c86..0000000 --- a/attribute-source-openapi.yml +++ /dev/null @@ -1,430 +0,0 @@ -openapi: 3.0.4 -info: - title: Attribute Source API - version: 0.1.0 - x-products: [vdx] - description: | - Register the attribute sources that an issuer pipeline can read from when it prepares - credential subject data. The registry is owned by the EDK attribute-source commands - (`CreateAttributeSourceArgs`, `UpdateAttributeSourceArgs`, `ListAttributeSourcesArgs`, and - `SemanticBindingInput`); this VDX API is the product REST facade mounted at - `/api/attribute-source/v1`. - - An attribute source describes a real integration target, not a credential definition. Typical - entries are an HR profile REST endpoint keyed by `employee_id`, an employee directory database - table keyed by `person_id`, or a managed batch file source keyed by `student_number`. The - `sourceId` returned by this API is the value a pipeline binding can place in - `AttributeSourceBinding.sourceInstanceId`, so OID4VCI and other credential pipelines can reuse - the same registered source without introducing an OID4VCI-specific semantic channel. - - The registry deliberately separates three concerns: - - - `kind`, `managementMode`, and `runtimeMode` classify how the source is operated. They do - not contain connector credentials. - - `consumedLookupKeys` and `producedAttributes` document the runtime contract that pipeline - steps rely on: which lookup keys must be available and which fields the source can return. - - `connectionRef` points at endpoint and configuration material. Secrets are referenced by - configuration key prefix and are never sent inline through this API. - - Semantic bindings are optional. A source can be used by a pipeline without semantic metadata; - when bindings are supplied, they describe which catalog/profile/set attribute each native field - contributes. That allows VDX documentation, governance, and service-capability views to explain - the source in the same semantic language as credential designs and credential channels. - - The list endpoint returns the shared EDK `Page` shape directly: - `items`, `total_count`, `limit`, `offset`, plus computed navigation fields emitted by the - serializer. It is not wrapped in a VDX `data`/`pagination` envelope. - contact: - name: Product Engineering - email: support@example.com - url: https://example.com - license: - name: Apache 2.0 - url: https://www.apache.org/licenses/LICENSE-2.0 - -servers: - - url: https://api.example.com/api/attribute-source/v1 - description: Production server. - - url: http://localhost:8080/api/attribute-source/v1 - description: Local development server. - -security: - - bearer: [] - -tags: - - name: AttributeSources - description: Register EDK attribute-source definitions and optionally bind their native fields to semantic attributes. - -paths: - /sources: - get: - operationId: listAttributeSources - summary: List attribute sources - description: | - Lists the registered attribute sources for the caller's tenant. Use `kind` to find sources - by connector family, for example `REST_API` during OID4VCI session enrichment or `DATABASE` - for a directory-backed issuer pipeline. Use `lifecycleStatus=ACTIVE` when selecting sources - that are eligible for new pipeline bindings. - tags: [AttributeSources] - parameters: - - name: kind - in: query - description: Optional connector family filter. - schema: - $ref: './attribute-source-components.yml#/components/schemas/AttributeSourceKind' - - name: lifecycleStatus - in: query - description: Optional lifecycle filter. - schema: - $ref: './attribute-source-components.yml#/components/schemas/AttributeSourceLifecycleStatus' - - $ref: './common-components.yml#/components/parameters/Page' - - $ref: './common-components.yml#/components/parameters/Size' - responses: - '200': - description: Paged EDK attribute-source definitions. - content: - application/json: - schema: - $ref: '#/components/schemas/AttributeSourcePage' - examples: - hrSources: - summary: HR and directory sources registered for issuer pipelines - value: - items: - - sourceId: hr-workday-profile - tenantId: acme - displayName: Workday profile lookup - description: Resolves employee credential claims from the HR profile API by employee_id. - kind: REST_API - lifecycleStatus: ACTIVE - managementMode: EXTERNAL - runtimeMode: THIRD_PARTY - consumedLookupKeys: [employee_id] - producedAttributes: - - path: employee.givenName - nativeName: first_name - nativeType: string - label: Given name - - path: employee.familyName - nativeName: last_name - nativeType: string - label: Family name - - path: employment.department - nativeName: department_code - nativeType: string - label: Department - connectionRef: - endpointUrl: https://hr.example.com/api/employees - configKeyPrefix: attribute-source.hr-workday - createdAt: '2026-06-10T08:30:00Z' - updatedAt: '2026-06-10T08:30:00Z' - total_count: 1 - limit: 20 - offset: 0 - has_more: false - page_number: 0 - total_pages: 1 - '400': - $ref: './common-components.yml#/components/responses/ValidationError' - '401': - $ref: './common-components.yml#/components/responses/Unauthorized' - post: - operationId: createAttributeSource - summary: Create an attribute source - description: | - Creates the tenant-scoped source definition that EDK persistence and pipeline bindings use. - Provide `sourceId` when the integration needs a stable, human-readable id in configuration; - omit it when the service should assign one. The request body maps directly to - `CreateAttributeSourceArgs`. - tags: [AttributeSources] - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/CreateAttributeSourceRequest' - examples: - hrRestSource: - summary: REST source used during employee credential issuance - value: - sourceId: hr-workday-profile - displayName: Workday profile lookup - description: Resolves employee credential claims from the HR profile API by employee_id. - kind: REST_API - managementMode: EXTERNAL - runtimeMode: THIRD_PARTY - consumedLookupKeys: [employee_id] - producedAttributes: - - path: employee.givenName - nativeName: first_name - nativeType: string - label: Given name - - path: employee.familyName - nativeName: last_name - nativeType: string - label: Family name - - path: employment.department - nativeName: department_code - nativeType: string - label: Department - connectionRef: - endpointUrl: https://hr.example.com/api/employees - configKeyPrefix: attribute-source.hr-workday - directoryDatabase: - summary: Database source for a directory-backed pipeline - value: - sourceId: employee-directory - displayName: Employee directory table - description: Reads stable employee attributes from the directory database by person_id. - kind: DATABASE - managementMode: HYBRID - runtimeMode: REMOTE_EDK - consumedLookupKeys: [person_id] - producedAttributes: - - path: employee.email - nativeName: email_address - nativeType: varchar - label: Work email - - path: employment.costCenter - nativeName: cost_center - nativeType: varchar - label: Cost center - connectionRef: - configKeyPrefix: attribute-source.employee-directory - backingSourceId: directory.employee_profile - responses: - '201': - description: Attribute source created. - content: - application/json: - schema: - $ref: '#/components/schemas/AttributeSourceDefinition' - '400': - $ref: './common-components.yml#/components/responses/ValidationError' - '401': - $ref: './common-components.yml#/components/responses/Unauthorized' - - /sources/{sourceId}: - get: - operationId: getAttributeSource - summary: Get an attribute source - description: | - Reads one source definition by the registry id used in pipeline bindings. The id is the - EDK attribute-source id, not a VDX party id and not a credential configuration id. - tags: [AttributeSources] - parameters: - - $ref: './attribute-source-components.yml#/components/parameters/SourceId' - responses: - '200': - description: Attribute source definition. - content: - application/json: - schema: - $ref: '#/components/schemas/AttributeSourceDefinition' - '401': - $ref: './common-components.yml#/components/responses/Unauthorized' - '404': - $ref: './common-components.yml#/components/responses/NotFound' - put: - operationId: updateAttributeSource - summary: Update an attribute source - description: | - Updates mutable source metadata and runtime contract fields. The `{sourceId}` path value is - authoritative and is copied into `UpdateAttributeSourceArgs.sourceId`; any `sourceId` in - the body is ignored by the REST command. - tags: [AttributeSources] - parameters: - - $ref: './attribute-source-components.yml#/components/parameters/SourceId' - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/UpdateAttributeSourceRequest' - examples: - addEmploymentFields: - summary: Add fields returned by the HR profile endpoint - value: - description: Resolves employee credential and employment claims from the HR profile API by employee_id. - producedAttributes: - - path: employee.givenName - nativeName: first_name - nativeType: string - label: Given name - - path: employee.familyName - nativeName: last_name - nativeType: string - label: Family name - - path: employment.department - nativeName: department_code - nativeType: string - label: Department - - path: employment.jobTitle - nativeName: job_title - nativeType: string - label: Job title - suspendSource: - summary: Temporarily stop new pipeline use - value: - lifecycleStatus: SUSPENDED - responses: - '200': - description: Attribute source updated. - content: - application/json: - schema: - $ref: '#/components/schemas/AttributeSourceDefinition' - '400': - $ref: './common-components.yml#/components/responses/ValidationError' - '401': - $ref: './common-components.yml#/components/responses/Unauthorized' - '404': - $ref: './common-components.yml#/components/responses/NotFound' - delete: - operationId: deleteAttributeSource - summary: Delete an attribute source - description: | - Deletes the source definition for this tenant. Existing pipeline configuration should stop - referencing the `sourceId` before deletion; the endpoint returns `204` when the command - succeeds. - tags: [AttributeSources] - parameters: - - $ref: './attribute-source-components.yml#/components/parameters/SourceId' - responses: - '204': - description: Attribute source deleted. - '401': - $ref: './common-components.yml#/components/responses/Unauthorized' - '404': - $ref: './common-components.yml#/components/responses/NotFound' - - /sources/{sourceId}/semantic-bindings: - get: - operationId: listAttributeSourceSemanticBindings - summary: List semantic bindings for an attribute source - description: | - Lists the optional semantic annotations for the source's native fields. These records are - separate from the source definition so an integration can first be registered and used by a - pipeline, then enriched with catalog/profile meaning when that semantic model is available. - tags: [AttributeSources] - parameters: - - $ref: './attribute-source-components.yml#/components/parameters/SourceId' - responses: - '200': - description: Semantic bindings for native fields produced by the source. - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/AttributeSourceSemanticBinding' - examples: - employeeCredentialBindings: - summary: Native HR fields bound to employee credential semantics - value: - - bindingId: bnd-hr-first-name - tenantId: acme - sourceId: hr-workday-profile - catalogId: employee-core - profileId: employee-credential-profile - setId: employment-credential-set - attributePath: employee.givenName - nativeField: first_name - createdAt: '2026-06-10T08:45:00Z' - updatedAt: '2026-06-10T08:45:00Z' - - bindingId: bnd-hr-department - tenantId: acme - sourceId: hr-workday-profile - catalogId: employee-core - profileId: employee-credential-profile - setId: employment-credential-set - attributePath: employment.department - nativeField: department_code - createdAt: '2026-06-10T08:45:00Z' - updatedAt: '2026-06-10T08:45:00Z' - '401': - $ref: './common-components.yml#/components/responses/Unauthorized' - '404': - $ref: './common-components.yml#/components/responses/NotFound' - put: - operationId: setAttributeSourceSemanticBindings - summary: Replace semantic bindings for an attribute source - description: | - Replaces the complete binding set for the source. Send every semantic binding that should - remain active. The command stores tenant, source id, binding id, and timestamps; the request - body only contains the authored `SemanticBindingInput` fields. - tags: [AttributeSources] - parameters: - - $ref: './attribute-source-components.yml#/components/parameters/SourceId' - requestBody: - required: true - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/SemanticBindingInput' - examples: - employeeCredentialBindings: - summary: Bind HR fields to the employee credential profile - value: - - catalogId: employee-core - profileId: employee-credential-profile - setId: employment-credential-set - attributePath: employee.givenName - nativeField: first_name - - catalogId: employee-core - profileId: employee-credential-profile - setId: employment-credential-set - attributePath: employee.familyName - nativeField: last_name - - catalogId: employee-core - profileId: employee-credential-profile - setId: employment-credential-set - attributePath: employment.department - nativeField: department_code - responses: - '200': - description: Semantic bindings replaced. - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/AttributeSourceSemanticBinding' - '400': - $ref: './common-components.yml#/components/responses/ValidationError' - '401': - $ref: './common-components.yml#/components/responses/Unauthorized' - '404': - $ref: './common-components.yml#/components/responses/NotFound' - -components: - securitySchemes: - bearer: - $ref: './common-components.yml#/components/securitySchemes/bearer' - schemas: - AttributeSourceKind: - $ref: './attribute-source-components.yml#/components/schemas/AttributeSourceKind' - AttributeSourceLifecycleStatus: - $ref: './attribute-source-components.yml#/components/schemas/AttributeSourceLifecycleStatus' - AttributeSourceManagementMode: - $ref: './attribute-source-components.yml#/components/schemas/AttributeSourceManagementMode' - AttributeSourceRuntimeMode: - $ref: './attribute-source-components.yml#/components/schemas/AttributeSourceRuntimeMode' - ProducedAttribute: - $ref: './attribute-source-components.yml#/components/schemas/ProducedAttribute' - AttributeSourceConnectionRef: - $ref: './attribute-source-components.yml#/components/schemas/AttributeSourceConnectionRef' - AttributeSourceDefinition: - $ref: './attribute-source-components.yml#/components/schemas/AttributeSourceDefinition' - CreateAttributeSourceRequest: - $ref: './attribute-source-components.yml#/components/schemas/CreateAttributeSourceRequest' - UpdateAttributeSourceRequest: - $ref: './attribute-source-components.yml#/components/schemas/UpdateAttributeSourceRequest' - AttributeSourcePage: - $ref: './attribute-source-components.yml#/components/schemas/AttributeSourcePage' - SemanticBindingInput: - $ref: './attribute-source-components.yml#/components/schemas/SemanticBindingInput' - AttributeSourceSemanticBinding: - $ref: './attribute-source-components.yml#/components/schemas/AttributeSourceSemanticBinding' diff --git a/command-types.json b/command-types.json deleted file mode 100644 index 211fc6e..0000000 --- a/command-types.json +++ /dev/null @@ -1,692 +0,0 @@ -{ - "CreateCredentialDesignArgs": { - "kind": "data class", - "name": "CreateCredentialDesignArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class CreateCredentialDesignArgs(\n val tenantId: String,\n val input: CreateCredentialDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class CreateCredentialDesignInput\n @JvmOverloads\n constructor(\n val bindings: List,\n val alias: String? = null,\n val hostingMode: DesignHostingMode = DesignHostingMode.LOCAL,\n val credentialTemplateId: Uuid? = null,\n val issuerDesignId: Uuid? = null,\n val displays: List,\n val claims: List = emptyList(),\n val renderVariantIds: List = emptyList(),\n val credentialType: CredentialTypeDescriptor? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\ndata class LocalizedCredentialDisplay\n @JvmOverloads\n constructor(\n val locale: String,\n val name: String,\n val description: String? = null,\n val issuerNameOverride: String? = null,\n val preferredRenderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class ClaimPresentation\n @JvmOverloads\n constructor(\n val path: DesignClaimPath,\n val labels: List,\n val mandatory: Boolean = false,\n val sdPolicy: SdPolicy = SdPolicy.ALLOWED,\n val order: Int = 0,\n val group: String? = null,\n val svgId: String? = null,\n val valueKind: ClaimValueKind? = null,\n val widgetHint: ClaimWidgetHint? = null,\n val markdownAllowed: Boolean = false,\n val entryCodes: List? = null,\n val unit: String? = null,\n )" - }, - "CredentialDesignRecord": { - "kind": "data class", - "name": "CredentialDesignRecord", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class CredentialDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val credentialTemplateId: Uuid? = null,\n val issuerDesignId: Uuid? = null,\n val displays: List,\n val claims: List = emptyList(),\n val renderVariantIds: List = emptyList(),\n val derivedRenderHintsId: Uuid? = null,\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n /** Optional OCA semantic attribute set this design draws from. When present, the OCA-backed\n * credential-design resolution derives selective-disclosure and mandatory flags from it. */\n val semanticAttributeSetRef: SemanticAttributeSetRef? = null,\n /** Optional attribute-profile this design draws from. When present, credential-design\n * resolution derives selective-disclosure and mandatory flags from the profile's resolved\n * effective projection in preference to [semanticAttributeSetRef]. The id and pinned\n * version are held as primitives so this IDK contract stays free of the EDK profile types. */\n val attributeProfileId: Uuid? = null,\n val attributeProfileVersion: Long? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n val credentialType: CredentialTypeDescriptor? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\ndata class LocalizedCredentialDisplay\n @JvmOverloads\n constructor(\n val locale: String,\n val name: String,\n val description: String? = null,\n val issuerNameOverride: String? = null,\n val preferredRenderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class ClaimPresentation\n @JvmOverloads\n constructor(\n val path: DesignClaimPath,\n val labels: List,\n val mandatory: Boolean = false,\n val sdPolicy: SdPolicy = SdPolicy.ALLOWED,\n val order: Int = 0,\n val group: String? = null,\n val svgId: String? = null,\n val valueKind: ClaimValueKind? = null,\n val widgetHint: ClaimWidgetHint? = null,\n val markdownAllowed: Boolean = false,\n val entryCodes: List? = null,\n val unit: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class SemanticAttributeSetRef(\n /** OCA bundle / vocabulary identifier. */\n val bundleId: String,\n /** Optional pinned bundle version; null = resolve the current version. */\n val version: String? = null,\n)\n\ntypealias DesignClaimPath = List\n\n@JsExportCompat\n@Serializable\ndata class ClaimLabel\n @JvmOverloads\n constructor(\n val locale: String,\n val label: String,\n val description: String? = null,\n @JsExportIgnoreCompat\n val entryValues: Map? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class SdPolicy {\n ALWAYS,\n ALLOWED,\n NEVER,\n}\n\n@JsExportCompat\n@Serializable\nenum class ClaimValueKind {\n STRING,\n BOOLEAN,\n NUMBER,\n INTEGER,\n ARRAY,\n OBJECT,\n DATE,\n DATE_TIME,\n URI,\n IMAGE,\n BINARY,\n MARKDOWN,\n REFERENCE,\n UNKNOWN,\n}\n\n@JsExportCompat\n@Serializable\nenum class ClaimWidgetHint {\n TEXT,\n MULTILINE_TEXT,\n CHECKBOX,\n BADGE,\n LIST,\n TABLE,\n GROUP,\n DATE,\n DATE_TIME,\n URI,\n IMAGE,\n MARKDOWN,\n HIDDEN,\n PICKLIST,\n FILE,\n}" - }, - "ListDesignsArgs": { - "kind": "data class", - "name": "ListDesignsArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class ListDesignsArgs\n @JvmOverloads\n constructor(\n val tenantId: String,\n val filter: DesignFilter = DesignFilter(),\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignFilter\n @JvmOverloads\n constructor(\n val entityType: DesignEntityType? = null,\n val hostingMode: DesignHostingMode? = null,\n val binding: DesignBinding? = null,\n val bindingKey: DesignBindingKey? = null,\n val bindingValue: String? = null,\n val aliasContains: String? = null,\n val sourceType: DesignSourceType? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignEntityType {\n CREDENTIAL,\n ISSUER,\n VERIFIER,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}" - }, - "FindByBindingKeyArgs": { - "kind": "data class", - "name": "FindByBindingKeyArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class FindByBindingKeyArgs(\n val tenantId: String,\n val bindingKey: DesignBindingKey,\n val bindingValue: String,\n)\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}" - }, - "ImportExternalDesignArgs": { - "kind": "data class", - "name": "ImportExternalDesignArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class ImportExternalDesignArgs(\n val tenantId: String,\n val input: ImportExternalDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class ImportExternalDesignInput\n @JvmOverloads\n constructor(\n val entityType: DesignEntityType,\n val bindings: List,\n val alias: String? = null,\n val sourceUrl: String,\n val sourceType: DesignSourceType,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignEntityType {\n CREDENTIAL,\n ISSUER,\n VERIFIER,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}" - }, - "ResolveCredentialDesignArgs": { - "kind": "data class", - "name": "ResolveCredentialDesignArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class ResolveCredentialDesignArgs(\n val tenantId: String,\n val input: ResolveCredentialDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class ResolveCredentialDesignInput\n @JvmOverloads\n constructor(\n val designId: Uuid? = null,\n val binding: DesignBinding? = null,\n val bindingKey: DesignBindingKey? = null,\n val bindingValue: String? = null,\n val preferredLocales: List = emptyList(),\n val renderTarget: RenderVariantKind? = null,\n val externalMetadata: ExternalDesignMetadata? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}\n\n@JsExportCompat\n@Serializable\nenum class RenderVariantKind {\n SIMPLE_CARD,\n SVG_TEMPLATE,\n W3C_RENDER_METHOD,\n PDF_TEMPLATE,\n EXTERNAL_REFERENCE,\n}\n\n@JsExportCompat\n@Serializable\ndata class ExternalDesignMetadata\n @JvmOverloads\n constructor(\n val sdJwtVctMetadata: JsonObject? = null,\n val oid4vciCredentialConfiguration: JsonObject? = null,\n val oid4vciIssuerMetadata: JsonObject? = null,\n val sdJwtIssuerMetadata: JsonObject? = null,\n val jsonSchema: JsonObject? = null,\n val jsonLdContext: JsonObject? = null,\n val oidcDiscovery: JsonObject? = null,\n val openIdFederationEntity: JsonObject? = null,\n val oauthClientRegistration: JsonObject? = null,\n val eidasRegistryData: JsonObject? = null,\n val eidasCatalogueData: JsonObject? = null,\n val w3cRenderMethod: JsonObject? = null,\n val ocaBundle: JsonObject? = null,\n val ocaCaptureBase: JsonObject? = null,\n val ocaOverlays: List = emptyList(),\n val ocaFile: String? = null,\n val overlayFiles: List = emptyList(),\n )" - }, - "ResolvedCredentialDesign": { - "kind": "data class", - "name": "ResolvedCredentialDesign", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class ResolvedCredentialDesign\n @JvmOverloads\n constructor(\n val design: CredentialDesignRecord,\n val issuerDesign: IssuerDesignRecord? = null,\n val verifierDesign: VerifierDesignRecord? = null,\n val renderVariants: List,\n val derivedRenderHints: DerivedRenderHintsRecord? = null,\n val appliedLayers: List,\n @JsExportIgnoreCompat\n val lockedFields: Map,\n val resolvedAt: Instant,\n val etag: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class CredentialDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val credentialTemplateId: Uuid? = null,\n val issuerDesignId: Uuid? = null,\n val displays: List,\n val claims: List = emptyList(),\n val renderVariantIds: List = emptyList(),\n val derivedRenderHintsId: Uuid? = null,\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n /** Optional OCA semantic attribute set this design draws from. When present, the OCA-backed\n * credential-design resolution derives selective-disclosure and mandatory flags from it. */\n val semanticAttributeSetRef: SemanticAttributeSetRef? = null,\n /** Optional attribute-profile this design draws from. When present, credential-design\n * resolution derives selective-disclosure and mandatory flags from the profile's resolved\n * effective projection in preference to [semanticAttributeSetRef]. The id and pinned\n * version are held as primitives so this IDK contract stays free of the EDK profile types. */\n val attributeProfileId: Uuid? = null,\n val attributeProfileVersion: Long? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n val credentialType: CredentialTypeDescriptor? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class IssuerDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val partyId: Uuid? = null,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n )\n\n@JsExportCompat\n@Serializable\ndata class VerifierDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val partyId: Uuid? = null,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n )\n\n@JsExportCompat\n@Serializable\ndata class RenderVariantRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val kind: RenderVariantKind,\n val alias: String? = null,\n val localeApplicability: List = emptyList(),\n val sourceSnapshotId: Uuid? = null,\n val logo: AssetReference? = null,\n val backgroundImage: AssetReference? = null,\n val backgroundColor: String? = null,\n val textColor: String? = null,\n val accentColor: String? = null,\n val svgTemplate: SvgTemplate? = null,\n val w3cRenderMethod: W3cRenderMethodReference? = null,\n val pdfTemplate: AssetReference? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DerivedRenderHintsRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val sourceSnapshotIds: List = emptyList(),\n val fieldHints: List,\n @JsExportIgnoreCompat\n val groupHints: Map> = emptyMap(),\n val defaultOrdering: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class AppliedDesignLayer\n @JvmOverloads\n constructor(\n val sourceType: DesignSourceType,\n val sourceUrl: String? = null,\n val priority: Int,\n val authoritative: Boolean = false,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\ndata class LocalizedCredentialDisplay\n @JvmOverloads\n constructor(\n val locale: String,\n val name: String,\n val description: String? = null,\n val issuerNameOverride: String? = null,\n val preferredRenderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class ClaimPresentation\n @JvmOverloads\n constructor(\n val path: DesignClaimPath,\n val labels: List,\n val mandatory: Boolean = false,\n val sdPolicy: SdPolicy = SdPolicy.ALLOWED,\n val order: Int = 0,\n val group: String? = null,\n val svgId: String? = null,\n val valueKind: ClaimValueKind? = null,\n val widgetHint: ClaimWidgetHint? = null,\n val markdownAllowed: Boolean = false,\n val entryCodes: List? = null,\n val unit: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class SemanticAttributeSetRef(\n /** OCA bundle / vocabulary identifier. */\n val bundleId: String,\n /** Optional pinned bundle version; null = resolve the current version. */\n val version: String? = null,\n)\n\n@JsExportCompat\n@Serializable\ndata class EntityLocaleDesign\n @JvmOverloads\n constructor(\n val locale: String,\n val displayName: String? = null,\n val description: String? = null,\n )" - }, - "GetCredentialDesignArgs": { - "kind": "data class", - "name": "GetCredentialDesignArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class GetCredentialDesignArgs(\n val tenantId: String,\n val id: Uuid,\n)" - }, - "UpdateCredentialDesignArgs": { - "kind": "data class", - "name": "UpdateCredentialDesignArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class UpdateCredentialDesignArgs(\n val tenantId: String,\n val id: Uuid,\n val input: UpdateCredentialDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class UpdateCredentialDesignInput\n @JvmOverloads\n constructor(\n val alias: String? = null,\n val bindings: List? = null,\n val credentialTemplateId: Uuid? = null,\n val issuerDesignId: Uuid? = null,\n val displays: List? = null,\n val claims: List? = null,\n val renderVariantIds: List? = null,\n val hostingMode: DesignHostingMode? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\ndata class LocalizedCredentialDisplay\n @JvmOverloads\n constructor(\n val locale: String,\n val name: String,\n val description: String? = null,\n val issuerNameOverride: String? = null,\n val preferredRenderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class ClaimPresentation\n @JvmOverloads\n constructor(\n val path: DesignClaimPath,\n val labels: List,\n val mandatory: Boolean = false,\n val sdPolicy: SdPolicy = SdPolicy.ALLOWED,\n val order: Int = 0,\n val group: String? = null,\n val svgId: String? = null,\n val valueKind: ClaimValueKind? = null,\n val widgetHint: ClaimWidgetHint? = null,\n val markdownAllowed: Boolean = false,\n val entryCodes: List? = null,\n val unit: String? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}" - }, - "DeleteDesignArgs": { - "kind": "data class", - "name": "DeleteDesignArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class DeleteDesignArgs(\n val tenantId: String,\n val id: Uuid,\n)" - }, - "RefreshDesignArgs": { - "kind": "data class", - "name": "RefreshDesignArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class RefreshDesignArgs(\n val tenantId: String,\n val designId: Uuid,\n)" - }, - "CreateIssuerDesignArgs": { - "kind": "data class", - "name": "CreateIssuerDesignArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class CreateIssuerDesignArgs(\n val tenantId: String,\n val input: CreateIssuerDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class CreateIssuerDesignInput\n @JvmOverloads\n constructor(\n val bindings: List,\n val partyId: Uuid? = null,\n val alias: String? = null,\n val hostingMode: DesignHostingMode = DesignHostingMode.LOCAL,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\ndata class EntityLocaleDesign\n @JvmOverloads\n constructor(\n val locale: String,\n val displayName: String? = null,\n val description: String? = null,\n )" - }, - "IssuerDesignRecord": { - "kind": "data class", - "name": "IssuerDesignRecord", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class IssuerDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val partyId: Uuid? = null,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\ndata class EntityLocaleDesign\n @JvmOverloads\n constructor(\n val locale: String,\n val displayName: String? = null,\n val description: String? = null,\n )" - }, - "ResolveIssuerDesignArgs": { - "kind": "data class", - "name": "ResolveIssuerDesignArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class ResolveIssuerDesignArgs(\n val tenantId: String,\n val input: ResolveEntityDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class ResolveEntityDesignInput\n @JvmOverloads\n constructor(\n val designId: Uuid? = null,\n val binding: DesignBinding? = null,\n val bindingKey: DesignBindingKey? = null,\n val bindingValue: String? = null,\n val preferredLocales: List = emptyList(),\n val externalMetadata: ExternalDesignMetadata? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}\n\n@JsExportCompat\n@Serializable\ndata class ExternalDesignMetadata\n @JvmOverloads\n constructor(\n val sdJwtVctMetadata: JsonObject? = null,\n val oid4vciCredentialConfiguration: JsonObject? = null,\n val oid4vciIssuerMetadata: JsonObject? = null,\n val sdJwtIssuerMetadata: JsonObject? = null,\n val jsonSchema: JsonObject? = null,\n val jsonLdContext: JsonObject? = null,\n val oidcDiscovery: JsonObject? = null,\n val openIdFederationEntity: JsonObject? = null,\n val oauthClientRegistration: JsonObject? = null,\n val eidasRegistryData: JsonObject? = null,\n val eidasCatalogueData: JsonObject? = null,\n val w3cRenderMethod: JsonObject? = null,\n val ocaBundle: JsonObject? = null,\n val ocaCaptureBase: JsonObject? = null,\n val ocaOverlays: List = emptyList(),\n val ocaFile: String? = null,\n val overlayFiles: List = emptyList(),\n )" - }, - "ResolvedIssuerDesign": { - "kind": "data class", - "name": "ResolvedIssuerDesign", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class ResolvedIssuerDesign\n @JvmOverloads\n constructor(\n val design: IssuerDesignRecord,\n val renderVariants: List,\n val appliedLayers: List,\n @JsExportIgnoreCompat\n val lockedFields: Map,\n val resolvedAt: Instant,\n val etag: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class IssuerDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val partyId: Uuid? = null,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n )\n\n@JsExportCompat\n@Serializable\ndata class RenderVariantRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val kind: RenderVariantKind,\n val alias: String? = null,\n val localeApplicability: List = emptyList(),\n val sourceSnapshotId: Uuid? = null,\n val logo: AssetReference? = null,\n val backgroundImage: AssetReference? = null,\n val backgroundColor: String? = null,\n val textColor: String? = null,\n val accentColor: String? = null,\n val svgTemplate: SvgTemplate? = null,\n val w3cRenderMethod: W3cRenderMethodReference? = null,\n val pdfTemplate: AssetReference? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class AppliedDesignLayer\n @JvmOverloads\n constructor(\n val sourceType: DesignSourceType,\n val sourceUrl: String? = null,\n val priority: Int,\n val authoritative: Boolean = false,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\ndata class EntityLocaleDesign\n @JvmOverloads\n constructor(\n val locale: String,\n val displayName: String? = null,\n val description: String? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class RenderVariantKind {\n SIMPLE_CARD,\n SVG_TEMPLATE,\n W3C_RENDER_METHOD,\n PDF_TEMPLATE,\n EXTERNAL_REFERENCE,\n}\n\n@JsExportCompat\n@Serializable\ndata class AssetReference\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val altText: String? = null,\n val contentType: String? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class SvgTemplate\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val orientation: SvgOrientation? = null,\n val colorScheme: SvgColorScheme? = null,\n val contrast: SvgContrast? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class W3cRenderMethodReference\n @JvmOverloads\n constructor(\n val type: String,\n val renderSuite: String? = null,\n val uri: String,\n val mediaType: String? = null,\n val name: String? = null,\n val description: String? = null,\n val digestMultibase: String? = null,\n val renderProperties: List? = null,\n )" - }, - "CreateRenderVariantArgs": { - "kind": "data class", - "name": "CreateRenderVariantArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class CreateRenderVariantArgs(\n val tenantId: String,\n val input: CreateRenderVariantInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class CreateRenderVariantInput\n @JvmOverloads\n constructor(\n val kind: RenderVariantKind,\n val alias: String? = null,\n val localeApplicability: List = emptyList(),\n val logo: AssetReference? = null,\n val backgroundImage: AssetReference? = null,\n val backgroundColor: String? = null,\n val textColor: String? = null,\n val accentColor: String? = null,\n val svgTemplate: SvgTemplate? = null,\n val w3cRenderMethod: W3cRenderMethodReference? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class RenderVariantKind {\n SIMPLE_CARD,\n SVG_TEMPLATE,\n W3C_RENDER_METHOD,\n PDF_TEMPLATE,\n EXTERNAL_REFERENCE,\n}\n\n@JsExportCompat\n@Serializable\ndata class AssetReference\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val altText: String? = null,\n val contentType: String? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class SvgTemplate\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val orientation: SvgOrientation? = null,\n val colorScheme: SvgColorScheme? = null,\n val contrast: SvgContrast? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class W3cRenderMethodReference\n @JvmOverloads\n constructor(\n val type: String,\n val renderSuite: String? = null,\n val uri: String,\n val mediaType: String? = null,\n val name: String? = null,\n val description: String? = null,\n val digestMultibase: String? = null,\n val renderProperties: List? = null,\n )" - }, - "RenderVariantRecord": { - "kind": "data class", - "name": "RenderVariantRecord", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class RenderVariantRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val kind: RenderVariantKind,\n val alias: String? = null,\n val localeApplicability: List = emptyList(),\n val sourceSnapshotId: Uuid? = null,\n val logo: AssetReference? = null,\n val backgroundImage: AssetReference? = null,\n val backgroundColor: String? = null,\n val textColor: String? = null,\n val accentColor: String? = null,\n val svgTemplate: SvgTemplate? = null,\n val w3cRenderMethod: W3cRenderMethodReference? = null,\n val pdfTemplate: AssetReference? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class RenderVariantKind {\n SIMPLE_CARD,\n SVG_TEMPLATE,\n W3C_RENDER_METHOD,\n PDF_TEMPLATE,\n EXTERNAL_REFERENCE,\n}\n\n@JsExportCompat\n@Serializable\ndata class AssetReference\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val altText: String? = null,\n val contentType: String? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class SvgTemplate\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val orientation: SvgOrientation? = null,\n val colorScheme: SvgColorScheme? = null,\n val contrast: SvgContrast? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class W3cRenderMethodReference\n @JvmOverloads\n constructor(\n val type: String,\n val renderSuite: String? = null,\n val uri: String,\n val mediaType: String? = null,\n val name: String? = null,\n val description: String? = null,\n val digestMultibase: String? = null,\n val renderProperties: List? = null,\n )\n\n@Serializable\n@SerialName(\"blob-info\")\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"BlobInfo\", exact = true)\ndata class BlobInfo(\n override val storeId: String? = null,\n override val path: String? = null,\n override val tenantId: String? = null,\n override val contentType: String? = null,\n override val metadata: Map = emptyMap(),\n @Transient\n val opts: Map = emptyMap(),\n) : BlobInfoType {\n override fun toBlobInfo(): BlobInfo = this\n\n /**\n * Returns a [BlobMetadata] from this info's content type and custom metadata.\n */\n fun toBlobMetadata(): BlobMetadata =\n BlobMetadata(\n contentType = contentType,\n custom = metadata,\n )\n\n /**\n * Lightweight identity for use as map keys and cache lookups.\n * Like [KeyIdentity] — deterministic equality without transient fields.\n */\n fun toIdentity(): BlobIdentity =\n BlobIdentity(\n storeId = storeId,\n path = path,\n tenantId = tenantId,\n )\n\n /** Creates a copy targeting a different path. */\n fun withPath(newPath: String): BlobInfo = copy(path = newPath)\n\n /** Creates a copy targeting a different store. */\n fun withStore(newStoreId: String): BlobInfo = copy(storeId = newStoreId)\n\n companion object {\n fun of(\n storeId: String,\n path: String,\n ) = BlobInfo(storeId = storeId, path = path)\n\n fun fromDescriptor(\n descriptor: BlobDescriptor,\n tenantId: String? = null,\n ) = BlobInfo(\n storeId = descriptor.storeId,\n path = descriptor.path,\n tenantId = tenantId,\n contentType = descriptor.contentType,\n metadata = descriptor.metadata.custom,\n )\n\n /**\n * Validates a blob path for security:\n * - Rejects path traversal segments (`..`)\n * - Rejects null bytes\n * - Rejects absolute paths\n * - Rejects backslash separators\n */\n fun validatePath(path: String) {\n require(!path.contains('\\u0000')) { \"Blob path must not contain null bytes\" }\n require(!path.startsWith('/')) { \"Blob path must not be absolute\" }\n require(!path.contains('\\\\')) { \"Blob path must use '/' separators, not '\\\\'\" }\n val segments = path.split('/')\n require(segments.none { it == \"..\" }) { \"Blob path must not contain '..' traversal segments: $path\" }\n require(segments.none { it == \".\" }) { \"Blob path must not contain '.' self-reference segments: $path\" }\n }\n\n /**\n * Sanitizes and normalizes a user-provided path. Returns a safe path string.\n * Throws [IllegalArgumentException] if the path is malicious.\n */\n fun sanitizePath(path: String): String {\n val normalized =\n path\n .replace('\\\\', '/')\n .replace(Regex(\"/+\"), \"/\")\n .trimStart('/')\n .trimEnd('/')\n require(normalized.isNotBlank()) { \"Sanitized path must not be blank\" }\n validatePath(normalized)\n return normalized\n }\n }\n}\n\n@JsExportCompat\n@Serializable\nenum class SvgOrientation { PORTRAIT, LANDSCAPE }\n\n@JsExportCompat\n@Serializable\nenum class SvgColorScheme { LIGHT, DARK }\n\n@JsExportCompat\n@Serializable\nenum class SvgContrast { NORMAL, HIGH }" - }, - "ListRenderVariantsArgs": { - "kind": "data class", - "name": "ListRenderVariantsArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class ListRenderVariantsArgs\n @JvmOverloads\n constructor(\n val tenantId: String,\n val filter: DesignFilter = DesignFilter(),\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignFilter\n @JvmOverloads\n constructor(\n val entityType: DesignEntityType? = null,\n val hostingMode: DesignHostingMode? = null,\n val binding: DesignBinding? = null,\n val bindingKey: DesignBindingKey? = null,\n val bindingValue: String? = null,\n val aliasContains: String? = null,\n val sourceType: DesignSourceType? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignEntityType {\n CREDENTIAL,\n ISSUER,\n VERIFIER,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\nenum class CredentialTypeFormat {\n SD_JWT_VC,\n MSO_MDOC,\n W3C_VC,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n val type: String? = null,\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}" - }, - "GetSourceSnapshotArgs": { - "kind": "data class", - "name": "GetSourceSnapshotArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class GetSourceSnapshotArgs(\n val tenantId: String,\n val snapshotId: Uuid,\n)" - }, - "SourceSnapshotRecord": { - "kind": "data class", - "name": "SourceSnapshotRecord", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class SourceSnapshotRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val sourceType: DesignSourceType,\n val sourceUrl: String? = null,\n val etag: String? = null,\n val integrity: String? = null,\n val said: String? = null,\n val fetchedAt: Instant,\n val contentBlob: BlobInfo,\n val normalizedFromVersion: String? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}\n\n@Serializable\n@SerialName(\"blob-info\")\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"BlobInfo\", exact = true)\ndata class BlobInfo(\n override val storeId: String? = null,\n override val path: String? = null,\n override val tenantId: String? = null,\n override val contentType: String? = null,\n override val metadata: Map = emptyMap(),\n @Transient\n val opts: Map = emptyMap(),\n) : BlobInfoType {\n override fun toBlobInfo(): BlobInfo = this\n\n /**\n * Returns a [BlobMetadata] from this info's content type and custom metadata.\n */\n fun toBlobMetadata(): BlobMetadata =\n BlobMetadata(\n contentType = contentType,\n custom = metadata,\n )\n\n /**\n * Lightweight identity for use as map keys and cache lookups.\n * Like [KeyIdentity] — deterministic equality without transient fields.\n */\n fun toIdentity(): BlobIdentity =\n BlobIdentity(\n storeId = storeId,\n path = path,\n tenantId = tenantId,\n )\n\n /** Creates a copy targeting a different path. */\n fun withPath(newPath: String): BlobInfo = copy(path = newPath)\n\n /** Creates a copy targeting a different store. */\n fun withStore(newStoreId: String): BlobInfo = copy(storeId = newStoreId)\n\n companion object {\n fun of(\n storeId: String,\n path: String,\n ) = BlobInfo(storeId = storeId, path = path)\n\n fun fromDescriptor(\n descriptor: BlobDescriptor,\n tenantId: String? = null,\n ) = BlobInfo(\n storeId = descriptor.storeId,\n path = descriptor.path,\n tenantId = tenantId,\n contentType = descriptor.contentType,\n metadata = descriptor.metadata.custom,\n )\n\n /**\n * Validates a blob path for security:\n * - Rejects path traversal segments (`..`)\n * - Rejects null bytes\n * - Rejects absolute paths\n * - Rejects backslash separators\n */\n fun validatePath(path: String) {\n require(!path.contains('\\u0000')) { \"Blob path must not contain null bytes\" }\n require(!path.startsWith('/')) { \"Blob path must not be absolute\" }\n require(!path.contains('\\\\')) { \"Blob path must use '/' separators, not '\\\\'\" }\n val segments = path.split('/')\n require(segments.none { it == \"..\" }) { \"Blob path must not contain '..' traversal segments: $path\" }\n require(segments.none { it == \".\" }) { \"Blob path must not contain '.' self-reference segments: $path\" }\n }\n\n /**\n * Sanitizes and normalizes a user-provided path. Returns a safe path string.\n * Throws [IllegalArgumentException] if the path is malicious.\n */\n fun sanitizePath(path: String): String {\n val normalized =\n path\n .replace('\\\\', '/')\n .replace(Regex(\"/+\"), \"/\")\n .trimStart('/')\n .trimEnd('/')\n require(normalized.isNotBlank()) { \"Sanitized path must not be blank\" }\n validatePath(normalized)\n return normalized\n }\n }\n}\n\n@Serializable\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"BlobInfoType\", exact = true)\n@JsExportCompat\nsealed interface BlobInfoType {\n val storeId: String?\n val path: String?\n val tenantId: String?\n val contentType: String?\n\n @JsExportIgnoreCompat\n val metadata: Map\n\n /** Extract the unresolved [BlobInfo] from any variant. */\n fun toBlobInfo(): BlobInfo\n}\n\n@Serializable\n@JsExportCompat\ndata class BlobMetadata(\n val contentType: String? = null,\n val contentEncoding: String? = null,\n val contentDisposition: String? = null,\n @JsExportIgnoreCompat\n val custom: Map = emptyMap(),\n val contentHash: String? = null,\n val retentionHint: RetentionHint? = null,\n /** Consumer-supplied sensitivity classification hint (e.g., \"CONFIDENTIAL\"). */\n val classification: String? = null,\n /** Consumer-supplied legal basis hint (e.g., \"gdpr.art6.1a.consent\"). */\n val legalBasis: String? = null,\n /** Consumer-supplied retention-days hint; authoritative value lives on the consumer row. */\n val retentionDays: Int? = null,\n /** Consumer-supplied processing-purpose hint (GDPR Art. 5(1)(b)). */\n val processingPurpose: String? = null,\n /** Consumer-supplied jurisdiction hint (e.g., \"EU-NL\"). */\n val jurisdiction: String? = null,\n) {\n companion object {\n val EMPTY = BlobMetadata()\n\n fun ofContentType(contentType: String) = BlobMetadata(contentType = contentType)\n }\n}\n\n@Serializable\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"BlobIdentity\", exact = true)\n@JsExportCompat\ndata class BlobIdentity(\n val storeId: String? = null,\n val path: String? = null,\n val tenantId: String? = null,\n) {\n fun hasIdentity(): Boolean = path != null\n}\n\n@Serializable\n@JsExportCompat\ndata class BlobDescriptor(\n val path: String,\n /**\n * The CONFIGURED registry id of the store this blob lives in (e.g. `\"default\"` from\n * `blob.stores.default.*`), NOT the backend scheme id ([BlobStore.schemeId], e.g. `\"memory\"`\n * or `\"filesystem\"`).\n *\n * Backend [BlobStore] implementations stamp their own scheme id here, but [BlobService]\n * normalises it to the configured id on every caller-facing descriptor before it leaves the\n * service. Callers may therefore round-trip this value straight back into [BlobInfo.storeId]\n * for a subsequent operation. Descriptors observed directly from a [BlobStore] (below the\n * service boundary) still carry the scheme id.\n */\n val storeId: String,\n val sizeBytes: Long,\n val contentType: String? = null,\n val filename: String? = null,\n val etag: String? = null,\n val createdAt: Instant? = null,\n val lastModified: Instant? = null,\n val metadata: BlobMetadata = BlobMetadata.EMPTY,\n val contentHash: String? = null,\n /** Consumer-supplied sensitivity classification hint mirrored from [BlobMetadata.classification]. */\n val classification: String? = null,\n /** Consumer-supplied legal basis hint mirrored from [BlobMetadata.legalBasis]. */\n val legalBasis: String? = null,\n /** Consumer-supplied retention-days hint mirrored from [BlobMetadata.retentionDays]. */\n val retentionDays: Int? = null,\n /** Consumer-supplied processing-purpose hint mirrored from [BlobMetadata.processingPurpose]. */\n val processingPurpose: String? = null,\n /** Consumer-supplied jurisdiction hint mirrored from [BlobMetadata.jurisdiction]. */\n val jurisdiction: String? = null,\n)" - }, - "RefreshSourceSnapshotArgs": { - "kind": "data class", - "name": "RefreshSourceSnapshotArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class RefreshSourceSnapshotArgs(\n val tenantId: String,\n val snapshotId: Uuid,\n)" - }, - "UploadDesignAssetArgs": { - "kind": "data class", - "name": "UploadDesignAssetArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class UploadDesignAssetArgs(\n val tenantId: String,\n val input: UploadDesignAssetInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class UploadDesignAssetInput(\n val designId: Uuid,\n val locale: String,\n val assetType: DesignAssetType,\n val data: ByteArray,\n val contentType: String,\n) {\n override fun equals(other: Any?): Boolean {\n if (this === other) {\n return true\n }\n if (other !is UploadDesignAssetInput) {\n return false\n }\n return designId == other.designId && locale == other.locale && assetType == other.assetType &&\n data.contentEquals(other.data) && contentType == other.contentType\n }\n\n override fun hashCode(): Int {\n var result = designId.hashCode()\n result = 31 * result + locale.hashCode()\n result = 31 * result + assetType.hashCode()\n result = 31 * result + data.contentHashCode()\n result = 31 * result + contentType.hashCode()\n return result\n }\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignAssetType {\n LOGO,\n BACKGROUND_IMAGE,\n SVG_TEMPLATE,\n PDF_TEMPLATE,\n}" - }, - "AssetReference": { - "kind": "data class", - "name": "AssetReference", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class AssetReference\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val altText: String? = null,\n val contentType: String? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@Serializable\n@SerialName(\"blob-info\")\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"BlobInfo\", exact = true)\ndata class BlobInfo(\n override val storeId: String? = null,\n override val path: String? = null,\n override val tenantId: String? = null,\n override val contentType: String? = null,\n override val metadata: Map = emptyMap(),\n @Transient\n val opts: Map = emptyMap(),\n) : BlobInfoType {\n override fun toBlobInfo(): BlobInfo = this\n\n /**\n * Returns a [BlobMetadata] from this info's content type and custom metadata.\n */\n fun toBlobMetadata(): BlobMetadata =\n BlobMetadata(\n contentType = contentType,\n custom = metadata,\n )\n\n /**\n * Lightweight identity for use as map keys and cache lookups.\n * Like [KeyIdentity] — deterministic equality without transient fields.\n */\n fun toIdentity(): BlobIdentity =\n BlobIdentity(\n storeId = storeId,\n path = path,\n tenantId = tenantId,\n )\n\n /** Creates a copy targeting a different path. */\n fun withPath(newPath: String): BlobInfo = copy(path = newPath)\n\n /** Creates a copy targeting a different store. */\n fun withStore(newStoreId: String): BlobInfo = copy(storeId = newStoreId)\n\n companion object {\n fun of(\n storeId: String,\n path: String,\n ) = BlobInfo(storeId = storeId, path = path)\n\n fun fromDescriptor(\n descriptor: BlobDescriptor,\n tenantId: String? = null,\n ) = BlobInfo(\n storeId = descriptor.storeId,\n path = descriptor.path,\n tenantId = tenantId,\n contentType = descriptor.contentType,\n metadata = descriptor.metadata.custom,\n )\n\n /**\n * Validates a blob path for security:\n * - Rejects path traversal segments (`..`)\n * - Rejects null bytes\n * - Rejects absolute paths\n * - Rejects backslash separators\n */\n fun validatePath(path: String) {\n require(!path.contains('\\u0000')) { \"Blob path must not contain null bytes\" }\n require(!path.startsWith('/')) { \"Blob path must not be absolute\" }\n require(!path.contains('\\\\')) { \"Blob path must use '/' separators, not '\\\\'\" }\n val segments = path.split('/')\n require(segments.none { it == \"..\" }) { \"Blob path must not contain '..' traversal segments: $path\" }\n require(segments.none { it == \".\" }) { \"Blob path must not contain '.' self-reference segments: $path\" }\n }\n\n /**\n * Sanitizes and normalizes a user-provided path. Returns a safe path string.\n * Throws [IllegalArgumentException] if the path is malicious.\n */\n fun sanitizePath(path: String): String {\n val normalized =\n path\n .replace('\\\\', '/')\n .replace(Regex(\"/+\"), \"/\")\n .trimStart('/')\n .trimEnd('/')\n require(normalized.isNotBlank()) { \"Sanitized path must not be blank\" }\n validatePath(normalized)\n return normalized\n }\n }\n}\n\n@Serializable\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"BlobInfoType\", exact = true)\n@JsExportCompat\nsealed interface BlobInfoType {\n val storeId: String?\n val path: String?\n val tenantId: String?\n val contentType: String?\n\n @JsExportIgnoreCompat\n val metadata: Map\n\n /** Extract the unresolved [BlobInfo] from any variant. */\n fun toBlobInfo(): BlobInfo\n}\n\n@Serializable\n@JsExportCompat\ndata class BlobMetadata(\n val contentType: String? = null,\n val contentEncoding: String? = null,\n val contentDisposition: String? = null,\n @JsExportIgnoreCompat\n val custom: Map = emptyMap(),\n val contentHash: String? = null,\n val retentionHint: RetentionHint? = null,\n /** Consumer-supplied sensitivity classification hint (e.g., \"CONFIDENTIAL\"). */\n val classification: String? = null,\n /** Consumer-supplied legal basis hint (e.g., \"gdpr.art6.1a.consent\"). */\n val legalBasis: String? = null,\n /** Consumer-supplied retention-days hint; authoritative value lives on the consumer row. */\n val retentionDays: Int? = null,\n /** Consumer-supplied processing-purpose hint (GDPR Art. 5(1)(b)). */\n val processingPurpose: String? = null,\n /** Consumer-supplied jurisdiction hint (e.g., \"EU-NL\"). */\n val jurisdiction: String? = null,\n) {\n companion object {\n val EMPTY = BlobMetadata()\n\n fun ofContentType(contentType: String) = BlobMetadata(contentType = contentType)\n }\n}\n\n@Serializable\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"BlobIdentity\", exact = true)\n@JsExportCompat\ndata class BlobIdentity(\n val storeId: String? = null,\n val path: String? = null,\n val tenantId: String? = null,\n) {\n fun hasIdentity(): Boolean = path != null\n}\n\n@Serializable\n@JsExportCompat\ndata class BlobDescriptor(\n val path: String,\n /**\n * The CONFIGURED registry id of the store this blob lives in (e.g. `\"default\"` from\n * `blob.stores.default.*`), NOT the backend scheme id ([BlobStore.schemeId], e.g. `\"memory\"`\n * or `\"filesystem\"`).\n *\n * Backend [BlobStore] implementations stamp their own scheme id here, but [BlobService]\n * normalises it to the configured id on every caller-facing descriptor before it leaves the\n * service. Callers may therefore round-trip this value straight back into [BlobInfo.storeId]\n * for a subsequent operation. Descriptors observed directly from a [BlobStore] (below the\n * service boundary) still carry the scheme id.\n */\n val storeId: String,\n val sizeBytes: Long,\n val contentType: String? = null,\n val filename: String? = null,\n val etag: String? = null,\n val createdAt: Instant? = null,\n val lastModified: Instant? = null,\n val metadata: BlobMetadata = BlobMetadata.EMPTY,\n val contentHash: String? = null,\n /** Consumer-supplied sensitivity classification hint mirrored from [BlobMetadata.classification]. */\n val classification: String? = null,\n /** Consumer-supplied legal basis hint mirrored from [BlobMetadata.legalBasis]. */\n val legalBasis: String? = null,\n /** Consumer-supplied retention-days hint mirrored from [BlobMetadata.retentionDays]. */\n val retentionDays: Int? = null,\n /** Consumer-supplied processing-purpose hint mirrored from [BlobMetadata.processingPurpose]. */\n val processingPurpose: String? = null,\n /** Consumer-supplied jurisdiction hint mirrored from [BlobMetadata.jurisdiction]. */\n val jurisdiction: String? = null,\n)" - }, - "GetDesignAssetArgs": { - "kind": "data class", - "name": "GetDesignAssetArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class GetDesignAssetArgs(\n val tenantId: String,\n val input: GetDesignAssetInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class GetDesignAssetInput(\n val designId: Uuid,\n val locale: String,\n val assetType: DesignAssetType,\n)\n\n@JsExportCompat\n@Serializable\nenum class DesignAssetType {\n LOGO,\n BACKGROUND_IMAGE,\n SVG_TEMPLATE,\n PDF_TEMPLATE,\n}" - }, - "ResolvedDesignAsset": { - "kind": "data class", - "name": "ResolvedDesignAsset", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class ResolvedDesignAsset(\n val data: ByteArray,\n val contentType: String,\n val reference: AssetReference,\n) {\n override fun equals(other: Any?): Boolean {\n if (this === other) {\n return true\n }\n if (other !is ResolvedDesignAsset) {\n return false\n }\n return data.contentEquals(other.data) && contentType == other.contentType && reference == other.reference\n }\n\n override fun hashCode(): Int {\n var result = data.contentHashCode()\n result = 31 * result + contentType.hashCode()\n result = 31 * result + reference.hashCode()\n return result\n }\n}\n\n@JsExportCompat\n@Serializable\ndata class AssetReference\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val altText: String? = null,\n val contentType: String? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@Serializable\n@SerialName(\"blob-info\")\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"BlobInfo\", exact = true)\ndata class BlobInfo(\n override val storeId: String? = null,\n override val path: String? = null,\n override val tenantId: String? = null,\n override val contentType: String? = null,\n override val metadata: Map = emptyMap(),\n @Transient\n val opts: Map = emptyMap(),\n) : BlobInfoType {\n override fun toBlobInfo(): BlobInfo = this\n\n /**\n * Returns a [BlobMetadata] from this info's content type and custom metadata.\n */\n fun toBlobMetadata(): BlobMetadata =\n BlobMetadata(\n contentType = contentType,\n custom = metadata,\n )\n\n /**\n * Lightweight identity for use as map keys and cache lookups.\n * Like [KeyIdentity] — deterministic equality without transient fields.\n */\n fun toIdentity(): BlobIdentity =\n BlobIdentity(\n storeId = storeId,\n path = path,\n tenantId = tenantId,\n )\n\n /** Creates a copy targeting a different path. */\n fun withPath(newPath: String): BlobInfo = copy(path = newPath)\n\n /** Creates a copy targeting a different store. */\n fun withStore(newStoreId: String): BlobInfo = copy(storeId = newStoreId)\n\n companion object {\n fun of(\n storeId: String,\n path: String,\n ) = BlobInfo(storeId = storeId, path = path)\n\n fun fromDescriptor(\n descriptor: BlobDescriptor,\n tenantId: String? = null,\n ) = BlobInfo(\n storeId = descriptor.storeId,\n path = descriptor.path,\n tenantId = tenantId,\n contentType = descriptor.contentType,\n metadata = descriptor.metadata.custom,\n )\n\n /**\n * Validates a blob path for security:\n * - Rejects path traversal segments (`..`)\n * - Rejects null bytes\n * - Rejects absolute paths\n * - Rejects backslash separators\n */\n fun validatePath(path: String) {\n require(!path.contains('\\u0000')) { \"Blob path must not contain null bytes\" }\n require(!path.startsWith('/')) { \"Blob path must not be absolute\" }\n require(!path.contains('\\\\')) { \"Blob path must use '/' separators, not '\\\\'\" }\n val segments = path.split('/')\n require(segments.none { it == \"..\" }) { \"Blob path must not contain '..' traversal segments: $path\" }\n require(segments.none { it == \".\" }) { \"Blob path must not contain '.' self-reference segments: $path\" }\n }\n\n /**\n * Sanitizes and normalizes a user-provided path. Returns a safe path string.\n * Throws [IllegalArgumentException] if the path is malicious.\n */\n fun sanitizePath(path: String): String {\n val normalized =\n path\n .replace('\\\\', '/')\n .replace(Regex(\"/+\"), \"/\")\n .trimStart('/')\n .trimEnd('/')\n require(normalized.isNotBlank()) { \"Sanitized path must not be blank\" }\n validatePath(normalized)\n return normalized\n }\n }\n}" - }, - "InitPipelineSessionArgs": { - "kind": "data class", - "name": "InitPipelineSessionArgs", - "module": "public", - "source": "@Serializable\ndata class InitPipelineSessionArgs(\n /** The pipeline this session runs. */\n val pipelineConfiguration: PipelineConfiguration,\n /** External correlation handle; the command generates one when absent. */\n val correlationId: String? = null,\n /** Attributes known at session init (invitation context, static-offer config, ...). */\n val initialAttributes: List = emptyList(),\n /** Lookup keys known at session init — these satisfy a source's `consumedLookupKeys` directly. */\n val initialLookupKeys: List = emptyList(),\n /** How the session payload is protected at rest. */\n val encryptionMode: SessionEncryptionMode = PlatformEncryptedMode,\n /** Session lifetime; the command applies a configured default when absent. */\n val ttlSeconds: Long? = null,\n)\n\n@JsExportCompat\n@Serializable\ndata class PipelineConfiguration(\n /** Stable identifier — referenced by [IssuancePipelineSession.pipelineId]. */\n val pipelineId: String,\n /** The attribute sources bound into this pipeline, each with its phases and binding config. */\n @JsExportIgnoreCompat\n val sourceBindings: List = emptyList(),\n /** The credentials this pipeline can assemble claims for. */\n @JsExportIgnoreCompat\n val claimsBindings: List = emptyList(),\n /**\n * Lookup keys the caller is expected to provide at session init (from invitation context,\n * static-offer config, or the init call). A source may consume one of these without any\n * other source producing it.\n */\n @JsExportIgnoreCompat\n val expectedInitialLookupKeys: Set = emptySet(),\n)\n\n@JsExportCompat\n@Serializable\ndata class AttributeRecord(\n /** Where this attribute lives in the bag. */\n val path: AttributePath,\n /** The typed value. */\n val value: AttributeValue,\n /** Which source produced this record (opaque producer id — an IDV node, a pipeline source, ...). */\n val sourceId: AttributeProvenanceRef,\n /** Source-specific detail (e.g. IDV node id, OIDC issuer, HR-API endpoint). */\n val sourceDetail: String? = null,\n /** The phase during which this record was contributed. */\n val phase: PipelinePhase,\n /** When this record was contributed. */\n val timestamp: Instant,\n /** Assurance level (from IDV evidence, OIDC `acr`, ...). */\n val assurance: EidasAssuranceLevel? = null,\n /** Conflict-resolution priority — higher wins; ties broken by [timestamp]. */\n val priority: Int = 0,\n /** Retention policy for this specific attribute. */\n val retention: AttributeRetentionPolicy = SessionRetention(),\n /** Whether this attribute has been verified by an IDV process. */\n val verified: Boolean = false,\n) {\n /**\n * The value as a [JsonElement] when it is plain data, else `null`. Blob / key / evidence\n * values are references and have no direct JSON form here — a downstream assembler handles\n * those explicitly.\n */\n val jsonValue: JsonElement?\n get() = (value as? AttributeData)?.value\n}\n\n@JsExportCompat\n@Serializable\ndata class LookupKey(\n /** Unique name within the session — e.g. `email`, `employee_id`. */\n val name: String,\n /** The key value. PII — encrypted at rest. */\n val value: String,\n /** Optional well-known classification of the key. */\n val type: LookupKeyType? = null,\n /**\n * PROVENANCE only: the single source that PRODUCED this lookup key — one producer, one\n * phase, one timestamp. This is *not* the source(s) that consume it (consumption is 1→N and\n * declared on the consuming source's `consumedLookupKeys`).\n */\n val producedBy: AttributeProvenanceRef,\n /** Source-specific detail (e.g. IDV node id, HR-API endpoint). */\n val sourceDetail: String? = null,\n /** The phase during which this key was contributed. */\n val phase: PipelinePhase,\n /** When this key was contributed. */\n val timestamp: Instant,\n /**\n * If non-null, the lookup key is ALSO emitted as an attribute at this path before credential\n * assembly, so claim mapping can pick it up. Leave null when the key is purely operational\n * (a business key) and should not appear in the credential.\n */\n val promotedToAttributePath: AttributePath? = null,\n /** Free-form metadata; e.g. verification status, source TTL. */\n val metadata: Map = emptyMap(),\n)\n\n@JsExportCompat\n@Serializable\nsealed interface SessionEncryptionMode\n\n/** No encryption — the payload is stored as plaintext. For local development / non-PII flows only. */\n@Serializable\n@SerialName(\"plaintext\")\n\n@Serializable\n@SerialName(\"platform-encrypted\")\ndata object PlatformEncryptedMode : SessionEncryptionMode\n\n/**\n * Tier 2: the effective encryption key is additionally bound to the session's `correlationId`\n * via HKDF, so decryption requires re-presenting the `correlationId`. The platform alone cannot\n * read the payload.\n *\n * @property fallbackToPlatform when true, a session whose `correlationId` cannot be re-presented\n * degrades to [PlatformEncryptedMode] semantics rather than being unreadable.\n */\n@Serializable\n@SerialName(\"client-bound\")\n\n @Serializable\n @SerialName(\"session\")\n data class Session(\n /** `null` -> use the domain default ([SessionRetention.encryptionRequired] = `true`). */\n val encryptionRequired: Boolean? = null,\n ) : RetentionDto() {\n override val kind: String = \"session\"\n }\n\n@JsExportCompat\n@Serializable\ndata class IssuancePipelineSession(\n /** Stable primary identifier. */\n val sessionId: String,\n /** The pipeline this session runs — carried on the session so a phase can be run without a separate registry lookup. */\n val pipelineConfiguration: PipelineConfiguration,\n /** The tenant this session belongs to. */\n val tenantId: String,\n /**\n * Which VDX issuer instance this session belongs to. Reserved for the multi-issuer-per-tenant\n * work; null for single-issuer deployments.\n */\n val issuerPartyId: String? = null,\n /** Lifecycle status. */\n val status: IssuancePipelineStatus,\n /** External correlation handle — the join key to the issuer-core session and all ingress paths. */\n val correlationId: String,\n /** Attributes accumulated across every phase run so far. Encrypted at rest per [encryptionMode]. */\n val bag: AttributeBag = AttributeBag.empty(),\n /** Lookup keys accumulated so far. Encrypted at rest per [encryptionMode]. */\n val lookupKeys: LookupKeySet = LookupKeySet.empty(),\n /** Phases that have completed for this session. */\n @JsExportIgnoreCompat\n val completedPhases: Set = emptySet(),\n /** The phase currently executing, if any. */\n val currentPhase: PipelinePhase? = null,\n /** Protocol-specific context the front-end adapter carries through phases (e.g. `issuer_state`). */\n @JsExportIgnoreCompat\n val protocolContext: Map = emptyMap(),\n /** Per-binding deferral state, keyed by `bindingId`. Operational metadata; stored plaintext. */\n @JsExportIgnoreCompat\n val deferralEntries: Map = emptyMap(),\n /** Approval-gate state, present when a bound credential requires approval. Encrypted at rest. */\n val approval: ApprovalState? = null,\n /** How [bag] / [lookupKeys] / [approval] are protected at rest. */\n val encryptionMode: SessionEncryptionMode = PlatformEncryptedMode,\n val createdAt: Instant,\n val updatedAt: Instant,\n val expiresAt: Instant,\n) {\n /** The id of the [pipelineConfiguration] this session runs. */\n val pipelineId: String get() = pipelineConfiguration.pipelineId\n}\n\n@JsExportCompat\n@Serializable\ndata class AttributeSourceBinding(\n /** Which source this binds — matches [AttributeSource.sourceId]. */\n val sourceId: AttributeProvenanceRef,\n /** The phases this source runs in for this pipeline. */\n @JsExportIgnoreCompat\n val phases: Set,\n /** When true, a missing required lookup key or a source failure fails the phase. */\n val required: Boolean = true,\n /**\n * How long `/credential` (or `/deferred_credential`) holds the request open waiting for this\n * source's async callback before falling back to a deferred response. `ZERO` = defer\n * immediately. Hard-capped at config-load time.\n */\n val syncWaitWindow: Duration = Duration.ZERO,\n /** Optional source-native field → semantic attribute mapping. */\n @JsExportIgnoreCompat\n val attributeMapping: List = emptyList(),\n /** Whether this source replies synchronously or via async callback. */\n val callbackStyle: CallbackStyle = CallbackStyle.SYNCHRONOUS,\n)\n\n@JsExportCompat\n@Serializable\ndata class CredentialClaimsBinding(\n /** Matches the credential's `credential_configuration_id`. */\n val id: String,\n /**\n * The semantic attribute set (OCA bundle / vocabulary subset) this credential draws from.\n * The credential-design service resolves SD policy + mandatory claims from it.\n */\n val semanticAttributeSetRef: SemanticAttributeSetRef,\n /**\n * Optional mapping FROM semantic-model attribute names TO the credential's claim structure\n * (renaming / restructuring per vct / doctype). Null when names map 1:1. NOT where selective\n * disclosure is decided.\n */\n val claimMappingConfigId: String? = null,\n /** Inline alternative to [claimMappingConfigId]. */\n val inlineClaimMappingConfig: ClaimMappingConfiguration? = null,\n /** Which of the pipeline's sources this credential consumes, per phase. */\n @JsExportIgnoreCompat\n val consumedSources: Map> = emptyMap(),\n /** Per-credential deferral policy. */\n val deferralPolicy: DeferralPolicy = DeferralPolicy.disabled(),\n)\n\n@JsExportCompat\n@Serializable(with = AttributePathSerializer::class)\ndata class AttributePath(\n val value: String,\n)\n\n@JsExportCompat\n@Serializable\nsealed interface AttributeValue\n\n/**\n * A plain data value (string, number, boolean, object, array). Becomes a credential \"claim\"\n * only once a downstream assembler maps it into a credential.\n */\n@Serializable\n@SerialName(\"data\")\n\n@JsExportCompat\n@Serializable(with = AttributeProvenanceRefSerializer::class)\ndata class AttributeProvenanceRef(\n val value: String,\n)\n\n sealed class Source {\n /**\n * Load keystore data from a file path.\n * @param path the filesystem path to the keystore file\n */\n data class File(\n val path: String,\n val autoCreate: Boolean = true,\n ) : Source()\n\n /**\n * Load keystore data from an in-memory byte array.\n * @param data the raw keystore bytes\n */\n data class Bytes(\n var data: ByteArray,\n ) : Source() {\n override fun equals(other: Any?): Boolean {\n if (this === other) {\n return true\n }\n if (other == null || this::class != other::class) {\n return false\n }\n\n other as Bytes\n\n if (!data.contentEquals(other.data)) {\n return false\n }\n\n return true\n }\n\n override fun hashCode(): Int = data.contentHashCode()\n }\n\n /**\n * Load keystore data from a ByteReadChannel.\n * @param channel the [ByteChannel] supplying the keystore bytes\n */\n data class Channel(\n val channel: ByteChannel,\n ) : Source()\n }" - }, - "InitPipelineSessionResult": { - "kind": "data class", - "name": "InitPipelineSessionResult", - "module": "public", - "source": "@Serializable\ndata class InitPipelineSessionResult(\n val sessionId: String,\n /** The correlation handle — generated when the caller did not supply one. */\n val correlationId: String,\n)" - }, - "ContributeAttributesArgs": { - "kind": "data class", - "name": "ContributeAttributesArgs", - "module": "public", - "source": "@Serializable\ndata class ContributeAttributesArgs(\n /** The session to contribute to. */\n val correlationId: String,\n /** The phase to run. */\n val phase: PipelinePhase,\n /** Attributes pushed in as input for this phase (from a backend push, a callback, ...). */\n val attributes: List = emptyList(),\n /** Lookup keys pushed in as input for this phase. */\n val lookupKeys: List = emptyList(),\n)\n\n@JsExportCompat\n@Serializable\ndata class PipelinePhase(\n val value: String,\n) {\n companion object {\n /** Session / offer creation — initial attributes injected by the caller. */\n val SESSION_INIT = PipelinePhase(\"session_init\")\n\n /**\n * Generic, channel-neutral attribute resolution — the phase a non-credential caller (a form,\n * portal page, PDF/API render, or a standalone semantic-enrichment lookup) uses to resolve\n * attributes from bound sources without any issuance flow. Lets the pipeline drive every\n * channel, not only credential issuance.\n */\n val RESOLUTION = PipelinePhase(\"resolution\")\n\n /** Identity verification completed — IDV results are available. */\n val IDV_COMPLETED = PipelinePhase(\"idv_completed\")\n\n /** Credential assembly — final enrichment before credential construction. */\n val CREDENTIAL_ASSEMBLY = PipelinePhase(\"credential_assembly\")\n\n /** Post-issuance — audit, cleanup, retention enforcement. */\n val POST_ISSUANCE = PipelinePhase(\"post_issuance\")\n }\n}\n\n@JsExportCompat\n@Serializable\ndata class AttributeRecord(\n /** Where this attribute lives in the bag. */\n val path: AttributePath,\n /** The typed value. */\n val value: AttributeValue,\n /** Which source produced this record (opaque producer id — an IDV node, a pipeline source, ...). */\n val sourceId: AttributeProvenanceRef,\n /** Source-specific detail (e.g. IDV node id, OIDC issuer, HR-API endpoint). */\n val sourceDetail: String? = null,\n /** The phase during which this record was contributed. */\n val phase: PipelinePhase,\n /** When this record was contributed. */\n val timestamp: Instant,\n /** Assurance level (from IDV evidence, OIDC `acr`, ...). */\n val assurance: EidasAssuranceLevel? = null,\n /** Conflict-resolution priority — higher wins; ties broken by [timestamp]. */\n val priority: Int = 0,\n /** Retention policy for this specific attribute. */\n val retention: AttributeRetentionPolicy = SessionRetention(),\n /** Whether this attribute has been verified by an IDV process. */\n val verified: Boolean = false,\n) {\n /**\n * The value as a [JsonElement] when it is plain data, else `null`. Blob / key / evidence\n * values are references and have no direct JSON form here — a downstream assembler handles\n * those explicitly.\n */\n val jsonValue: JsonElement?\n get() = (value as? AttributeData)?.value\n}\n\n@JsExportCompat\n@Serializable\ndata class LookupKey(\n /** Unique name within the session — e.g. `email`, `employee_id`. */\n val name: String,\n /** The key value. PII — encrypted at rest. */\n val value: String,\n /** Optional well-known classification of the key. */\n val type: LookupKeyType? = null,\n /**\n * PROVENANCE only: the single source that PRODUCED this lookup key — one producer, one\n * phase, one timestamp. This is *not* the source(s) that consume it (consumption is 1→N and\n * declared on the consuming source's `consumedLookupKeys`).\n */\n val producedBy: AttributeProvenanceRef,\n /** Source-specific detail (e.g. IDV node id, HR-API endpoint). */\n val sourceDetail: String? = null,\n /** The phase during which this key was contributed. */\n val phase: PipelinePhase,\n /** When this key was contributed. */\n val timestamp: Instant,\n /**\n * If non-null, the lookup key is ALSO emitted as an attribute at this path before credential\n * assembly, so claim mapping can pick it up. Leave null when the key is purely operational\n * (a business key) and should not appear in the credential.\n */\n val promotedToAttributePath: AttributePath? = null,\n /** Free-form metadata; e.g. verification status, source TTL. */\n val metadata: Map = emptyMap(),\n)\n\n @Serializable\n @SerialName(\"session\")\n data class Session(\n /** `null` -> use the domain default ([SessionRetention.encryptionRequired] = `true`). */\n val encryptionRequired: Boolean? = null,\n ) : RetentionDto() {\n override val kind: String = \"session\"\n }\n\n data class Generic(\n val exception: Throwable? = null,\n override val message: String = \"Consent error\",\n ) : ConsentError\n\n@JsExportCompat\n@Serializable\ndata class Identity\n @JvmOverloads\n constructor(\n /** Party ID - serves as the primary key */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Tenant this identity belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The role of this identity in the credential ecosystem */\n @SerialName(\"identityRole\")\n val identityRole: IdentityRole,\n /** Whether this is the default identity for the owning party */\n @SerialName(\"isDefault\")\n val isDefault: Boolean = false,\n /** Opaque per-identity salt handle (reference only; no crypto in this layer) */\n @SerialName(\"saltRef\")\n val saltRef: String? = null,\n /** When the identity was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the identity (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the identity was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the identity (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the identity was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the identity (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n )\n\n data class Post(\n val credentials: ClientCredentials,\n ) : ClientAuthenticationConfig\n\n@JsExportCompat\n@Serializable(with = AttributePathSerializer::class)\ndata class AttributePath(\n val value: String,\n)\n\n@JsExportCompat\n@Serializable\nsealed interface AttributeValue\n\n/**\n * A plain data value (string, number, boolean, object, array). Becomes a credential \"claim\"\n * only once a downstream assembler maps it into a credential.\n */\n@Serializable\n@SerialName(\"data\")\n\n@JsExportCompat\n@Serializable(with = AttributeProvenanceRefSerializer::class)\ndata class AttributeProvenanceRef(\n val value: String,\n)\n\n sealed class Source {\n /**\n * Load keystore data from a file path.\n * @param path the filesystem path to the keystore file\n */\n data class File(\n val path: String,\n val autoCreate: Boolean = true,\n ) : Source()\n\n /**\n * Load keystore data from an in-memory byte array.\n * @param data the raw keystore bytes\n */\n data class Bytes(\n var data: ByteArray,\n ) : Source() {\n override fun equals(other: Any?): Boolean {\n if (this === other) {\n return true\n }\n if (other == null || this::class != other::class) {\n return false\n }\n\n other as Bytes\n\n if (!data.contentEquals(other.data)) {\n return false\n }\n\n return true\n }\n\n override fun hashCode(): Int = data.contentHashCode()\n }\n\n /**\n * Load keystore data from a ByteReadChannel.\n * @param channel the [ByteChannel] supplying the keystore bytes\n */\n data class Channel(\n val channel: ByteChannel,\n ) : Source()\n }\n\n@JsExportCompat\n@Serializable\nenum class EidasAssuranceLevel(\n val serializedValue: String,\n) {\n @SerialName(\"low\")\n LOW(\"low\"),\n\n @SerialName(\"substantial\")\n SUBSTANTIAL(\"substantial\"),\n\n @SerialName(\"high\")\n HIGH(\"high\"),\n}\n\n@JsExportCompat\n@Serializable\nsealed interface AttributeRetentionPolicy\n\n/** In-memory only. Never serialized to persistent storage. */\n@Serializable\n@SerialName(\"ephemeral\")" - }, - "ContributeAttributesResult": { - "kind": "data class", - "name": "ContributeAttributesResult", - "module": "public", - "source": "@Serializable\ndata class ContributeAttributesResult(\n val sessionId: String,\n /** The session status after the phase ran. */\n val status: IssuancePipelineStatus,\n /** Phases completed for the session, including this one. */\n val completedPhases: Set,\n)\n\n@JsExportCompat\nenum class IssuancePipelineStatus {\n /** Session created; no phase has run yet. */\n CREATED,\n\n /** A phase's sources are currently executing. */\n PHASE_EXECUTING,\n\n /** A phase finished; the session is between phases. */\n PHASE_COMPLETED,\n\n /** `/credential` returned 202; waiting for deferred attribute ingress. */\n AWAITING_DEFERRED,\n\n /** Required attributes are complete but an approver has not yet decided. */\n AWAITING_APPROVAL,\n\n /** All bindings complete and approved (if required); claims can be assembled. */\n READY,\n\n /** Issuance finished for every bound credential. */\n COMPLETED,\n\n /** The session failed terminally. */\n FAILED,\n\n /** The session passed its `expiresAt` without completing. */\n EXPIRED,\n}\n\n@JsExportCompat\n@Serializable\ndata class PipelinePhase(\n val value: String,\n) {\n companion object {\n /** Session / offer creation — initial attributes injected by the caller. */\n val SESSION_INIT = PipelinePhase(\"session_init\")\n\n /**\n * Generic, channel-neutral attribute resolution — the phase a non-credential caller (a form,\n * portal page, PDF/API render, or a standalone semantic-enrichment lookup) uses to resolve\n * attributes from bound sources without any issuance flow. Lets the pipeline drive every\n * channel, not only credential issuance.\n */\n val RESOLUTION = PipelinePhase(\"resolution\")\n\n /** Identity verification completed — IDV results are available. */\n val IDV_COMPLETED = PipelinePhase(\"idv_completed\")\n\n /** Credential assembly — final enrichment before credential construction. */\n val CREDENTIAL_ASSEMBLY = PipelinePhase(\"credential_assembly\")\n\n /** Post-issuance — audit, cleanup, retention enforcement. */\n val POST_ISSUANCE = PipelinePhase(\"post_issuance\")\n }\n}\n\n @Serializable\n @SerialName(\"session\")\n data class Session(\n /** `null` -> use the domain default ([SessionRetention.encryptionRequired] = `true`). */\n val encryptionRequired: Boolean? = null,\n ) : RetentionDto() {\n override val kind: String = \"session\"\n }\n\n @Serializable\r\n @SerialName(\"Required\")\r\n data class Required(\r\n val message: String? = null,\r\n ) : FieldValidationRule\n\n data class Generic(\n val exception: Throwable? = null,\n override val message: String = \"Consent error\",\n ) : ConsentError\n\n@JsExportCompat\n@Serializable\ndata class Identity\n @JvmOverloads\n constructor(\n /** Party ID - serves as the primary key */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Tenant this identity belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The role of this identity in the credential ecosystem */\n @SerialName(\"identityRole\")\n val identityRole: IdentityRole,\n /** Whether this is the default identity for the owning party */\n @SerialName(\"isDefault\")\n val isDefault: Boolean = false,\n /** Opaque per-identity salt handle (reference only; no crypto in this layer) */\n @SerialName(\"saltRef\")\n val saltRef: String? = null,\n /** When the identity was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the identity (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the identity was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the identity (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the identity was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the identity (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n )\n\n data class Post(\n val credentials: ClientCredentials,\n ) : ClientAuthenticationConfig" - }, - "GetSessionAttributesArgs": { - "kind": "data class", - "name": "GetSessionAttributesArgs", - "module": "public", - "source": "@Serializable\ndata class GetSessionAttributesArgs(\n /** The session whose attributes are read. */\n val correlationId: String,\n)" - }, - "GetSessionAttributesResult": { - "kind": "data class", - "name": "GetSessionAttributesResult", - "module": "public", - "source": "@Serializable\ndata class GetSessionAttributesResult(\n /**\n * The effective attribute data records from the session bag, keyed by attribute path string.\n * Only records whose value is plain attribute data are included; blob / key / evidence\n * references have no direct JSON form and are omitted.\n */\n val attributes: Map,\n /**\n * The names of lookup keys that have a non-null promotedToAttributePath: i.e. the keys\n * that will be emitted as attributes during credential assembly. The key VALUES are omitted:\n * they are PII and are never returned in the clear over REST.\n */\n val promotedLookupKeyNames: List,\n)\n\n-- discriminator-tagged sealed-interface JSON via kotlinx-serialization." - }, - "EvaluateAttributeCompletenessArgs": { - "kind": "data class", - "name": "EvaluateAttributeCompletenessArgs", - "module": "public", - "source": "@Serializable\ndata class EvaluateAttributeCompletenessArgs(\n /** The session whose bag is evaluated. */\n val correlationId: String,\n)" - }, - "EvaluateAttributeCompletenessResult": { - "kind": "data class", - "name": "EvaluateAttributeCompletenessResult", - "module": "public", - "source": "@Serializable\ndata class EvaluateAttributeCompletenessResult(\n /** One verdict per credential-claims binding in the session's pipeline configuration. */\n val verdicts: List,\n)\n\n@Serializable\ndata class BindingCompletenessVerdict(\n /** The `CredentialClaimsBinding.id` this verdict is for. */\n val bindingId: String,\n /** True when every mandatory attribute path is present in the bag. */\n val complete: Boolean,\n /** Mandatory attribute paths still missing from the bag. Empty when [complete]. */\n val missingRequiredPaths: List = emptyList(),\n /**\n * True when the binding is incomplete and its `DeferralPolicy.enabled` is set — i.e. the\n * issuer-side wiring should defer rather than fail. False when incomplete but deferral is\n * disabled (the request should fail) or when [complete].\n */\n val deferralRecommended: Boolean = false,\n /**\n * True when the binding's `DeferralPolicy.approvalRequired` is set and the session has not\n * yet been approved. Even a [complete] binding must defer (HTTP 202) while this is true:\n * the credential is not issued until an approver grants it.\n */\n val awaitingApproval: Boolean = false,\n)\n\n@JsExportCompat\n@Serializable\ndata class CredentialClaimsBinding(\n /** Matches the credential's `credential_configuration_id`. */\n val id: String,\n /**\n * The semantic attribute set (OCA bundle / vocabulary subset) this credential draws from.\n * The credential-design service resolves SD policy + mandatory claims from it.\n */\n val semanticAttributeSetRef: SemanticAttributeSetRef,\n /**\n * Optional mapping FROM semantic-model attribute names TO the credential's claim structure\n * (renaming / restructuring per vct / doctype). Null when names map 1:1. NOT where selective\n * disclosure is decided.\n */\n val claimMappingConfigId: String? = null,\n /** Inline alternative to [claimMappingConfigId]. */\n val inlineClaimMappingConfig: ClaimMappingConfiguration? = null,\n /** Which of the pipeline's sources this credential consumes, per phase. */\n @JsExportIgnoreCompat\n val consumedSources: Map> = emptyMap(),\n /** Per-credential deferral policy. */\n val deferralPolicy: DeferralPolicy = DeferralPolicy.disabled(),\n)\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTrue\")\n @Serializable(with = CDDLSerializer::class)\n object True : CDDL(\"true\", MajorType.SPECIAL, 21) {\n fun newTrue() = CborSimple.TRUE\n\n fun fromJson(value: JsonPrimitive) = CborSimple.TRUE\n }\n\n data object Empty : GenericHttpBody() {\n override val isEmpty: Boolean = true\n\n override fun asTextOrNull(): String? = null\n\n override fun asBytesOrNull(): ByteArray? = null\n }\n\n@JsExportCompat\n@Serializable(with = AttributePathSerializer::class)\ndata class AttributePath(\n val value: String,\n)\n\n@JsExportCompat\n@Serializable\ndata class DeferralPolicy(\n /** When false, missing required attributes fail the credential request rather than deferring. */\n val enabled: Boolean = false,\n /** Hint to the wallet for the `/deferred_credential` poll interval. */\n val pollIntervalSeconds: Int = 60,\n /** Max time from the first `/credential` 202 until the pipeline gives up. Defaults to 7 days. */\n val maxDeferralSeconds: Long = 7L * 24 * 3600,\n /**\n * When true, even with all required attributes present the session moves to an\n * awaiting-approval state rather than issuing — an explicit approval is required.\n */\n val approvalRequired: Boolean = false,\n) {\n companion object {\n fun disabled(): DeferralPolicy = DeferralPolicy(enabled = false)\n }\n}\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFalse\")\n @Serializable(with = CDDLSerializer::class)\n object False : CDDL(\"false\", MajorType.SPECIAL, 20) {\n fun newFalse() = CborSimple.FALSE\n\n fun fromJson(value: JsonPrimitive) = CborSimple.FALSE\n }" - }, - "ApprovePipelineSessionArgs": { - "kind": "data class", - "name": "ApprovePipelineSessionArgs", - "module": "public", - "source": "@Serializable\ndata class ApprovePipelineSessionArgs(\n /** The external correlation handle identifying the session to approve or reject. */\n val correlationId: String,\n /** The decision taken by the approver. */\n val decision: ApprovalDecision,\n /** Human-readable reason; required on [ApprovalDecision.REJECT], optional on [ApprovalDecision.APPROVE]. */\n val reason: String? = null,\n /** Supporting evidence captured at approval time; recorded in the bag on [ApprovalDecision.APPROVE]. */\n val evidence: AttributeEvidence? = null,\n)\n\n@Serializable\nenum class ApprovalDecision {\n APPROVE,\n REJECT,\n}\n\n @Serializable\n data class Human(\n override val id: String,\n /** Correlation key the engine binds to; UI signals completion against this key. */\n val correlationKey: String,\n /** Bounded wait; null means wait until the workflow's overall deadline. */\n val timeoutSeconds: Long? = null,\n val next: String? = null,\n ) : WorkflowTask()\n\n@Serializable\n@SerialName(\"evidence\")\ndata class AttributeEvidence(\n val evidenceId: String,\n val evidenceType: String,\n val hash: String? = null,\n val hashAlgorithm: String? = null,\n val blobInfo: BlobInfo? = null,\n val uri: String? = null,\n val metadata: Map = emptyMap(),\n) : AttributeValue\n\n@Serializable\nsealed class WorkflowTask {\n abstract val id: String\n\n /** Invoke a [com.sphereon.core.api.service.ServiceCommand] and pass its output to the next task. */\n @Serializable\n data class System(\n override val id: String,\n val commandId: String,\n /** Mapping expression (engine-interpreted) producing the command's input from prior outputs. */\n val inputExpression: String,\n val next: String? = null,\n ) : WorkflowTask()\n\n /** Wait for an out-of-band signal (form submission, approval, IDV completion). */\n @Serializable\n data class Human(\n override val id: String,\n /** Correlation key the engine binds to; UI signals completion against this key. */\n val correlationKey: String,\n /** Bounded wait; null means wait until the workflow's overall deadline. */\n val timeoutSeconds: Long? = null,\n val next: String? = null,\n ) : WorkflowTask()\n\n /** Conditional branch on the current payload. */\n @Serializable\n data class Branch(\n override val id: String,\n val conditionExpression: String,\n val thenNext: String,\n val elseNext: String,\n ) : WorkflowTask()\n\n /**\n * Schedule a language-native Temporal activity by name on a dedicated task\n * queue (Pattern B in `distributed-execution.md` §5.2): the workflow does\n * not need a JVM `@ActivityInterface` for the activity type — it is\n * dispatched untyped via Temporal's `newUntypedActivityStub(...)`. The\n * non-JVM worker (Rust, Python, …) registers the activity directly with\n * its language SDK and polls [taskQueue]; the workflow addresses it by\n * [activityName].\n *\n * Bytes-typed boundary: the activity input bytes are produced from the\n * current payload by [inputExpression] (same semantics as\n * [WorkflowTask.System.inputExpression]); the activity returns\n * `ByteArray` and that becomes the new current payload. The worker\n * (de)serialises the bytes against whatever shape it advertises.\n *\n * **Tenant context propagation.** Tenant id, correlation id, blob\n * references, and the `blob_auth` envelope (Gap 5) must be embedded\n * **inside the bytes produced by [inputExpression]** — this is the\n * workflow author's responsibility, not the interpreter's. Workflow-\n * level memo / search attributes / activity headers carry trace context\n * separately (see `lib/temporal/docs/operator.md` §12).\n *\n * **Determinism.** All timeouts and retry are required-or-defaulted at\n * task-definition time; the workflow body must not read config / DI when\n * building the `ActivityOptions` (same rule as Gap 1).\n *\n * @param activityName Activity type as registered by the non-JVM worker.\n * Engine-neutral by convention — engine selection happens at the\n * task-queue level, not in the activity name (e.g. `\"ocr.process\"`,\n * not `\"ocr.tesseract.process\"`).\n * @param taskQueue Task queue the worker polls (e.g. `\"ocr.tesseract\"`).\n * @param inputExpression Mapping expression producing the activity input\n * bytes from the current payload — same shape as `System.inputExpression`.\n * @param startToCloseTimeoutMs Wall-clock budget for one attempt.\n * @param heartbeatTimeoutMs Liveness window for heartbeating activities;\n * `null` if the activity does not heartbeat.\n * @param retryMaxAttempts Maximum Temporal-level attempts before the\n * workflow sees the failure. Defaults to 3.\n * @param next Id of the next task; `null` terminates the workflow.\n */\n @Serializable\n data class NativeActivity(\n override val id: String,\n val activityName: String,\n val taskQueue: String,\n val inputExpression: String,\n val startToCloseTimeoutMs: Long,\n val heartbeatTimeoutMs: Long? = null,\n val retryMaxAttempts: Int = 3,\n val next: String? = null,\n ) : WorkflowTask()\n}\n\n@Serializable\n@SerialName(\"blob-info\")\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"BlobInfo\", exact = true)\ndata class BlobInfo(\n override val storeId: String? = null,\n override val path: String? = null,\n override val tenantId: String? = null,\n override val contentType: String? = null,\n override val metadata: Map = emptyMap(),\n @Transient\n val opts: Map = emptyMap(),\n) : BlobInfoType {\n override fun toBlobInfo(): BlobInfo = this\n\n /**\n * Returns a [BlobMetadata] from this info's content type and custom metadata.\n */\n fun toBlobMetadata(): BlobMetadata =\n BlobMetadata(\n contentType = contentType,\n custom = metadata,\n )\n\n /**\n * Lightweight identity for use as map keys and cache lookups.\n * Like [KeyIdentity] — deterministic equality without transient fields.\n */\n fun toIdentity(): BlobIdentity =\n BlobIdentity(\n storeId = storeId,\n path = path,\n tenantId = tenantId,\n )\n\n /** Creates a copy targeting a different path. */\n fun withPath(newPath: String): BlobInfo = copy(path = newPath)\n\n /** Creates a copy targeting a different store. */\n fun withStore(newStoreId: String): BlobInfo = copy(storeId = newStoreId)\n\n companion object {\n fun of(\n storeId: String,\n path: String,\n ) = BlobInfo(storeId = storeId, path = path)\n\n fun fromDescriptor(\n descriptor: BlobDescriptor,\n tenantId: String? = null,\n ) = BlobInfo(\n storeId = descriptor.storeId,\n path = descriptor.path,\n tenantId = tenantId,\n contentType = descriptor.contentType,\n metadata = descriptor.metadata.custom,\n )\n\n /**\n * Validates a blob path for security:\n * - Rejects path traversal segments (`..`)\n * - Rejects null bytes\n * - Rejects absolute paths\n * - Rejects backslash separators\n */\n fun validatePath(path: String) {\n require(!path.contains('\\u0000')) { \"Blob path must not contain null bytes\" }\n require(!path.startsWith('/')) { \"Blob path must not be absolute\" }\n require(!path.contains('\\\\')) { \"Blob path must use '/' separators, not '\\\\'\" }\n val segments = path.split('/')\n require(segments.none { it == \"..\" }) { \"Blob path must not contain '..' traversal segments: $path\" }\n require(segments.none { it == \".\" }) { \"Blob path must not contain '.' self-reference segments: $path\" }\n }\n\n /**\n * Sanitizes and normalizes a user-provided path. Returns a safe path string.\n * Throws [IllegalArgumentException] if the path is malicious.\n */\n fun sanitizePath(path: String): String {\n val normalized =\n path\n .replace('\\\\', '/')\n .replace(Regex(\"/+\"), \"/\")\n .trimStart('/')\n .trimEnd('/')\n require(normalized.isNotBlank()) { \"Sanitized path must not be blank\" }\n validatePath(normalized)\n return normalized\n }\n }\n}\n\n@JsExportCompat\n@Serializable\nsealed interface AttributeValue\n\n/**\n * A plain data value (string, number, boolean, object, array). Becomes a credential \"claim\"\n * only once a downstream assembler maps it into a credential.\n */\n@Serializable\n@SerialName(\"data\")" - }, - "ApprovePipelineSessionResult": { - "kind": "data class", - "name": "ApprovePipelineSessionResult", - "module": "public", - "source": "@Serializable\ndata class ApprovePipelineSessionResult(\n /** The session's correlation id, echoed back for convenience. */\n val correlationId: String,\n /** The new lifecycle status after the decision was applied. */\n val status: IssuancePipelineStatus,\n)\n\n@JsExportCompat\nenum class IssuancePipelineStatus {\n /** Session created; no phase has run yet. */\n CREATED,\n\n /** A phase's sources are currently executing. */\n PHASE_EXECUTING,\n\n /** A phase finished; the session is between phases. */\n PHASE_COMPLETED,\n\n /** `/credential` returned 202; waiting for deferred attribute ingress. */\n AWAITING_DEFERRED,\n\n /** Required attributes are complete but an approver has not yet decided. */\n AWAITING_APPROVAL,\n\n /** All bindings complete and approved (if required); claims can be assembled. */\n READY,\n\n /** Issuance finished for every bound credential. */\n COMPLETED,\n\n /** The session failed terminally. */\n FAILED,\n\n /** The session passed its `expiresAt` without completing. */\n EXPIRED,\n}\n\n @Serializable\n @SerialName(\"session\")\n data class Session(\n /** `null` -> use the domain default ([SessionRetention.encryptionRequired] = `true`). */\n val encryptionRequired: Boolean? = null,\n ) : RetentionDto() {\n override val kind: String = \"session\"\n }\n\n @Serializable\r\n @SerialName(\"Required\")\r\n data class Required(\r\n val message: String? = null,\r\n ) : FieldValidationRule" - }, - "FailPipelineSourceArgs": { - "kind": "data class", - "name": "FailPipelineSourceArgs", - "module": "public", - "source": "@Serializable\ndata class FailPipelineSourceArgs(\n /** The external correlation handle identifying the pipeline session. */\n val correlationId: String,\n /** The opaque source identifier (matches `AttributeProvenanceRef.value`). */\n val sourceId: String,\n /** Optional human-readable reason recorded with the failure marker. */\n val reason: String? = null,\n)\n\n@JsExportCompat\n@Serializable(with = AttributeProvenanceRefSerializer::class)\ndata class AttributeProvenanceRef(\n val value: String,\n)\n\nobject AttributeProvenanceRefSerializer : KSerializer {\n override val descriptor: SerialDescriptor =\n PrimitiveSerialDescriptor(\"com.sphereon.attribute.flow.AttributeProvenanceRef\", PrimitiveKind.STRING)\n\n override fun serialize(\n encoder: Encoder,\n value: AttributeProvenanceRef\n ) = encoder.encodeString(value.value)\n\n override fun deserialize(decoder: Decoder): AttributeProvenanceRef = AttributeProvenanceRef(decoder.decodeString())\n}" - }, - "FailPipelineSourceResult": { - "kind": "data class", - "name": "FailPipelineSourceResult", - "module": "public", - "source": "@Serializable\ndata class FailPipelineSourceResult(\n /** The session's correlation id, echoed back for convenience. */\n val correlationId: String,\n /** The source id whose contribution was marked as failed. */\n val sourceId: String,\n)" - }, - "CreateDcqlQueryArgs": { - "kind": "data class", - "name": "CreateDcqlQueryArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class CreateDcqlQueryArgs(\n val queryId: String,\n val name: String,\n val description: String? = null,\n val dcqlQuery: DcqlQuery,\n val enabled: Boolean = true,\n)\n\n@Serializable\n@JsExportCompat\ndata class DcqlQuery(\n val credentials: List? = null,\n val credential_sets: List? = null,\n) {\n init {\n require(credentials != null || credential_sets != null) {\n \"At least one of 'credentials' or 'credential_sets' must be present\"\n }\n }\n}\n\n@Serializable\n@JsExportCompat\ndata class DcqlCredentialQuery(\n val id: String,\n val format: String? = null,\n val meta: JsonObject? = null,\n val claims: List? = null,\n val claim_sets: List? = null,\n val require_cryptographic_holder_binding: Boolean = true,\n val multiple: Boolean = false,\n @SerialName(\"trusted_authorities\")\n val trusted_authorities: List? = null,\n) {\n /**\n * Normalized trusted authorities with duplicate types automatically combined.\n *\n * When multiple authority entries of the same type exist in trusted_authorities,\n * they are automatically combined into a single entry with all values merged.\n * This prevents logic/validation problems by external parties.\n *\n * This property is computed in the init block and always reflects the deduplicated state.\n *\n * Example:\n * ```kotlin\n * // Input during construction/deserialization:\n * listOf(\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed1.com\")),\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed2.com\"))\n * )\n * // Automatically normalized to:\n * listOf(\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed1.com\", \"https://fed2.com\"))\n * )\n * ```\n */\n @Transient\n val normalizedTrustedAuthorities: List? = trusted_authorities?.let { normalizeTrustedAuthorities(it) }\n\n companion object {\n /**\n * Combines multiple trusted authority entries of the same type into single entries.\n *\n * @param authorities Original list that may contain duplicate types\n * @return List with duplicate types merged, maintaining order of first occurrence\n */\n private fun normalizeTrustedAuthorities(authorities: List): List {\n if (authorities.isEmpty()) {\n return authorities\n }\n\n // Group by type and combine all values\n val grouped = authorities.groupBy { it.type }\n\n // Maintain order of first occurrence for each type\n return authorities\n .distinctBy { it.type }\n .map { firstOfType ->\n val allValues = grouped[firstOfType.type]!!.flatMap { it.values }.distinct()\n DcqlTrustedAuthority(\n type = firstOfType.type,\n values = allValues,\n )\n }\n }\n }\n}\n\n@Serializable\n@JsExportCompat\ndata class DcqlCredentialSetQuery(\n val required: Boolean = false,\n val options: List,\n)" - }, - "DcqlQueryConfiguration": { - "kind": "data class", - "name": "DcqlQueryConfiguration", - "module": "public", - "source": "@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"DcqlQueryConfiguration\", exact = true)\n@JsExportCompat\n@Serializable\ndata class DcqlQueryConfiguration(\n val queryId: String,\n val name: String,\n val description: String? = null,\n val dcqlQuery: DcqlQuery,\n val enabled: Boolean = true,\n val createdAt: Long,\n val updatedAt: Long,\n /**\n * The version number of the currently active DCQL body, when the configuration is backed\n * by a version-history store. Null for stores without versioning (the IDK KV/SQLite\n * backings); set by the EDK versioned store.\n */\n val currentVersion: Int? = null,\n)\n\n@Serializable\n@JsExportCompat\ndata class DcqlQuery(\n val credentials: List? = null,\n val credential_sets: List? = null,\n) {\n init {\n require(credentials != null || credential_sets != null) {\n \"At least one of 'credentials' or 'credential_sets' must be present\"\n }\n }\n}\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNull\")\n @Serializable(with = CDDLSerializer::class)\n object Null : CDDL(\"null\", MajorType.SPECIAL, 22, arrayOf(nil)) {\n fun newNull() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n@Serializable\n@JsExportCompat\ndata class DcqlCredentialQuery(\n val id: String,\n val format: String? = null,\n val meta: JsonObject? = null,\n val claims: List? = null,\n val claim_sets: List? = null,\n val require_cryptographic_holder_binding: Boolean = true,\n val multiple: Boolean = false,\n @SerialName(\"trusted_authorities\")\n val trusted_authorities: List? = null,\n) {\n /**\n * Normalized trusted authorities with duplicate types automatically combined.\n *\n * When multiple authority entries of the same type exist in trusted_authorities,\n * they are automatically combined into a single entry with all values merged.\n * This prevents logic/validation problems by external parties.\n *\n * This property is computed in the init block and always reflects the deduplicated state.\n *\n * Example:\n * ```kotlin\n * // Input during construction/deserialization:\n * listOf(\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed1.com\")),\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed2.com\"))\n * )\n * // Automatically normalized to:\n * listOf(\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed1.com\", \"https://fed2.com\"))\n * )\n * ```\n */\n @Transient\n val normalizedTrustedAuthorities: List? = trusted_authorities?.let { normalizeTrustedAuthorities(it) }\n\n companion object {\n /**\n * Combines multiple trusted authority entries of the same type into single entries.\n *\n * @param authorities Original list that may contain duplicate types\n * @return List with duplicate types merged, maintaining order of first occurrence\n */\n private fun normalizeTrustedAuthorities(authorities: List): List {\n if (authorities.isEmpty()) {\n return authorities\n }\n\n // Group by type and combine all values\n val grouped = authorities.groupBy { it.type }\n\n // Maintain order of first occurrence for each type\n return authorities\n .distinctBy { it.type }\n .map { firstOfType ->\n val allValues = grouped[firstOfType.type]!!.flatMap { it.values }.distinct()\n DcqlTrustedAuthority(\n type = firstOfType.type,\n values = allValues,\n )\n }\n }\n }\n}\n\n@Serializable\n@JsExportCompat\ndata class DcqlCredentialSetQuery(\n val required: Boolean = false,\n val options: List,\n)\n\ninternal object CDDLSerializer : KSerializer {\n override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(\"CDDL\", PrimitiveKind.STRING)\n\n override fun serialize(\n encoder: Encoder,\n value: CDDL,\n ) {\n encoder.encodeString(value.format)\n }\n\n override fun deserialize(decoder: Decoder): CDDL = CDDL.util.fromFormat(decoder.decodeString())\n}\n\n@Suppress(\"UNCHECKED_CAST\")\n@JsExportCompat\n@Serializable(with = CDDLSerializer::class)\nsealed class CDDL(\n override val format: String,\n override val majorType: MajorType? = null,\n override val info: Int? = null,\n override val aliasFor: Array = arrayOf(),\n) : CDDLType {\n override fun newCborItemFromJson(\n element: JsonElement?,\n cddl: CDDLType?,\n ): CborItem {\n val jsonPrimitive: JsonPrimitive? = (element as? JsonPrimitive)?.jsonPrimitive\n val jsonArray: JsonArray? = (element as? JsonArray)?.jsonArray\n val jsonObject: JsonObject? = (element as? JsonObject)?.jsonObject\n val isNull: Boolean = element == JsonNull || element === null\n val isString: Boolean = jsonPrimitive?.isString == true\n\n if (isNull) {\n return CborNull()\n } else if (isString && jsonPrimitive !== null) {\n return CborString(jsonPrimitive.content)\n } else if (jsonArray !== null) {\n return list.fromJson(jsonArray)\n } else if (jsonObject !== null) {\n if (CborItemJson.isCborItemValueJson(jsonObject)) {\n val key =\n if (CborItemJson.isCborItemJson(jsonObject)) {\n (jsonObject[\"key\"] as? JsonPrimitive)?.content\n } else {\n null\n }\n val cddlStr = (jsonObject[\"cddl\"] as? JsonPrimitive)?.content\n\n if (cddlStr === null) {\n // cddl key found, but wasn't a primitive, returning a null value\n return CborNull()\n }\n val cddlObject = util.fromFormat(cddlStr)\n val cborObject = newCborItemFromJson(jsonObject[jsonObject.keys.find { it != CDDL_LITERAL && it != KEY_LITERAL }], cddlObject)\n if (key === null) {\n return cborObject\n }\n return CborMap(mutableMapOf(Pair(CborString(key), cborObject)))\n }\n // number label keys?\n return CborMap(mutableMapOf(* jsonObject.map { Pair(CborString(it.key), newCborItemFromJson(it.value)) }.toTypedArray()))\n } else if (jsonPrimitive !== null) {\n if (cddl == null) {\n return newCborItem(jsonPrimitive)\n }\n return when (cddl) {\n // Needed because we cannot have inheritance with Kotlin to JS, unfortunately. The fromJson would cause clashes if we put it in the interface\n tstr -> tstr.fromJson(jsonPrimitive)\n\n Null -> CborNull()\n\n False -> CborSimple.FALSE\n\n True -> CborSimple.TRUE\n\n bool -> bool.fromJson(jsonPrimitive)\n\n bstr -> bstr.fromJson(jsonPrimitive)\n\n bytes -> bytes.fromJson(jsonPrimitive)\n\n float -> float.fromJson(jsonPrimitive)\n\n float16 -> float16.fromJson(jsonPrimitive)\n\n float32 -> float32.fromJson(jsonPrimitive)\n\n float64 -> float64.fromJson(jsonPrimitive)\n\n full_date -> full_date.fromJson(jsonPrimitive)\n\n int -> int.fromJson(jsonPrimitive)\n\n nil -> nil.newNil()\n\n nint -> nint.fromJson(jsonPrimitive)\n\n tdate -> tdate.fromJson(jsonPrimitive)\n\n text -> text.fromJson(jsonPrimitive)\n\n time -> time.fromJson(jsonPrimitive)\n\n uint -> uint.fromJson(jsonPrimitive)\n\n undefined -> undefined.newUndefined()\n\n else -> cddl.newCborItem(jsonPrimitive)\n }\n }\n return newCborItem(element)\n }\n\n override fun newCborItem(origValue: T?): CborItem {\n // We are not using inheritance for the methods as that would impact JS export.\n // Since this is a sealed class anyway that is not too bad\n var value = origValue\n val jsonElement: JsonElement? =\n when (value) {\n is JsonPrimitive -> value\n is JsonArray -> value\n is JsonObject -> value\n is JsonNull -> value\n else -> null\n }\n if (value == null) {\n return nil.newNil()\n } else if (value == Unit) {\n return undefined.newUndefined()\n }\n return when (this) {\n tstr -> {\n if (jsonElement === null) {\n tstr.newString(value.toString())\n } else {\n tstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n False -> {\n False.newFalse()\n }\n\n Null -> {\n Null.newNull()\n }\n\n True -> {\n True.newTrue()\n }\n\n any -> {\n return when (value) {\n is JsonPrimitive -> {\n val prim = value\n when {\n prim.isString -> tstr.fromJson(prim)\n prim.content == \"true\" || prim.content == \"false\" -> bool.fromJson(prim)\n prim.content.contains('.') || prim.content.contains('e') || prim.content.contains('E') -> float64.fromJson(prim)\n else -> int.fromJson(prim) // Assume integer if not string, boolean, or float\n }\n }\n\n is cddl_tstr -> {\n if (jsonElement === null) {\n tstr.newString(value)\n } else {\n tstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_bstr -> {\n if (jsonElement === null) {\n bstr.newByteString(value)\n } else {\n bstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_tdate -> {\n if (jsonElement === null) {\n tdate.newTDate(value)\n } else {\n tdate.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_full_date -> {\n if (jsonElement === null) {\n full_date.newFullDate(value)\n } else {\n full_date.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_bool -> {\n if (jsonElement === null) {\n bool.newBool(value)\n } else {\n bool.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n // Use consolidated Number handling for JS/WasmJs compatibility\n // (on JS, all numeric `is` checks match any Number, making individual checks unreliable)\n is Number -> {\n if (jsonElement === null) {\n value.toCborItem()\n } else {\n val d = value.toDouble()\n if (d != kotlin.math.floor(d) || d.isInfinite() || d.isNaN()) {\n float64.fromJson(jsonElement.jsonPrimitive)\n } else {\n int.fromJson(jsonElement.jsonPrimitive)\n }\n }\n }\n\n is cddl_list<*> -> {\n if (jsonElement === null) {\n list.newList(\n value\n .map {\n if (it is CborItem<*>) {\n it\n } else {\n any.newCborItem(\n it,\n )\n }\n }.toMutableList(),\n )\n } else {\n list.fromJson(jsonElement.jsonArray)\n }\n }\n\n is cddl_map<*, *> -> {\n if (jsonElement === null) {\n map.newMap(\n mutableMapOf(\n * value\n .map {\n Pair(\n if (it.key is CborItem<*>) {\n it.key as CborItem<*>\n } else {\n any.newCborItem(it.key)\n },\n if (it.value is CborItem<*>) {\n it.value as CborItem<*>\n } else {\n any.newCborItem(it.value)\n },\n )\n }.toTypedArray(),\n ),\n )\n } else {\n map.fromJson(jsonElement.jsonObject)\n }\n }\n\n else -> {\n throw IllegalArgumentException(\"newCborItem for $value Not implemented yet\")\n }\n }\n }\n\n bool -> {\n if (jsonElement === null) {\n bool.newBool(value == true)\n } else {\n bool.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n bstr -> {\n if (jsonElement === null) {\n bstr.newByteString(value as ByteArray)\n } else {\n bstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n bstr_indef_length -> {\n if (jsonElement === null) {\n bstr_indef_length.newByteString(value as List)\n } else {\n TODO(\"indef cddl from json not implemented yet\")\n }\n }\n\n bytes -> {\n if (jsonElement === null) {\n bytes.newBytes(value as ByteArray)\n } else {\n bytes.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float -> {\n if (jsonElement === null) {\n float.newFloat(value as Float)\n } else {\n float.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float16 -> {\n if (jsonElement === null) {\n float16.newFloat16(value as Float)\n } else {\n float16.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float32 -> {\n if (jsonElement === null) {\n float32.newFloat32(value as Float)\n } else {\n float32.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float64 -> {\n if (jsonElement === null) {\n float64.newFloat64(value as Double)\n } else {\n float64.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n full_date -> {\n if (jsonElement === null) {\n full_date.newFullDate(value as cddl_full_date)\n } else {\n full_date.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n int -> {\n if (jsonElement === null) {\n int.newInt(value as Int)\n } else {\n int.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n list -> {\n if (jsonElement === null) {\n if (value is CborArray<*>) {\n value\n } else {\n list.newList(\n (value as List<*>)\n .map {\n if (it is CborItem<*>) {\n it\n } else {\n any.newCborItem(\n it,\n )\n }\n }.toMutableList(),\n )\n }\n } else {\n list.fromJson(jsonElement.jsonArray)\n }\n }\n\n map -> {\n if (jsonElement === null) {\n if (value is CborMap<*, *>) {\n value\n } else {\n map.newMap(\n mutableMapOf(\n * (value as Map<*, *>)\n .map {\n Pair(\n if (it.key is CborItem<*>) {\n it.key as CborItem<*>\n } else {\n any.newCborItem(it.key)\n },\n if (it.value is CborItem<*>) {\n it.value as CborItem<*>\n } else {\n any.newCborItem(it.value)\n },\n )\n }.toTypedArray(),\n ),\n ) // fixme. Needs inspection of keys and values and map type\n }\n } else {\n return map.fromJson(jsonElement.jsonObject)\n }\n }\n\n nil -> {\n nil.newNil()\n }\n\n nint -> {\n if (jsonElement === null) {\n nint.newNInt(\n if (value is Number) {\n value.toLong()\n } else {\n value as Long\n }\n )\n } else {\n nint.fromJson(\n jsonElement.jsonPrimitive,\n )\n }\n }\n\n tdate -> {\n if (jsonElement === null) {\n tdate.newTDate(value as cddl_tdate)\n } else {\n tdate.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n text -> {\n if (jsonElement === null) {\n text.newText(value as cddl_text)\n } else {\n text.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n time -> {\n if (jsonElement === null) {\n time.newTime(value as cddl_time)\n } else {\n time.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n tstr_indef_length -> {\n if (jsonElement !== null) {\n tstr_indef_length.newStringIndefLength(value as List)\n } else {\n TODO(\"tstr indef length from json to cbor not implemented\")\n }\n }\n\n uint -> {\n if (jsonElement === null) {\n uint.newUint(\n if (value is Long) {\n value\n } else if (value is Number) {\n value.toLong()\n } else {\n value as Long\n },\n )\n } else {\n uint.fromJson(\n jsonElement.jsonPrimitive,\n )\n }\n }\n\n undefined -> {\n undefined.newUndefined()\n }\n }\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTstr\")\n object tstr : CDDL(\"tstr\", MajorType.UNICODE_STRING) {\n fun newString(value: cddl_tstr) = CborString(value)\n\n fun fromJson(value: JsonPrimitive) = CborString(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlUint\")\n object uint : CDDL(\"uint\", MajorType.UNSIGNED_INTEGER) {\n fun newUint(value: cddl_uint) = CborUInt(value)\n\n fun fromJson(value: JsonPrimitive) = CborUInt(value.content.toLong())\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNint\")\n object nint : CDDL(\"nint\", MajorType.NEGATIVE_INTEGER) {\n fun newNInt(value: cddl_nint) = CborNInt(value)\n\n fun fromJson(value: JsonPrimitive) = CborNInt(value.content.toLong())\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlInt\")\n object int :\n CDDL(\"int\", null, null, aliasFor = arrayOf(uint, nint)) {\n fun newInt(value: Int) =\n if (value < 0) {\n CborNInt(value.toLong())\n } else {\n CborUInt(value.toLong())\n }\n\n fun newLong(value: Long) =\n if (value < 0) {\n CborNInt(value)\n } else {\n CborUInt(value)\n }\n\n fun fromJson(value: JsonPrimitive) =\n if (value.long < 0) {\n CborNInt(value.long)\n } else {\n CborUInt(value.long)\n }\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBstr\")\n object bstr : CDDL(\"bstr\", MajorType.BYTE_STRING) {\n fun newByteString(value: cddl_bstr) = CborByteString(value)\n\n fun fromJson(\n value: JsonPrimitive,\n encoding: Encoding = Encoding.BASE64URL,\n ) = CborByteString(value.content.decodeFrom(encoding))\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBstrIndefLength\")\n object bstr_indef_length : CDDL(\"bstr\", MajorType.BYTE_STRING) {\n fun newByteString(value: List) = CborByteStringIndefLength(value)\n\n fun fromJson(\n value: JsonArray,\n encoding: Encoding = Encoding.BASE64URL,\n ): CborByteStringIndefLength = TODO(\"indef length from json to cbor not implemented yet\")\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBytes\")\n object bytes : CDDL(\"bytes\", MajorType.BYTE_STRING, aliasFor = arrayOf(bstr)) {\n fun newBytes(value: cddl_bstr) = CborByteString(value)\n\n fun fromJson(\n value: JsonPrimitive,\n encoding: Encoding = Encoding.BASE64URL,\n ) = CborByteString(value.content.decodeFrom(encoding))\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTstrIndefLength\")\n object tstr_indef_length : CDDL(\"tstr\", MajorType.UNICODE_STRING) {\n fun newStringIndefLength(value: List) = CborStringIndefLength(value)\n\n fun fromJson(\n value: JsonArray,\n encoding: Encoding = Encoding.BASE64URL,\n ): CborStringIndefLength = TODO(\"indef length from json to cbor not implemented yet\")\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlText\")\n object text : CDDL(\"text\", MajorType.UNICODE_STRING, aliasFor = arrayOf(tstr)) {\n fun newText(value: cddl_text) = CborString(value)\n\n fun fromJson(value: JsonPrimitive) = CborString(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTdate\")\n object tdate : CDDL(\n \"tdate\",\n MajorType.TAG,\n DATE_TIME_STRING,\n ) { // RFC 7049, section 2.4.1, a tdate data item shall contain a date-time string as specified in RFC 3339\n fun newTDate(value: cddl_tdate) = CborTDate(value)\n\n fun fromJson(value: JsonPrimitive) = CborTDate(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFullDate\")\n object full_date : CDDL(\n \"full-date\",\n MajorType.TAG,\n CborTagged.FULL_DATE_STRING,\n ) { // #6.1004(tstr) In accordance with RFC 8943, a full-date data item shall contain a full-datestring as specified in RFC 3339.\n fun newFullDate(value: cddl_full_date) = CborFullDate(value)\n\n fun fromJson(value: JsonPrimitive) = CborFullDate(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTime\")\n object time : CDDL(\n \"time\",\n MajorType.TAG,\n CborTagged.DATE_TIME_NUMBER,\n ) { // RFC 7049, section 2.4.1, a tdate data item shall contain a date-time number as specified in RFC 3339\n fun newTime(value: cddl_time) = CborTime(value)\n\n fun fromJson(value: JsonPrimitive) = CborTime(value.content.toLong())\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat16\")\n object float16 : CDDL(\"float16\", MajorType.SPECIAL, 25) {\n fun newFloat16(value: cddl_float16) = CborFloat16(value)\n\n fun fromJson(value: JsonPrimitive) = CborFloat16(value.float)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat32\")\n object float32 : CDDL(\"float32\", MajorType.SPECIAL, 26) {\n fun newFloat32(value: cddl_float32) = CborFloat32(value)\n\n fun fromJson(value: JsonPrimitive) = CborFloat32(value.float)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat64\")\n object float64 : CDDL(\"float64\", MajorType.SPECIAL, 27) {\n fun newFloat64(value: cddl_float64) = CborDouble(value)\n\n fun fromJson(value: JsonPrimitive) = CborDouble(value.double)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat\")\n object float : CDDL(\"float\", MajorType.SPECIAL, aliasFor = arrayOf(float16, float32, float64)) {\n fun newFloat(value: cddl_float) = CborFloat32(value)\n\n fun fromJson(value: JsonPrimitive) = CborFloat32(value.float)\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFalse\")\n @Serializable(with = CDDLSerializer::class)\n object False : CDDL(\"false\", MajorType.SPECIAL, 20) {\n fun newFalse() = CborSimple.FALSE\n\n fun fromJson(value: JsonPrimitive) = CborSimple.FALSE\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTrue\")\n @Serializable(with = CDDLSerializer::class)\n object True : CDDL(\"true\", MajorType.SPECIAL, 21) {\n fun newTrue() = CborSimple.TRUE\n\n fun fromJson(value: JsonPrimitive) = CborSimple.TRUE\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBool\")\n object bool :\n CDDL(\"bool\", MajorType.SPECIAL, aliasFor = arrayOf(False, True)) {\n fun newBool(value: cddl_bool) =\n if (value) {\n CborSimple.TRUE\n } else {\n CborSimple.FALSE\n }\n\n fun fromJson(value: JsonPrimitive) =\n if (value.boolean) {\n CborSimple.TRUE\n } else {\n CborSimple.FALSE\n }\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNil\")\n object nil : CDDL(\"nil\", MajorType.SPECIAL, 22) {\n fun newNil() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNull\")\n @Serializable(with = CDDLSerializer::class)\n object Null : CDDL(\"null\", MajorType.SPECIAL, 22, arrayOf(nil)) {\n fun newNull() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlUndefined\")\n object undefined :\n CDDL(\"undefined\", MajorType.SPECIAL, 23) {\n fun newUndefined() = CborSimple.UNDEFINED\n\n fun fromJson(value: JsonElement) = CborSimple.UNDEFINED\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlMap\")\n object map :\n CDDL(\n \"map\",\n MajorType.MAP,\n ) {\n fun newMap(value: MutableMap, CborItem<*>>): CborItem, CborItem<*>>> = CborMap(value)\n\n /**\n * Please note that this method is not able to map onto the exact Cbor items as the json values have no type information!\n */\n fun fromJson(value: JsonObject): CborMap> =\n CborMap(\n value.entries\n .map {\n Pair(\n CborString(it.key),\n when (it.value) {\n is JsonPrimitive -> any.fromJson(it.value)\n is JsonArray -> list.fromJson(it.value as JsonArray)\n is JsonObject -> fromJson(it.value as JsonObject)\n else -> throw IllegalArgumentException(\"Unknown type encountered\")\n },\n )\n }.toMap()\n .toMutableMap(),\n )\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlList\")\n object list :\n CDDL(\n \"list\",\n MajorType.ARRAY,\n ) {\n fun > newList(value: cddl_list) = CborArray(value)\n\n /**\n * Please note that this method is not able to map onto the exact Cbor items as the json values have no type information!\n */\n fun fromJson(value: JsonArray): CborArray> =\n CborArray(\n value\n .map { elt ->\n when (elt) {\n is JsonPrimitive -> {\n any.fromJson(elt)\n }\n\n is JsonArray -> {\n fromJson(elt)\n }\n\n is JsonObject -> {\n if (CborItemJson.isCborItemValueJson(elt)) {\n newCborItemFromJson(\n elt,\n elt[CDDL_LITERAL]?.jsonPrimitive?.content?.let { CDDL.util.fromFormat(it) },\n )\n } else {\n map.fromJson(elt)\n }\n }\n\n else -> {\n throw IllegalArgumentException(\"Unknown type encountered\")\n }\n }\n }.toMutableList(),\n )\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlAny\")\n object any :\n CDDL(\n \"any\",\n ) {\n fun newAny(value: cddl_any) = CborAny(value)\n\n fun fromJson(value: JsonElement): CborItem<*> {\n return newCborItemFromJson(value)\n// TODO(\"Json any to cbor not implemeted yet\")\n }\n }\n\n override fun toTag(additionalInfo: Int?): String {\n if (aliasFor.isNotEmpty()) {\n if (additionalInfo == null) {\n return aliasFor[0].toTag(additionalInfo)\n }\n\n // fixme: this is not correct. We first need to traverse the aliases, as an alias could go without major and additional info\n return util.entries\n .first { it.majorType == majorType && it.info == additionalInfo }\n .toTag(additionalInfo)\n }\n\n var tag = \"#\"\n if (majorType != null) {\n tag += majorType\n }\n if (additionalInfo != null) {\n tag += \".$additionalInfo\"\n }\n return tag\n }\n\n override fun toString(): String = \"CDDL(format='$format', majorType=$majorType, info=$info, aliasFor=${aliasFor.contentToString()})\"\n\n override fun equals(other: Any?): Boolean {\n if (this === other) {\n return true\n }\n if (other !is CDDL) {\n return false\n }\n\n if (format != other.format) {\n return false\n }\n if (majorType != other.majorType) {\n return false\n }\n if (info != other.info) {\n return false\n }\n if (!aliasFor.contentEquals(other.aliasFor)) {\n return false\n }\n\n return true\n }\n\n override fun hashCode(): Int {\n var result = format.hashCode()\n result = 31 * result + (majorType?.hashCode() ?: 0)\n result = 31 * result + (info ?: 0)\n result = 31 * result + aliasFor.contentHashCode()\n return result\n }\n\n object util {\n // Lazy for serialization as this class is used as object in the above CDDL class\n val entries by lazy {\n arrayOf(\n any,\n uint,\n int,\n nint,\n bstr,\n bstr_indef_length,\n bytes,\n tstr,\n tstr_indef_length,\n text,\n tdate,\n full_date,\n time,\n float,\n False,\n True,\n bool,\n nil,\n Null,\n undefined,\n float16,\n float32,\n float64,\n map,\n list,\n )\n }\n\n fun fromFormat(format: String) = entries.first { it.format == format }\n\n fun fromTag(tag: String): CDDL {\n require(tag.startsWith(\"#\")) { \"Invalid tag supplied $tag\" }\n val parts = tag.split(\"#\", \".\")\n if (parts.size == 1) {\n return any\n }\n val majorVal = parts[1].toIntOrNull()\n return fromMajorType(majorVal?.let { MajorType.fromInt(it) }, parts[2].toIntOrNull())\n }\n\n fun fromBytes(input: Int): CDDL {\n val majorType = input shr 5\n\n // todo additionalInto\n return fromMajorType(MajorType.fromInt(majorType))\n }\n\n fun fromMajorType(\n majorType: MajorType? = null,\n additionalInfo: Int? = null,\n ) = entries.first {\n it.majorType == majorType && it.info == additionalInfo\n }\n }\n}\n\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"MajorType\", exact = true)\n@Serializable\n@JsExportCompat\nenum class MajorType(\n val type: Int,\n) {\n /**\n * Major type 0.\n *\n * An unsigned integer in the range 0..2^64-1 inclusive. The value of the encoded item is the\n * argument itself. For example, the integer 10 is denoted as the one byte 0b000_01010 (major\n * type 0, additional information 10). The integer 500 would be 0b000_11001 (major type 0,\n * additional information 25) followed by the two bytes 0x01f4, which is 500 in decimal.\n */\n UNSIGNED_INTEGER(0),\n\n /**\n * Major type 1.\n *\n * A negative integer in the range -2^64..-1 inclusive. The value of the item is -1 minus\n * the argument. For example, the integer -500 would be 0b001_11001 (major type 1, additional\n * information 25) followed by the two bytes 0x01f3, which is 499 in decimal.\n */\n NEGATIVE_INTEGER(1),\n\n /**\n * Major type 2.\n *\n * A byte string. The number of bytes in the string is equal to the argument. For example,\n * a byte string whose length is 5 would have an initial byte of 0b010_00101 (major type 2,\n * additional information 5 for the length), followed by 5 bytes of binary content. A byte\n * string whose length is 500 would have 3 initial bytes of 0b010_11001 (major type 2,\n * additional information 25 to indicate a two-byte length) followed by the two bytes 0x01f4\n * for a length of 500, followed by 500 bytes of binary content.\n */\n BYTE_STRING(2),\n\n /**\n * Major type 3.\n *\n * A text string (Section 2) encoded as UTF-8 [RFC3629]. The number of bytes in the string\n * is equal to the argument. A string containing an invalid UTF-8 sequence is well-formed\n * but invalid (Section 1.2). This type is provided for systems that need to interpret or\n * display human-readable text, and allows the differentiation between unstructured bytes\n * and text that has a specified repertoire (that of Unicode) and encoding (UTF-8). In\n * contrast to formats such as JSON, the Unicode characters in this type are never escaped.\n * Thus, a newline character (U+000A) is always represented in a string as the byte 0x0a,\n * and never as the bytes 0x5c6e (the characters \"\\\" and \"n\") nor as 0x5c7530303061 (the\n * characters \"\\\", \"u\", \"0\", \"0\", \"0\", and \"a\").\n */\n UNICODE_STRING(3),\n\n /**\n * Major type 4.\n * An array of data items. In other formats, arrays are also called lists, sequences, or\n * tuples (a \"CBOR sequence\" is something slightly different, though [RFC8742]). The argument\n * is the number of data items in the array. Items in an array do not need to all be of the\n * same type. For example, an array that contains 10 items of any type would have an initial\n * byte of 0b100_01010 (major type 4, additional information 10 for the length) followed by\n * the 10 remaining items.\n */\n ARRAY(4),\n\n /**\n * Major type 5.\n *\n * A map of pairs of data items. Maps are also called tables, dictionaries, hashes, or\n * objects (in JSON). A map is comprised of pairs of data items, each pair consisting of a\n * key that is immediately followed by a value. The argument is the number of pairs of data\n * items in the map. For example, a map that contains 9 pairs would have an initial byte of\n * 0b101_01001 (major type 5, additional information 9 for the number of pairs) followed by\n * the 18 remaining items. The first item is the first key, the second item is the first\n * value, the third item is the second key, and so on. Because items in a map come in pairs,\n * their total number is always even: a map that contains an odd number of items (no value\n * data present after the last key data item) is not well-formed. A map that has duplicate\n * keys may be well-formed, but it is not valid, and thus it causes indeterminate decoding;\n * see also Section 5.6.\n */\n MAP(5),\n\n /**\n * Major type 6.\n *\n * A tagged data item (\"tag\") whose tag number, an integer in the range 0..2^64-1 inclusive,\n * is the argument and whose enclosed data item (tag content) is the single encoded data item\n * that follows the head. See Section 3.4.\n */\n TAG(6),\n\n /**\n * Major type 7.\n *\n * Floating-point numbers and simple values, as well as the \"break\" stop code. See Section 3.3.\n */\n SPECIAL(7),\n ;\n\n companion object {\n /**\n * Gets a [MajorType] instance from type.\n *\n * @param value an integer between 0 and 7, both inclusive\n * @return a [MajorType] for the given value.\n */\n @JsStatic\n @JvmStatic\n fun fromInt(value: Int): MajorType =\n entries.find { it.type == value }\n ?: throw IllegalArgumentException(\"Unknown major type with value $value\")\n }\n}\n\nabstract class CborSimple(\n value: Type,\n cddl: CDDL,\n) : CborItem(value, cddl) {\n init {\n val info =\n when (cddl) {\n is CDDL.bool -> {\n when (value) {\n true -> CDDL.True.info\n else -> CDDL.False.info\n }\n }\n\n else -> {\n cddl.info\n }\n }\n require(info != null)\n require(info is Int)\n check(info < 24 || (info in 32..255))\n }\n\n override fun encode(builder: ByteStringBuilder) {\n val majorTypeShifted = (majorType!!.type shl 5).toByte()\n builder.append(majorTypeShifted.or(info!!.toByte()))\n }\n\n override fun equals(other: Any?): Boolean = other is CborSimple<*> && value == other.value\n\n override fun hashCode(): Int = value.hashCode()\n\n override fun toString() =\n when (this) {\n FALSE -> \"Simple(FALSE)\"\n TRUE -> \"Simple(TRUE)\"\n NULL -> \"Simple(NULL)\"\n UNDEFINED -> \"Simple(UNDEFINED)\"\n else -> \"Simple($value)\"\n }\n\n companion object {\n /** The [Simple] value for FALSE */\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"CBOR_FALSE\")\n @JsStatic\n @JvmStatic\n val FALSE = CborFalse()\n\n /** The [Simple] value for TRUE */\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"CBOR_TRUE\")\n @JsStatic\n @JvmStatic\n val TRUE = CborTrue()\n\n /** The [Simple] value for NULL */\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"CBOR_NULL\")\n @JsStatic\n @JvmStatic\n val NULL = CborNull()\n\n /** The [Simple] value for UNDEFINED */\n @JsStatic\n @JvmStatic\n val UNDEFINED = CborUndefined()\n }\n}" - }, - "GetDcqlQueryArgs": { - "kind": "data class", - "name": "GetDcqlQueryArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class GetDcqlQueryArgs(\n val queryId: String,\n)" - }, - "ListDcqlQueriesArgs": { - "kind": "class", - "name": "ListDcqlQueriesArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\nclass ListDcqlQueriesArgs\n\n/**\n * Arguments for updating an existing DCQL query configuration.\n *\n * A null field leaves the corresponding value unchanged. This supports both full\n * replacement (PUT, all fields supplied) and partial update (PATCH, a subset supplied).\n */\n@JsExportCompat\n@Serializable" - }, - "UpdateDcqlQueryArgs": { - "kind": "data class", - "name": "UpdateDcqlQueryArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class UpdateDcqlQueryArgs(\n val queryId: String,\n val name: String? = null,\n val description: String? = null,\n val dcqlQuery: DcqlQuery? = null,\n val enabled: Boolean? = null,\n)\n\n@Serializable\n@JsExportCompat\ndata class DcqlQuery(\n val credentials: List? = null,\n val credential_sets: List? = null,\n) {\n init {\n require(credentials != null || credential_sets != null) {\n \"At least one of 'credentials' or 'credential_sets' must be present\"\n }\n }\n}\n\n@Serializable\n@JsExportCompat\ndata class DcqlCredentialQuery(\n val id: String,\n val format: String? = null,\n val meta: JsonObject? = null,\n val claims: List? = null,\n val claim_sets: List? = null,\n val require_cryptographic_holder_binding: Boolean = true,\n val multiple: Boolean = false,\n @SerialName(\"trusted_authorities\")\n val trusted_authorities: List? = null,\n) {\n /**\n * Normalized trusted authorities with duplicate types automatically combined.\n *\n * When multiple authority entries of the same type exist in trusted_authorities,\n * they are automatically combined into a single entry with all values merged.\n * This prevents logic/validation problems by external parties.\n *\n * This property is computed in the init block and always reflects the deduplicated state.\n *\n * Example:\n * ```kotlin\n * // Input during construction/deserialization:\n * listOf(\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed1.com\")),\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed2.com\"))\n * )\n * // Automatically normalized to:\n * listOf(\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed1.com\", \"https://fed2.com\"))\n * )\n * ```\n */\n @Transient\n val normalizedTrustedAuthorities: List? = trusted_authorities?.let { normalizeTrustedAuthorities(it) }\n\n companion object {\n /**\n * Combines multiple trusted authority entries of the same type into single entries.\n *\n * @param authorities Original list that may contain duplicate types\n * @return List with duplicate types merged, maintaining order of first occurrence\n */\n private fun normalizeTrustedAuthorities(authorities: List): List {\n if (authorities.isEmpty()) {\n return authorities\n }\n\n // Group by type and combine all values\n val grouped = authorities.groupBy { it.type }\n\n // Maintain order of first occurrence for each type\n return authorities\n .distinctBy { it.type }\n .map { firstOfType ->\n val allValues = grouped[firstOfType.type]!!.flatMap { it.values }.distinct()\n DcqlTrustedAuthority(\n type = firstOfType.type,\n values = allValues,\n )\n }\n }\n }\n}\n\n@Serializable\n@JsExportCompat\ndata class DcqlCredentialSetQuery(\n val required: Boolean = false,\n val options: List,\n)" - }, - "DeleteDcqlQueryArgs": { - "kind": "data class", - "name": "DeleteDcqlQueryArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class DeleteDcqlQueryArgs(\n val queryId: String,\n)" - }, - "ListDcqlQueryVersionsArgs": { - "kind": "data class", - "name": "ListDcqlQueryVersionsArgs", - "module": "public", - "source": "@Serializable\ndata class ListDcqlQueryVersionsArgs(\n val queryId: String,\n)" - }, - "DcqlQueryVersionSummary": { - "kind": "data class", - "name": "DcqlQueryVersionSummary", - "module": "public", - "source": "@Serializable\ndata class DcqlQueryVersionSummary(\n val version: Int,\n val createdAt: Long,\n val createdBy: String? = null,\n)" - }, - "GetDcqlQueryVersionArgs": { - "kind": "data class", - "name": "GetDcqlQueryVersionArgs", - "module": "public", - "source": "@Serializable\ndata class GetDcqlQueryVersionArgs(\n val queryId: String,\n val version: Int,\n)" - }, - "DcqlQueryVersionRecord": { - "kind": "data class", - "name": "DcqlQueryVersionRecord", - "module": "public", - "source": "@Serializable\ndata class DcqlQueryVersionRecord(\n val identifier: String,\n val version: Int,\n val dcqlQuery: DcqlQuery,\n val createdAt: Long,\n val createdBy: String? = null,\n)\n\n@Serializable\n@JsExportCompat\ndata class DcqlQuery(\n val credentials: List? = null,\n val credential_sets: List? = null,\n) {\n init {\n require(credentials != null || credential_sets != null) {\n \"At least one of 'credentials' or 'credential_sets' must be present\"\n }\n }\n}\n\n@Serializable\n@JsExportCompat\ndata class DcqlCredentialQuery(\n val id: String,\n val format: String? = null,\n val meta: JsonObject? = null,\n val claims: List? = null,\n val claim_sets: List? = null,\n val require_cryptographic_holder_binding: Boolean = true,\n val multiple: Boolean = false,\n @SerialName(\"trusted_authorities\")\n val trusted_authorities: List? = null,\n) {\n /**\n * Normalized trusted authorities with duplicate types automatically combined.\n *\n * When multiple authority entries of the same type exist in trusted_authorities,\n * they are automatically combined into a single entry with all values merged.\n * This prevents logic/validation problems by external parties.\n *\n * This property is computed in the init block and always reflects the deduplicated state.\n *\n * Example:\n * ```kotlin\n * // Input during construction/deserialization:\n * listOf(\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed1.com\")),\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed2.com\"))\n * )\n * // Automatically normalized to:\n * listOf(\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed1.com\", \"https://fed2.com\"))\n * )\n * ```\n */\n @Transient\n val normalizedTrustedAuthorities: List? = trusted_authorities?.let { normalizeTrustedAuthorities(it) }\n\n companion object {\n /**\n * Combines multiple trusted authority entries of the same type into single entries.\n *\n * @param authorities Original list that may contain duplicate types\n * @return List with duplicate types merged, maintaining order of first occurrence\n */\n private fun normalizeTrustedAuthorities(authorities: List): List {\n if (authorities.isEmpty()) {\n return authorities\n }\n\n // Group by type and combine all values\n val grouped = authorities.groupBy { it.type }\n\n // Maintain order of first occurrence for each type\n return authorities\n .distinctBy { it.type }\n .map { firstOfType ->\n val allValues = grouped[firstOfType.type]!!.flatMap { it.values }.distinct()\n DcqlTrustedAuthority(\n type = firstOfType.type,\n values = allValues,\n )\n }\n }\n }\n}\n\n@Serializable\n@JsExportCompat\ndata class DcqlCredentialSetQuery(\n val required: Boolean = false,\n val options: List,\n)" - }, - "RestoreDcqlQueryVersionArgs": { - "kind": "data class", - "name": "RestoreDcqlQueryVersionArgs", - "module": "public", - "source": "@Serializable\ndata class RestoreDcqlQueryVersionArgs(\n val queryId: String,\n val version: Int,\n val note: String? = null,\n)" - }, - "BindVerifierDcqlArgs": { - "kind": "data class", - "name": "BindVerifierDcqlArgs", - "module": "public", - "source": "@Serializable\ndata class BindVerifierDcqlArgs(\n val verifierId: String,\n val queryId: String,\n /** Version to pin. Defaults to the DCQL query's current version when null. */\n val version: Int? = null,\n)\n\n object Defaults {\n /** Default slot interval in minutes for availability calculations */\n const val SLOT_INTERVAL_MINUTES = 30\n\n /** Default concurrency limit (how many concurrent bookings allowed) */\n const val CONCURRENCY_LIMIT = 1\n\n /** Default minimum booking duration in minutes */\n const val MIN_BOOKING_DURATION_MINUTES = 30\n\n /** Default buffer time after each booking in minutes */\n const val BUFFER_AFTER_MINUTES = 0\n\n /** Default for allowing same-day bookings */\n const val ALLOW_SAME_DAY_BOOKING = true\n }" - }, - "VerifierDcqlBinding": { - "kind": "data class", - "name": "VerifierDcqlBinding", - "module": "public", - "source": "@Serializable\ndata class VerifierDcqlBinding(\n val id: String,\n val tenantId: String,\n val verifierId: String,\n val queryId: String,\n val pinnedVersion: Int,\n val enabled: Boolean = true,\n val alias: String? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n)" - }, - "ListVerifierDcqlBindingsArgs": { - "kind": "data class", - "name": "ListVerifierDcqlBindingsArgs", - "module": "public", - "source": "@Serializable\ndata class ListVerifierDcqlBindingsArgs(\n val verifierId: String,\n)" - }, - "VerifierDcqlBindingKey": { - "kind": "data class", - "name": "VerifierDcqlBindingKey", - "module": "public", - "source": "@Serializable\ndata class VerifierDcqlBindingKey(\n val verifierId: String,\n val queryId: String,\n)" - }, - "UpdateVerifierDcqlBindingArgs": { - "kind": "data class", - "name": "UpdateVerifierDcqlBindingArgs", - "module": "public", - "source": "@Serializable\ndata class UpdateVerifierDcqlBindingArgs(\n val verifierId: String,\n val queryId: String,\n /** New pinned version. Null leaves the pinned version unchanged. */\n val pinnedVersion: Int? = null,\n /** Null leaves `enabled` unchanged. */\n val enabled: Boolean? = null,\n /** Null leaves `alias` unchanged. */\n val alias: String? = null,\n)\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNull\")\n @Serializable(with = CDDLSerializer::class)\n object Null : CDDL(\"null\", MajorType.SPECIAL, 22, arrayOf(nil)) {\n fun newNull() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\ninternal object CDDLSerializer : KSerializer {\n override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(\"CDDL\", PrimitiveKind.STRING)\n\n override fun serialize(\n encoder: Encoder,\n value: CDDL,\n ) {\n encoder.encodeString(value.format)\n }\n\n override fun deserialize(decoder: Decoder): CDDL = CDDL.util.fromFormat(decoder.decodeString())\n}\n\n@Suppress(\"UNCHECKED_CAST\")\n@JsExportCompat\n@Serializable(with = CDDLSerializer::class)\nsealed class CDDL(\n override val format: String,\n override val majorType: MajorType? = null,\n override val info: Int? = null,\n override val aliasFor: Array = arrayOf(),\n) : CDDLType {\n override fun newCborItemFromJson(\n element: JsonElement?,\n cddl: CDDLType?,\n ): CborItem {\n val jsonPrimitive: JsonPrimitive? = (element as? JsonPrimitive)?.jsonPrimitive\n val jsonArray: JsonArray? = (element as? JsonArray)?.jsonArray\n val jsonObject: JsonObject? = (element as? JsonObject)?.jsonObject\n val isNull: Boolean = element == JsonNull || element === null\n val isString: Boolean = jsonPrimitive?.isString == true\n\n if (isNull) {\n return CborNull()\n } else if (isString && jsonPrimitive !== null) {\n return CborString(jsonPrimitive.content)\n } else if (jsonArray !== null) {\n return list.fromJson(jsonArray)\n } else if (jsonObject !== null) {\n if (CborItemJson.isCborItemValueJson(jsonObject)) {\n val key =\n if (CborItemJson.isCborItemJson(jsonObject)) {\n (jsonObject[\"key\"] as? JsonPrimitive)?.content\n } else {\n null\n }\n val cddlStr = (jsonObject[\"cddl\"] as? JsonPrimitive)?.content\n\n if (cddlStr === null) {\n // cddl key found, but wasn't a primitive, returning a null value\n return CborNull()\n }\n val cddlObject = util.fromFormat(cddlStr)\n val cborObject = newCborItemFromJson(jsonObject[jsonObject.keys.find { it != CDDL_LITERAL && it != KEY_LITERAL }], cddlObject)\n if (key === null) {\n return cborObject\n }\n return CborMap(mutableMapOf(Pair(CborString(key), cborObject)))\n }\n // number label keys?\n return CborMap(mutableMapOf(* jsonObject.map { Pair(CborString(it.key), newCborItemFromJson(it.value)) }.toTypedArray()))\n } else if (jsonPrimitive !== null) {\n if (cddl == null) {\n return newCborItem(jsonPrimitive)\n }\n return when (cddl) {\n // Needed because we cannot have inheritance with Kotlin to JS, unfortunately. The fromJson would cause clashes if we put it in the interface\n tstr -> tstr.fromJson(jsonPrimitive)\n\n Null -> CborNull()\n\n False -> CborSimple.FALSE\n\n True -> CborSimple.TRUE\n\n bool -> bool.fromJson(jsonPrimitive)\n\n bstr -> bstr.fromJson(jsonPrimitive)\n\n bytes -> bytes.fromJson(jsonPrimitive)\n\n float -> float.fromJson(jsonPrimitive)\n\n float16 -> float16.fromJson(jsonPrimitive)\n\n float32 -> float32.fromJson(jsonPrimitive)\n\n float64 -> float64.fromJson(jsonPrimitive)\n\n full_date -> full_date.fromJson(jsonPrimitive)\n\n int -> int.fromJson(jsonPrimitive)\n\n nil -> nil.newNil()\n\n nint -> nint.fromJson(jsonPrimitive)\n\n tdate -> tdate.fromJson(jsonPrimitive)\n\n text -> text.fromJson(jsonPrimitive)\n\n time -> time.fromJson(jsonPrimitive)\n\n uint -> uint.fromJson(jsonPrimitive)\n\n undefined -> undefined.newUndefined()\n\n else -> cddl.newCborItem(jsonPrimitive)\n }\n }\n return newCborItem(element)\n }\n\n override fun newCborItem(origValue: T?): CborItem {\n // We are not using inheritance for the methods as that would impact JS export.\n // Since this is a sealed class anyway that is not too bad\n var value = origValue\n val jsonElement: JsonElement? =\n when (value) {\n is JsonPrimitive -> value\n is JsonArray -> value\n is JsonObject -> value\n is JsonNull -> value\n else -> null\n }\n if (value == null) {\n return nil.newNil()\n } else if (value == Unit) {\n return undefined.newUndefined()\n }\n return when (this) {\n tstr -> {\n if (jsonElement === null) {\n tstr.newString(value.toString())\n } else {\n tstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n False -> {\n False.newFalse()\n }\n\n Null -> {\n Null.newNull()\n }\n\n True -> {\n True.newTrue()\n }\n\n any -> {\n return when (value) {\n is JsonPrimitive -> {\n val prim = value\n when {\n prim.isString -> tstr.fromJson(prim)\n prim.content == \"true\" || prim.content == \"false\" -> bool.fromJson(prim)\n prim.content.contains('.') || prim.content.contains('e') || prim.content.contains('E') -> float64.fromJson(prim)\n else -> int.fromJson(prim) // Assume integer if not string, boolean, or float\n }\n }\n\n is cddl_tstr -> {\n if (jsonElement === null) {\n tstr.newString(value)\n } else {\n tstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_bstr -> {\n if (jsonElement === null) {\n bstr.newByteString(value)\n } else {\n bstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_tdate -> {\n if (jsonElement === null) {\n tdate.newTDate(value)\n } else {\n tdate.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_full_date -> {\n if (jsonElement === null) {\n full_date.newFullDate(value)\n } else {\n full_date.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_bool -> {\n if (jsonElement === null) {\n bool.newBool(value)\n } else {\n bool.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n // Use consolidated Number handling for JS/WasmJs compatibility\n // (on JS, all numeric `is` checks match any Number, making individual checks unreliable)\n is Number -> {\n if (jsonElement === null) {\n value.toCborItem()\n } else {\n val d = value.toDouble()\n if (d != kotlin.math.floor(d) || d.isInfinite() || d.isNaN()) {\n float64.fromJson(jsonElement.jsonPrimitive)\n } else {\n int.fromJson(jsonElement.jsonPrimitive)\n }\n }\n }\n\n is cddl_list<*> -> {\n if (jsonElement === null) {\n list.newList(\n value\n .map {\n if (it is CborItem<*>) {\n it\n } else {\n any.newCborItem(\n it,\n )\n }\n }.toMutableList(),\n )\n } else {\n list.fromJson(jsonElement.jsonArray)\n }\n }\n\n is cddl_map<*, *> -> {\n if (jsonElement === null) {\n map.newMap(\n mutableMapOf(\n * value\n .map {\n Pair(\n if (it.key is CborItem<*>) {\n it.key as CborItem<*>\n } else {\n any.newCborItem(it.key)\n },\n if (it.value is CborItem<*>) {\n it.value as CborItem<*>\n } else {\n any.newCborItem(it.value)\n },\n )\n }.toTypedArray(),\n ),\n )\n } else {\n map.fromJson(jsonElement.jsonObject)\n }\n }\n\n else -> {\n throw IllegalArgumentException(\"newCborItem for $value Not implemented yet\")\n }\n }\n }\n\n bool -> {\n if (jsonElement === null) {\n bool.newBool(value == true)\n } else {\n bool.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n bstr -> {\n if (jsonElement === null) {\n bstr.newByteString(value as ByteArray)\n } else {\n bstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n bstr_indef_length -> {\n if (jsonElement === null) {\n bstr_indef_length.newByteString(value as List)\n } else {\n TODO(\"indef cddl from json not implemented yet\")\n }\n }\n\n bytes -> {\n if (jsonElement === null) {\n bytes.newBytes(value as ByteArray)\n } else {\n bytes.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float -> {\n if (jsonElement === null) {\n float.newFloat(value as Float)\n } else {\n float.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float16 -> {\n if (jsonElement === null) {\n float16.newFloat16(value as Float)\n } else {\n float16.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float32 -> {\n if (jsonElement === null) {\n float32.newFloat32(value as Float)\n } else {\n float32.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float64 -> {\n if (jsonElement === null) {\n float64.newFloat64(value as Double)\n } else {\n float64.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n full_date -> {\n if (jsonElement === null) {\n full_date.newFullDate(value as cddl_full_date)\n } else {\n full_date.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n int -> {\n if (jsonElement === null) {\n int.newInt(value as Int)\n } else {\n int.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n list -> {\n if (jsonElement === null) {\n if (value is CborArray<*>) {\n value\n } else {\n list.newList(\n (value as List<*>)\n .map {\n if (it is CborItem<*>) {\n it\n } else {\n any.newCborItem(\n it,\n )\n }\n }.toMutableList(),\n )\n }\n } else {\n list.fromJson(jsonElement.jsonArray)\n }\n }\n\n map -> {\n if (jsonElement === null) {\n if (value is CborMap<*, *>) {\n value\n } else {\n map.newMap(\n mutableMapOf(\n * (value as Map<*, *>)\n .map {\n Pair(\n if (it.key is CborItem<*>) {\n it.key as CborItem<*>\n } else {\n any.newCborItem(it.key)\n },\n if (it.value is CborItem<*>) {\n it.value as CborItem<*>\n } else {\n any.newCborItem(it.value)\n },\n )\n }.toTypedArray(),\n ),\n ) // fixme. Needs inspection of keys and values and map type\n }\n } else {\n return map.fromJson(jsonElement.jsonObject)\n }\n }\n\n nil -> {\n nil.newNil()\n }\n\n nint -> {\n if (jsonElement === null) {\n nint.newNInt(\n if (value is Number) {\n value.toLong()\n } else {\n value as Long\n }\n )\n } else {\n nint.fromJson(\n jsonElement.jsonPrimitive,\n )\n }\n }\n\n tdate -> {\n if (jsonElement === null) {\n tdate.newTDate(value as cddl_tdate)\n } else {\n tdate.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n text -> {\n if (jsonElement === null) {\n text.newText(value as cddl_text)\n } else {\n text.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n time -> {\n if (jsonElement === null) {\n time.newTime(value as cddl_time)\n } else {\n time.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n tstr_indef_length -> {\n if (jsonElement !== null) {\n tstr_indef_length.newStringIndefLength(value as List)\n } else {\n TODO(\"tstr indef length from json to cbor not implemented\")\n }\n }\n\n uint -> {\n if (jsonElement === null) {\n uint.newUint(\n if (value is Long) {\n value\n } else if (value is Number) {\n value.toLong()\n } else {\n value as Long\n },\n )\n } else {\n uint.fromJson(\n jsonElement.jsonPrimitive,\n )\n }\n }\n\n undefined -> {\n undefined.newUndefined()\n }\n }\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTstr\")\n object tstr : CDDL(\"tstr\", MajorType.UNICODE_STRING) {\n fun newString(value: cddl_tstr) = CborString(value)\n\n fun fromJson(value: JsonPrimitive) = CborString(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlUint\")\n object uint : CDDL(\"uint\", MajorType.UNSIGNED_INTEGER) {\n fun newUint(value: cddl_uint) = CborUInt(value)\n\n fun fromJson(value: JsonPrimitive) = CborUInt(value.content.toLong())\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNint\")\n object nint : CDDL(\"nint\", MajorType.NEGATIVE_INTEGER) {\n fun newNInt(value: cddl_nint) = CborNInt(value)\n\n fun fromJson(value: JsonPrimitive) = CborNInt(value.content.toLong())\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlInt\")\n object int :\n CDDL(\"int\", null, null, aliasFor = arrayOf(uint, nint)) {\n fun newInt(value: Int) =\n if (value < 0) {\n CborNInt(value.toLong())\n } else {\n CborUInt(value.toLong())\n }\n\n fun newLong(value: Long) =\n if (value < 0) {\n CborNInt(value)\n } else {\n CborUInt(value)\n }\n\n fun fromJson(value: JsonPrimitive) =\n if (value.long < 0) {\n CborNInt(value.long)\n } else {\n CborUInt(value.long)\n }\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBstr\")\n object bstr : CDDL(\"bstr\", MajorType.BYTE_STRING) {\n fun newByteString(value: cddl_bstr) = CborByteString(value)\n\n fun fromJson(\n value: JsonPrimitive,\n encoding: Encoding = Encoding.BASE64URL,\n ) = CborByteString(value.content.decodeFrom(encoding))\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBstrIndefLength\")\n object bstr_indef_length : CDDL(\"bstr\", MajorType.BYTE_STRING) {\n fun newByteString(value: List) = CborByteStringIndefLength(value)\n\n fun fromJson(\n value: JsonArray,\n encoding: Encoding = Encoding.BASE64URL,\n ): CborByteStringIndefLength = TODO(\"indef length from json to cbor not implemented yet\")\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBytes\")\n object bytes : CDDL(\"bytes\", MajorType.BYTE_STRING, aliasFor = arrayOf(bstr)) {\n fun newBytes(value: cddl_bstr) = CborByteString(value)\n\n fun fromJson(\n value: JsonPrimitive,\n encoding: Encoding = Encoding.BASE64URL,\n ) = CborByteString(value.content.decodeFrom(encoding))\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTstrIndefLength\")\n object tstr_indef_length : CDDL(\"tstr\", MajorType.UNICODE_STRING) {\n fun newStringIndefLength(value: List) = CborStringIndefLength(value)\n\n fun fromJson(\n value: JsonArray,\n encoding: Encoding = Encoding.BASE64URL,\n ): CborStringIndefLength = TODO(\"indef length from json to cbor not implemented yet\")\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlText\")\n object text : CDDL(\"text\", MajorType.UNICODE_STRING, aliasFor = arrayOf(tstr)) {\n fun newText(value: cddl_text) = CborString(value)\n\n fun fromJson(value: JsonPrimitive) = CborString(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTdate\")\n object tdate : CDDL(\n \"tdate\",\n MajorType.TAG,\n DATE_TIME_STRING,\n ) { // RFC 7049, section 2.4.1, a tdate data item shall contain a date-time string as specified in RFC 3339\n fun newTDate(value: cddl_tdate) = CborTDate(value)\n\n fun fromJson(value: JsonPrimitive) = CborTDate(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFullDate\")\n object full_date : CDDL(\n \"full-date\",\n MajorType.TAG,\n CborTagged.FULL_DATE_STRING,\n ) { // #6.1004(tstr) In accordance with RFC 8943, a full-date data item shall contain a full-datestring as specified in RFC 3339.\n fun newFullDate(value: cddl_full_date) = CborFullDate(value)\n\n fun fromJson(value: JsonPrimitive) = CborFullDate(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTime\")\n object time : CDDL(\n \"time\",\n MajorType.TAG,\n CborTagged.DATE_TIME_NUMBER,\n ) { // RFC 7049, section 2.4.1, a tdate data item shall contain a date-time number as specified in RFC 3339\n fun newTime(value: cddl_time) = CborTime(value)\n\n fun fromJson(value: JsonPrimitive) = CborTime(value.content.toLong())\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat16\")\n object float16 : CDDL(\"float16\", MajorType.SPECIAL, 25) {\n fun newFloat16(value: cddl_float16) = CborFloat16(value)\n\n fun fromJson(value: JsonPrimitive) = CborFloat16(value.float)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat32\")\n object float32 : CDDL(\"float32\", MajorType.SPECIAL, 26) {\n fun newFloat32(value: cddl_float32) = CborFloat32(value)\n\n fun fromJson(value: JsonPrimitive) = CborFloat32(value.float)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat64\")\n object float64 : CDDL(\"float64\", MajorType.SPECIAL, 27) {\n fun newFloat64(value: cddl_float64) = CborDouble(value)\n\n fun fromJson(value: JsonPrimitive) = CborDouble(value.double)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat\")\n object float : CDDL(\"float\", MajorType.SPECIAL, aliasFor = arrayOf(float16, float32, float64)) {\n fun newFloat(value: cddl_float) = CborFloat32(value)\n\n fun fromJson(value: JsonPrimitive) = CborFloat32(value.float)\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFalse\")\n @Serializable(with = CDDLSerializer::class)\n object False : CDDL(\"false\", MajorType.SPECIAL, 20) {\n fun newFalse() = CborSimple.FALSE\n\n fun fromJson(value: JsonPrimitive) = CborSimple.FALSE\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTrue\")\n @Serializable(with = CDDLSerializer::class)\n object True : CDDL(\"true\", MajorType.SPECIAL, 21) {\n fun newTrue() = CborSimple.TRUE\n\n fun fromJson(value: JsonPrimitive) = CborSimple.TRUE\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBool\")\n object bool :\n CDDL(\"bool\", MajorType.SPECIAL, aliasFor = arrayOf(False, True)) {\n fun newBool(value: cddl_bool) =\n if (value) {\n CborSimple.TRUE\n } else {\n CborSimple.FALSE\n }\n\n fun fromJson(value: JsonPrimitive) =\n if (value.boolean) {\n CborSimple.TRUE\n } else {\n CborSimple.FALSE\n }\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNil\")\n object nil : CDDL(\"nil\", MajorType.SPECIAL, 22) {\n fun newNil() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNull\")\n @Serializable(with = CDDLSerializer::class)\n object Null : CDDL(\"null\", MajorType.SPECIAL, 22, arrayOf(nil)) {\n fun newNull() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlUndefined\")\n object undefined :\n CDDL(\"undefined\", MajorType.SPECIAL, 23) {\n fun newUndefined() = CborSimple.UNDEFINED\n\n fun fromJson(value: JsonElement) = CborSimple.UNDEFINED\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlMap\")\n object map :\n CDDL(\n \"map\",\n MajorType.MAP,\n ) {\n fun newMap(value: MutableMap, CborItem<*>>): CborItem, CborItem<*>>> = CborMap(value)\n\n /**\n * Please note that this method is not able to map onto the exact Cbor items as the json values have no type information!\n */\n fun fromJson(value: JsonObject): CborMap> =\n CborMap(\n value.entries\n .map {\n Pair(\n CborString(it.key),\n when (it.value) {\n is JsonPrimitive -> any.fromJson(it.value)\n is JsonArray -> list.fromJson(it.value as JsonArray)\n is JsonObject -> fromJson(it.value as JsonObject)\n else -> throw IllegalArgumentException(\"Unknown type encountered\")\n },\n )\n }.toMap()\n .toMutableMap(),\n )\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlList\")\n object list :\n CDDL(\n \"list\",\n MajorType.ARRAY,\n ) {\n fun > newList(value: cddl_list) = CborArray(value)\n\n /**\n * Please note that this method is not able to map onto the exact Cbor items as the json values have no type information!\n */\n fun fromJson(value: JsonArray): CborArray> =\n CborArray(\n value\n .map { elt ->\n when (elt) {\n is JsonPrimitive -> {\n any.fromJson(elt)\n }\n\n is JsonArray -> {\n fromJson(elt)\n }\n\n is JsonObject -> {\n if (CborItemJson.isCborItemValueJson(elt)) {\n newCborItemFromJson(\n elt,\n elt[CDDL_LITERAL]?.jsonPrimitive?.content?.let { CDDL.util.fromFormat(it) },\n )\n } else {\n map.fromJson(elt)\n }\n }\n\n else -> {\n throw IllegalArgumentException(\"Unknown type encountered\")\n }\n }\n }.toMutableList(),\n )\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlAny\")\n object any :\n CDDL(\n \"any\",\n ) {\n fun newAny(value: cddl_any) = CborAny(value)\n\n fun fromJson(value: JsonElement): CborItem<*> {\n return newCborItemFromJson(value)\n// TODO(\"Json any to cbor not implemeted yet\")\n }\n }\n\n override fun toTag(additionalInfo: Int?): String {\n if (aliasFor.isNotEmpty()) {\n if (additionalInfo == null) {\n return aliasFor[0].toTag(additionalInfo)\n }\n\n // fixme: this is not correct. We first need to traverse the aliases, as an alias could go without major and additional info\n return util.entries\n .first { it.majorType == majorType && it.info == additionalInfo }\n .toTag(additionalInfo)\n }\n\n var tag = \"#\"\n if (majorType != null) {\n tag += majorType\n }\n if (additionalInfo != null) {\n tag += \".$additionalInfo\"\n }\n return tag\n }\n\n override fun toString(): String = \"CDDL(format='$format', majorType=$majorType, info=$info, aliasFor=${aliasFor.contentToString()})\"\n\n override fun equals(other: Any?): Boolean {\n if (this === other) {\n return true\n }\n if (other !is CDDL) {\n return false\n }\n\n if (format != other.format) {\n return false\n }\n if (majorType != other.majorType) {\n return false\n }\n if (info != other.info) {\n return false\n }\n if (!aliasFor.contentEquals(other.aliasFor)) {\n return false\n }\n\n return true\n }\n\n override fun hashCode(): Int {\n var result = format.hashCode()\n result = 31 * result + (majorType?.hashCode() ?: 0)\n result = 31 * result + (info ?: 0)\n result = 31 * result + aliasFor.contentHashCode()\n return result\n }\n\n object util {\n // Lazy for serialization as this class is used as object in the above CDDL class\n val entries by lazy {\n arrayOf(\n any,\n uint,\n int,\n nint,\n bstr,\n bstr_indef_length,\n bytes,\n tstr,\n tstr_indef_length,\n text,\n tdate,\n full_date,\n time,\n float,\n False,\n True,\n bool,\n nil,\n Null,\n undefined,\n float16,\n float32,\n float64,\n map,\n list,\n )\n }\n\n fun fromFormat(format: String) = entries.first { it.format == format }\n\n fun fromTag(tag: String): CDDL {\n require(tag.startsWith(\"#\")) { \"Invalid tag supplied $tag\" }\n val parts = tag.split(\"#\", \".\")\n if (parts.size == 1) {\n return any\n }\n val majorVal = parts[1].toIntOrNull()\n return fromMajorType(majorVal?.let { MajorType.fromInt(it) }, parts[2].toIntOrNull())\n }\n\n fun fromBytes(input: Int): CDDL {\n val majorType = input shr 5\n\n // todo additionalInto\n return fromMajorType(MajorType.fromInt(majorType))\n }\n\n fun fromMajorType(\n majorType: MajorType? = null,\n additionalInfo: Int? = null,\n ) = entries.first {\n it.majorType == majorType && it.info == additionalInfo\n }\n }\n}\n\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"MajorType\", exact = true)\n@Serializable\n@JsExportCompat\nenum class MajorType(\n val type: Int,\n) {\n /**\n * Major type 0.\n *\n * An unsigned integer in the range 0..2^64-1 inclusive. The value of the encoded item is the\n * argument itself. For example, the integer 10 is denoted as the one byte 0b000_01010 (major\n * type 0, additional information 10). The integer 500 would be 0b000_11001 (major type 0,\n * additional information 25) followed by the two bytes 0x01f4, which is 500 in decimal.\n */\n UNSIGNED_INTEGER(0),\n\n /**\n * Major type 1.\n *\n * A negative integer in the range -2^64..-1 inclusive. The value of the item is -1 minus\n * the argument. For example, the integer -500 would be 0b001_11001 (major type 1, additional\n * information 25) followed by the two bytes 0x01f3, which is 499 in decimal.\n */\n NEGATIVE_INTEGER(1),\n\n /**\n * Major type 2.\n *\n * A byte string. The number of bytes in the string is equal to the argument. For example,\n * a byte string whose length is 5 would have an initial byte of 0b010_00101 (major type 2,\n * additional information 5 for the length), followed by 5 bytes of binary content. A byte\n * string whose length is 500 would have 3 initial bytes of 0b010_11001 (major type 2,\n * additional information 25 to indicate a two-byte length) followed by the two bytes 0x01f4\n * for a length of 500, followed by 500 bytes of binary content.\n */\n BYTE_STRING(2),\n\n /**\n * Major type 3.\n *\n * A text string (Section 2) encoded as UTF-8 [RFC3629]. The number of bytes in the string\n * is equal to the argument. A string containing an invalid UTF-8 sequence is well-formed\n * but invalid (Section 1.2). This type is provided for systems that need to interpret or\n * display human-readable text, and allows the differentiation between unstructured bytes\n * and text that has a specified repertoire (that of Unicode) and encoding (UTF-8). In\n * contrast to formats such as JSON, the Unicode characters in this type are never escaped.\n * Thus, a newline character (U+000A) is always represented in a string as the byte 0x0a,\n * and never as the bytes 0x5c6e (the characters \"\\\" and \"n\") nor as 0x5c7530303061 (the\n * characters \"\\\", \"u\", \"0\", \"0\", \"0\", and \"a\").\n */\n UNICODE_STRING(3),\n\n /**\n * Major type 4.\n * An array of data items. In other formats, arrays are also called lists, sequences, or\n * tuples (a \"CBOR sequence\" is something slightly different, though [RFC8742]). The argument\n * is the number of data items in the array. Items in an array do not need to all be of the\n * same type. For example, an array that contains 10 items of any type would have an initial\n * byte of 0b100_01010 (major type 4, additional information 10 for the length) followed by\n * the 10 remaining items.\n */\n ARRAY(4),\n\n /**\n * Major type 5.\n *\n * A map of pairs of data items. Maps are also called tables, dictionaries, hashes, or\n * objects (in JSON). A map is comprised of pairs of data items, each pair consisting of a\n * key that is immediately followed by a value. The argument is the number of pairs of data\n * items in the map. For example, a map that contains 9 pairs would have an initial byte of\n * 0b101_01001 (major type 5, additional information 9 for the number of pairs) followed by\n * the 18 remaining items. The first item is the first key, the second item is the first\n * value, the third item is the second key, and so on. Because items in a map come in pairs,\n * their total number is always even: a map that contains an odd number of items (no value\n * data present after the last key data item) is not well-formed. A map that has duplicate\n * keys may be well-formed, but it is not valid, and thus it causes indeterminate decoding;\n * see also Section 5.6.\n */\n MAP(5),\n\n /**\n * Major type 6.\n *\n * A tagged data item (\"tag\") whose tag number, an integer in the range 0..2^64-1 inclusive,\n * is the argument and whose enclosed data item (tag content) is the single encoded data item\n * that follows the head. See Section 3.4.\n */\n TAG(6),\n\n /**\n * Major type 7.\n *\n * Floating-point numbers and simple values, as well as the \"break\" stop code. See Section 3.3.\n */\n SPECIAL(7),\n ;\n\n companion object {\n /**\n * Gets a [MajorType] instance from type.\n *\n * @param value an integer between 0 and 7, both inclusive\n * @return a [MajorType] for the given value.\n */\n @JsStatic\n @JvmStatic\n fun fromInt(value: Int): MajorType =\n entries.find { it.type == value }\n ?: throw IllegalArgumentException(\"Unknown major type with value $value\")\n }\n}\n\nabstract class CborSimple(\n value: Type,\n cddl: CDDL,\n) : CborItem(value, cddl) {\n init {\n val info =\n when (cddl) {\n is CDDL.bool -> {\n when (value) {\n true -> CDDL.True.info\n else -> CDDL.False.info\n }\n }\n\n else -> {\n cddl.info\n }\n }\n require(info != null)\n require(info is Int)\n check(info < 24 || (info in 32..255))\n }\n\n override fun encode(builder: ByteStringBuilder) {\n val majorTypeShifted = (majorType!!.type shl 5).toByte()\n builder.append(majorTypeShifted.or(info!!.toByte()))\n }\n\n override fun equals(other: Any?): Boolean = other is CborSimple<*> && value == other.value\n\n override fun hashCode(): Int = value.hashCode()\n\n override fun toString() =\n when (this) {\n FALSE -> \"Simple(FALSE)\"\n TRUE -> \"Simple(TRUE)\"\n NULL -> \"Simple(NULL)\"\n UNDEFINED -> \"Simple(UNDEFINED)\"\n else -> \"Simple($value)\"\n }\n\n companion object {\n /** The [Simple] value for FALSE */\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"CBOR_FALSE\")\n @JsStatic\n @JvmStatic\n val FALSE = CborFalse()\n\n /** The [Simple] value for TRUE */\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"CBOR_TRUE\")\n @JsStatic\n @JvmStatic\n val TRUE = CborTrue()\n\n /** The [Simple] value for NULL */\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"CBOR_NULL\")\n @JsStatic\n @JvmStatic\n val NULL = CborNull()\n\n /** The [Simple] value for UNDEFINED */\n @JsStatic\n @JvmStatic\n val UNDEFINED = CborUndefined()\n }\n}" - }, - "ScheduleVerifierDcqlActivationArgs": { - "kind": "data class", - "name": "ScheduleVerifierDcqlActivationArgs", - "module": "public", - "source": "@Serializable\ndata class ScheduleVerifierDcqlActivationArgs(\n val verifierId: String,\n val queryId: String,\n /** Version to pin at activation time. Defaults to the DCQL query's current version when null. */\n val pinnedVersion: Int? = null,\n val effectiveAt: Instant,\n)\n\n object Defaults {\n /** Default slot interval in minutes for availability calculations */\n const val SLOT_INTERVAL_MINUTES = 30\n\n /** Default concurrency limit (how many concurrent bookings allowed) */\n const val CONCURRENCY_LIMIT = 1\n\n /** Default minimum booking duration in minutes */\n const val MIN_BOOKING_DURATION_MINUTES = 30\n\n /** Default buffer time after each booking in minutes */\n const val BUFFER_AFTER_MINUTES = 0\n\n /** Default for allowing same-day bookings */\n const val ALLOW_SAME_DAY_BOOKING = true\n }" - }, - "VerifierDcqlScheduledActivation": { - "kind": "data class", - "name": "VerifierDcqlScheduledActivation", - "module": "public", - "source": "@Serializable\ndata class VerifierDcqlScheduledActivation(\n val activationId: String,\n val verifierId: String,\n val queryId: String,\n /** The resolved concrete version pinned by this activation. */\n val pinnedVersion: Int,\n val effectiveAt: Instant,\n val status: ScheduledActivationStatus,\n)\n\n@Serializable\nenum class ScheduledActivationStatus {\n PENDING,\n APPLIED,\n CANCELLED,\n FAILED,\n}" - }, - "CancelVerifierDcqlActivationArgs": { - "kind": "data class", - "name": "CancelVerifierDcqlActivationArgs", - "module": "public", - "source": "@Serializable\ndata class CancelVerifierDcqlActivationArgs(\n val verifierId: String,\n val queryId: String,\n val activationId: String,\n)" - }, - "ListVerifiersForDcqlArgs": { - "kind": "data class", - "name": "ListVerifiersForDcqlArgs", - "module": "public", - "source": "@Serializable\ndata class ListVerifiersForDcqlArgs(\n val queryId: String,\n)" - }, - "CreatePersonArgs": { - "kind": "data class", - "name": "CreatePersonArgs", - "module": "service-api", - "source": "@Serializable\ndata class CreatePersonArgs(\n val displayName: String,\n val firstName: String? = null,\n val middleName: String? = null,\n val lastName: String? = null,\n val birthDate: LocalDate? = null,\n val origin: PartyOrigin = PartyOrigin.MANAGED,\n val uri: String? = null,\n val jurisdiction: String? = null,\n val ownerId: Uuid? = null,\n val organizationUnitId: Uuid? = null,\n)\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }" - }, - "Person": { - "kind": "data class", - "name": "Person", - "module": "public", - "source": " * data class Person(val name: String, val age: Int)" - }, - "GetPersonArgs": { - "kind": "data class", - "name": "GetPersonArgs", - "module": "service-api", - "source": "@Serializable\ndata class GetPersonArgs(val id: Uuid, val include: Set = emptySet())" - }, - "ListPersonsArgs": { - "kind": "data class", - "name": "ListPersonsArgs", - "module": "service-api", - "source": "@Serializable\ndata class ListPersonsArgs(\n val firstName: String? = null,\n val lastName: String? = null,\n val displayName: String? = null,\n val page: PageRequest = PageRequest.DEFAULT,\n val include: Set = emptySet(),\n)\n\n@Serializable\n@JsExportCompat\ndata class PageRequest(\n val pageToken: String? = null,\n val pageSize: Int = DEFAULT_PAGE_SIZE,\n) {\n init {\n require(pageSize in 1..MAX_PAGE_SIZE) {\n \"pageSize must be in 1..$MAX_PAGE_SIZE (was $pageSize)\"\n }\n }\n\n companion object {\n const val DEFAULT_PAGE_SIZE: Int = 50\n const val MAX_PAGE_SIZE: Int = 500\n }\n}" - }, - "UpdatePersonArgs": { - "kind": "data class", - "name": "UpdatePersonArgs", - "module": "service-api", - "source": "@Serializable\ndata class UpdatePersonArgs(\n val id: Uuid,\n val displayName: String? = null,\n val firstName: String? = null,\n val middleName: String? = null,\n val lastName: String? = null,\n val birthDate: LocalDate? = null,\n val uri: String? = null,\n val jurisdiction: String? = null,\n val organizationUnitId: Uuid? = null,\n)" - }, - "DeletePersonArgs": { - "kind": "data class", - "name": "DeletePersonArgs", - "module": "service-api", - "source": "@Serializable\ndata class DeletePersonArgs(val id: Uuid)" - }, - "DeletePersonResult": { - "kind": "data class", - "name": "DeletePersonResult", - "module": "service-api", - "source": "@Serializable\ndata class DeletePersonResult(val deleted: Boolean)" - }, - "CreateOrganizationArgs": { - "kind": "data class", - "name": "CreateOrganizationArgs", - "module": "service-api", - "source": "@Serializable\ndata class CreateOrganizationArgs(\n val displayName: String,\n val legalName: String,\n val organizationType: String? = null,\n val industry: String? = null,\n val contactEmail: String? = null,\n val websiteUrl: String? = null,\n val privacyPolicyUri: String? = null,\n val tosUri: String? = null,\n val origin: PartyOrigin = PartyOrigin.MANAGED,\n val uri: String? = null,\n val jurisdiction: String? = null,\n val ownerId: Uuid? = null,\n val organizationUnitId: Uuid? = null,\n)\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }" - }, - "Organization": { - "kind": "data class", - "name": "Organization", - "module": "public", - "source": "@JsExportCompat\n@Serializable\n@SerialName(\"organization\")\ndata class Organization\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n override val partyId: Uuid,\n @SerialName(\"tenantId\")\n override val tenantId: String,\n override val origin: PartyOrigin,\n @SerialName(\"displayName\")\n override val displayName: String,\n override val uri: String? = null,\n override val jurisdiction: String? = null,\n @SerialName(\"ownerId\")\n override val ownerId: Uuid? = null,\n @SerialName(\"organizationUnitId\")\n override val organizationUnitId: Uuid? = null,\n @SerialName(\"specializations\")\n override val specializations: List = emptyList(),\n @SerialName(\"createdAt\")\n override val createdAt: Instant,\n @SerialName(\"createdById\")\n override val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n override val updatedAt: Instant,\n @SerialName(\"updatedById\")\n override val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n override val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n override val deletedById: Uuid? = null,\n @SerialName(\"electronicAddresses\")\n override val electronicAddresses: List? = null,\n @SerialName(\"physicalAddresses\")\n override val physicalAddresses: List? = null,\n /** Registered legal name */\n @SerialName(\"legalName\")\n val legalName: String,\n /** Organization type (e.g. company, foundation, government) */\n @SerialName(\"organizationType\")\n val organizationType: String? = null,\n /** Industry classification */\n @SerialName(\"industry\")\n val industry: String? = null,\n /** Primary contact email */\n @SerialName(\"contactEmail\")\n val contactEmail: String? = null,\n /** Public website URL */\n @SerialName(\"websiteUrl\")\n val websiteUrl: String? = null,\n /** Privacy policy URI */\n @SerialName(\"privacyPolicyUri\")\n val privacyPolicyUri: String? = null,\n /** Terms of service URI */\n @SerialName(\"tosUri\")\n val tosUri: String? = null,\n ) : PartyEntity {\n override val partyType: PartyType get() = PartyType.ORGANIZATION\n }\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class PartySpecialization\n @JvmOverloads\n constructor(\n /** Human role label for this specialization (e.g. \"employee\", \"customer\", \"supplier\", \"student\") */\n @SerialName(\"subtype\")\n val subtype: String,\n /** The bound semantic Profile id; null indicates an untyped declaration */\n @SerialName(\"profileId\")\n val profileId: String? = null,\n /** The profile version the values were validated/captured against */\n @SerialName(\"profileVersion\")\n val profileVersion: String? = null,\n /** Values for THIS specialization; populated only when licensed */\n @SerialName(\"attributes\")\n val attributes: JsonObject? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class ElectronicAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Type of address (e.g. EMAIL, PHONE, URL, SOCIAL_MEDIA) */\n @SerialName(\"addressType\")\n val addressType: String,\n /** The address value */\n @SerialName(\"value\")\n val value: String,\n /** Optional label (e.g. \"Work\", \"Personal\", \"Mobile\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Whether this address has been verified */\n @SerialName(\"isVerified\")\n val isVerified: Boolean = false,\n /** When the address was verified */\n @SerialName(\"verifiedAt\")\n val verifiedAt: Instant? = null,\n /** When the address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When the address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n)\n\n@JsExportCompat\n@Serializable\ndata class PhysicalAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type/purpose of this address */\n @SerialName(\"addressType\")\n val addressType: String,\n /** User-friendly label (e.g. \"Headquarters\", \"Home\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Street address (house number, street name, unit) */\n @SerialName(\"streetAddress\")\n val streetAddress: String? = null,\n /** City/municipality name */\n @SerialName(\"city\")\n val city: String? = null,\n /** State/province/region */\n @SerialName(\"province\")\n val province: String? = null,\n /** Postal/ZIP code */\n @SerialName(\"postalCode\")\n val postalCode: String? = null,\n /** Country code (ISO 3166-1 alpha-2) */\n @SerialName(\"countryCode\")\n val countryCode: String? = null,\n /** Latitude coordinate */\n @SerialName(\"latitude\")\n val latitude: Double? = null,\n /** Longitude coordinate */\n @SerialName(\"longitude\")\n val longitude: Double? = null,\n /** When this address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When this address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n /** When the address was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the address (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the address was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the address (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the address was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the address (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n)\n\n@JsExportCompat\n@Serializable\n@JsonClassDiscriminator(\"partyType\")\nsealed interface PartyEntity {\n /** Unique identifier for the party */\n val partyId: Uuid\n\n /** Tenant this party belongs to */\n val tenantId: String\n\n /** The type of party (matches the JSON class discriminator) */\n val partyType: PartyType\n\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin\n\n /** User-friendly display name */\n val displayName: String\n\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String?\n\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String?\n\n /** Reference to the owning party */\n val ownerId: Uuid?\n\n /** The single home organization unit; null means the tenant root */\n val organizationUnitId: Uuid?\n\n /** The specializations (roles) this party bears; multi-typing allows several */\n val specializations: List\n\n /** When the party was created */\n val createdAt: Instant\n\n /** Who created the party (party ID) */\n val createdById: Uuid?\n\n /** When the party was last updated */\n val updatedAt: Instant\n\n /** Who last updated the party (party ID) */\n val updatedById: Uuid?\n\n /** When the party was soft-deleted (null if not deleted) */\n val deletedAt: Instant?\n\n /** Who deleted the party (party ID) */\n val deletedById: Uuid?\n\n /**\n * The party's electronic addresses, hydrated on demand. Null means the association was not\n * requested (default); an empty list means it was requested and there are none.\n */\n val electronicAddresses: List?\n\n /**\n * The party's physical addresses, hydrated on demand. Null means the association was not\n * requested (default); an empty list means it was requested and there are none.\n */\n val physicalAddresses: List?\n}\n\n@Serializable\n@JvmInline\nvalue class PartyType(\n val value: String,\n) {\n companion object {\n /** A human individual */\n val NATURAL_PERSON = PartyType(\"natural_person\")\n\n /** Alias for [NATURAL_PERSON] */\n val PERSON = NATURAL_PERSON\n\n /** A company, institution, or other legal entity */\n val ORGANIZATION = PartyType(\"organization\")\n\n /** A software-backed service participant (endpoint, integration, automated actor) */\n val SERVICE = PartyType(\"service\")\n\n /** A unit within an organization (department, division, sub-tenant scope) */\n val ORGANIZATION_UNIT = PartyType(\"organization_unit\")\n\n /** A collection of parties grouped for addressing or authorization */\n val GROUP = PartyType(\"group\")\n\n /** An autonomous actor acting on behalf of another party */\n val AGENT = PartyType(\"agent\")\n }\n\n override fun toString(): String = value\n}\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }\n\n @Serializable\n data class Human(\n override val id: String,\n /** Correlation key the engine binds to; UI signals completion against this key. */\n val correlationKey: String,\n /** Bounded wait; null means wait until the workflow's overall deadline. */\n val timeoutSeconds: Long? = null,\n val next: String? = null,\n ) : WorkflowTask()\n\n@JsExportCompat\n@Serializable\ndata class Tenant\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n val tenantId: String,\n @SerialName(\"tenantType\")\n val tenantType: TenantType,\n val name: String,\n val description: String? = null,\n /**\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\n * platform subdomain label and the dispatcher's peelable path segment.\n */\n val slug: String,\n /**\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\n * time (cycle detection walks up `parent_tenant_id`).\n */\n @SerialName(\"parentTenantId\")\n val parentTenantId: String? = null,\n val status: TenantStatus = TenantStatus.ACTIVE,\n /**\n * Generic \"system tenant\" flag. System tenants are excluded from default\n * listings and from all slug-based / parent-based resolution queries. Customer\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\n * their own system-tenant patterns. EDK does not define what a system tenant\n * is or what privileges it carries.\n */\n val system: Boolean = false,\n @SerialName(\"ownerPartyId\")\n val ownerPartyId: Uuid? = null,\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = tenantId\n }\n\n enum class Type {\n WORKFLOW_EXECUTION_STARTED,\n WORKFLOW_EXECUTION_COMPLETED,\n WORKFLOW_EXECUTION_FAILED,\n WORKFLOW_EXECUTION_TIMED_OUT,\n WORKFLOW_EXECUTION_CANCELED,\n WORKFLOW_EXECUTION_TERMINATED,\n WORKFLOW_EXECUTION_CONTINUED_AS_NEW,\n WORKFLOW_TASK_SCHEDULED,\n WORKFLOW_TASK_STARTED,\n WORKFLOW_TASK_COMPLETED,\n WORKFLOW_TASK_FAILED,\n WORKFLOW_TASK_TIMED_OUT,\n ACTIVITY_TASK_SCHEDULED,\n ACTIVITY_TASK_STARTED,\n ACTIVITY_TASK_COMPLETED,\n ACTIVITY_TASK_FAILED,\n ACTIVITY_TASK_TIMED_OUT,\n ACTIVITY_TASK_CANCEL_REQUESTED,\n ACTIVITY_TASK_CANCELED,\n TIMER_STARTED,\n TIMER_FIRED,\n TIMER_CANCELED,\n WORKFLOW_EXECUTION_SIGNALED,\n WORKFLOW_EXECUTION_UPDATE_ACCEPTED,\n WORKFLOW_EXECUTION_UPDATE_COMPLETED,\n WORKFLOW_EXECUTION_UPDATE_REJECTED,\n CHILD_WORKFLOW_EXECUTION_STARTED,\n CHILD_WORKFLOW_EXECUTION_COMPLETED,\n CHILD_WORKFLOW_EXECUTION_FAILED,\n MARKER_RECORDED,\n OTHER,\n }\n\n enum class State {\n CLOSED,\n OPEN,\n HALF_OPEN\n }\n\n /** Filter by schema object ID */\r\n @SerialName(\"schemaId\")\n\n-- discriminator-tagged sealed-interface JSON via kotlinx-serialization." - }, - "CreateOrganizationUnitArgs": { - "kind": "data class", - "name": "CreateOrganizationUnitArgs", - "module": "service-api", - "source": "@Serializable\ndata class CreateOrganizationUnitArgs(\n val displayName: String,\n val name: String,\n val parentOuId: Uuid? = null,\n val tosUri: String? = null,\n val branding: JsonObject? = null,\n val ouInheritancePolicy: String = \"READ_ONLY_ANCESTOR\",\n val origin: PartyOrigin = PartyOrigin.MANAGED,\n val uri: String? = null,\n val jurisdiction: String? = null,\n val ownerId: Uuid? = null,\n val organizationUnitId: Uuid? = null,\n)\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }" - }, - "OrganizationUnit": { - "kind": "data class", - "name": "OrganizationUnit", - "module": "public", - "source": "@JsExportCompat\n@Serializable\n@SerialName(\"organization_unit\")\ndata class OrganizationUnit\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n override val partyId: Uuid,\n @SerialName(\"tenantId\")\n override val tenantId: String,\n override val origin: PartyOrigin,\n @SerialName(\"displayName\")\n override val displayName: String,\n override val uri: String? = null,\n override val jurisdiction: String? = null,\n @SerialName(\"ownerId\")\n override val ownerId: Uuid? = null,\n @SerialName(\"organizationUnitId\")\n override val organizationUnitId: Uuid? = null,\n @SerialName(\"specializations\")\n override val specializations: List = emptyList(),\n @SerialName(\"createdAt\")\n override val createdAt: Instant,\n @SerialName(\"createdById\")\n override val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n override val updatedAt: Instant,\n @SerialName(\"updatedById\")\n override val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n override val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n override val deletedById: Uuid? = null,\n @SerialName(\"electronicAddresses\")\n override val electronicAddresses: List? = null,\n @SerialName(\"physicalAddresses\")\n override val physicalAddresses: List? = null,\n /** Parent organization unit; null means this unit sits directly under the organization root */\n @SerialName(\"parentOuId\")\n val parentOuId: Uuid? = null,\n /** Unit name */\n @SerialName(\"name\")\n val name: String,\n /** Terms of service URI for this unit */\n @SerialName(\"tosUri\")\n val tosUri: String? = null,\n /** Unit-level branding configuration */\n @SerialName(\"branding\")\n val branding: JsonObject? = null,\n /** How this unit inherits configuration from its ancestors */\n @SerialName(\"ouInheritancePolicy\")\n val ouInheritancePolicy: String = \"READ_ONLY_ANCESTOR\",\n /**\n * The direct child organization units, hydrated on demand. Null means the association\n * was not requested (default); an empty list means it was requested and there are none.\n */\n @SerialName(\"childUnits\")\n val childUnits: List? = null,\n /**\n * The parties that have this unit as their home organization unit, hydrated on demand.\n * Null means the association was not requested (default).\n */\n @SerialName(\"members\")\n val members: List? = null,\n ) : PartyEntity {\n override val partyType: PartyType get() = PartyType.ORGANIZATION_UNIT\n }\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class PartySpecialization\n @JvmOverloads\n constructor(\n /** Human role label for this specialization (e.g. \"employee\", \"customer\", \"supplier\", \"student\") */\n @SerialName(\"subtype\")\n val subtype: String,\n /** The bound semantic Profile id; null indicates an untyped declaration */\n @SerialName(\"profileId\")\n val profileId: String? = null,\n /** The profile version the values were validated/captured against */\n @SerialName(\"profileVersion\")\n val profileVersion: String? = null,\n /** Values for THIS specialization; populated only when licensed */\n @SerialName(\"attributes\")\n val attributes: JsonObject? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class ElectronicAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Type of address (e.g. EMAIL, PHONE, URL, SOCIAL_MEDIA) */\n @SerialName(\"addressType\")\n val addressType: String,\n /** The address value */\n @SerialName(\"value\")\n val value: String,\n /** Optional label (e.g. \"Work\", \"Personal\", \"Mobile\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Whether this address has been verified */\n @SerialName(\"isVerified\")\n val isVerified: Boolean = false,\n /** When the address was verified */\n @SerialName(\"verifiedAt\")\n val verifiedAt: Instant? = null,\n /** When the address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When the address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n)\n\n@JsExportCompat\n@Serializable\ndata class PhysicalAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type/purpose of this address */\n @SerialName(\"addressType\")\n val addressType: String,\n /** User-friendly label (e.g. \"Headquarters\", \"Home\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Street address (house number, street name, unit) */\n @SerialName(\"streetAddress\")\n val streetAddress: String? = null,\n /** City/municipality name */\n @SerialName(\"city\")\n val city: String? = null,\n /** State/province/region */\n @SerialName(\"province\")\n val province: String? = null,\n /** Postal/ZIP code */\n @SerialName(\"postalCode\")\n val postalCode: String? = null,\n /** Country code (ISO 3166-1 alpha-2) */\n @SerialName(\"countryCode\")\n val countryCode: String? = null,\n /** Latitude coordinate */\n @SerialName(\"latitude\")\n val latitude: Double? = null,\n /** Longitude coordinate */\n @SerialName(\"longitude\")\n val longitude: Double? = null,\n /** When this address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When this address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n /** When the address was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the address (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the address was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the address (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the address was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the address (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n)\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNull\")\n @Serializable(with = CDDLSerializer::class)\n object Null : CDDL(\"null\", MajorType.SPECIAL, 22, arrayOf(nil)) {\n fun newNull() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n@JsExportCompat\n@Serializable\n@JsonClassDiscriminator(\"partyType\")\nsealed interface PartyEntity {\n /** Unique identifier for the party */\n val partyId: Uuid\n\n /** Tenant this party belongs to */\n val tenantId: String\n\n /** The type of party (matches the JSON class discriminator) */\n val partyType: PartyType\n\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin\n\n /** User-friendly display name */\n val displayName: String\n\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String?\n\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String?\n\n /** Reference to the owning party */\n val ownerId: Uuid?\n\n /** The single home organization unit; null means the tenant root */\n val organizationUnitId: Uuid?\n\n /** The specializations (roles) this party bears; multi-typing allows several */\n val specializations: List\n\n /** When the party was created */\n val createdAt: Instant\n\n /** Who created the party (party ID) */\n val createdById: Uuid?\n\n /** When the party was last updated */\n val updatedAt: Instant\n\n /** Who last updated the party (party ID) */\n val updatedById: Uuid?\n\n /** When the party was soft-deleted (null if not deleted) */\n val deletedAt: Instant?\n\n /** Who deleted the party (party ID) */\n val deletedById: Uuid?\n\n /**\n * The party's electronic addresses, hydrated on demand. Null means the association was not\n * requested (default); an empty list means it was requested and there are none.\n */\n val electronicAddresses: List?\n\n /**\n * The party's physical addresses, hydrated on demand. Null means the association was not\n * requested (default); an empty list means it was requested and there are none.\n */\n val physicalAddresses: List?\n}\n\n@Serializable\n@JvmInline\nvalue class PartyType(\n val value: String,\n) {\n companion object {\n /** A human individual */\n val NATURAL_PERSON = PartyType(\"natural_person\")\n\n /** Alias for [NATURAL_PERSON] */\n val PERSON = NATURAL_PERSON\n\n /** A company, institution, or other legal entity */\n val ORGANIZATION = PartyType(\"organization\")\n\n /** A software-backed service participant (endpoint, integration, automated actor) */\n val SERVICE = PartyType(\"service\")\n\n /** A unit within an organization (department, division, sub-tenant scope) */\n val ORGANIZATION_UNIT = PartyType(\"organization_unit\")\n\n /** A collection of parties grouped for addressing or authorization */\n val GROUP = PartyType(\"group\")\n\n /** An autonomous actor acting on behalf of another party */\n val AGENT = PartyType(\"agent\")\n }\n\n override fun toString(): String = value\n}\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }\n\n @Serializable\n data class Human(\n override val id: String,\n /** Correlation key the engine binds to; UI signals completion against this key. */\n val correlationKey: String,\n /** Bounded wait; null means wait until the workflow's overall deadline. */\n val timeoutSeconds: Long? = null,\n val next: String? = null,\n ) : WorkflowTask()\n\n@JsExportCompat\n@Serializable\ndata class Tenant\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n val tenantId: String,\n @SerialName(\"tenantType\")\n val tenantType: TenantType,\n val name: String,\n val description: String? = null,\n /**\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\n * platform subdomain label and the dispatcher's peelable path segment.\n */\n val slug: String,\n /**\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\n * time (cycle detection walks up `parent_tenant_id`).\n */\n @SerialName(\"parentTenantId\")\n val parentTenantId: String? = null,\n val status: TenantStatus = TenantStatus.ACTIVE,\n /**\n * Generic \"system tenant\" flag. System tenants are excluded from default\n * listings and from all slug-based / parent-based resolution queries. Customer\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\n * their own system-tenant patterns. EDK does not define what a system tenant\n * is or what privileges it carries.\n */\n val system: Boolean = false,\n @SerialName(\"ownerPartyId\")\n val ownerPartyId: Uuid? = null,\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = tenantId\n }\n\n enum class Type {\n WORKFLOW_EXECUTION_STARTED,\n WORKFLOW_EXECUTION_COMPLETED,\n WORKFLOW_EXECUTION_FAILED,\n WORKFLOW_EXECUTION_TIMED_OUT,\n WORKFLOW_EXECUTION_CANCELED,\n WORKFLOW_EXECUTION_TERMINATED,\n WORKFLOW_EXECUTION_CONTINUED_AS_NEW,\n WORKFLOW_TASK_SCHEDULED,\n WORKFLOW_TASK_STARTED,\n WORKFLOW_TASK_COMPLETED,\n WORKFLOW_TASK_FAILED,\n WORKFLOW_TASK_TIMED_OUT,\n ACTIVITY_TASK_SCHEDULED,\n ACTIVITY_TASK_STARTED,\n ACTIVITY_TASK_COMPLETED,\n ACTIVITY_TASK_FAILED,\n ACTIVITY_TASK_TIMED_OUT,\n ACTIVITY_TASK_CANCEL_REQUESTED,\n ACTIVITY_TASK_CANCELED,\n TIMER_STARTED,\n TIMER_FIRED,\n TIMER_CANCELED,\n WORKFLOW_EXECUTION_SIGNALED,\n WORKFLOW_EXECUTION_UPDATE_ACCEPTED,\n WORKFLOW_EXECUTION_UPDATE_COMPLETED,\n WORKFLOW_EXECUTION_UPDATE_REJECTED,\n CHILD_WORKFLOW_EXECUTION_STARTED,\n CHILD_WORKFLOW_EXECUTION_COMPLETED,\n CHILD_WORKFLOW_EXECUTION_FAILED,\n MARKER_RECORDED,\n OTHER,\n }\n\n enum class State {\n CLOSED,\n OPEN,\n HALF_OPEN\n }\n\n /** Filter by schema object ID */\r\n @SerialName(\"schemaId\")" - }, - "CreateServiceArgs": { - "kind": "data class", - "name": "CreateServiceArgs", - "module": "service-api", - "source": "@Serializable\ndata class CreateServiceArgs(\n val displayName: String,\n val serviceType: String? = null,\n val endpointUri: String? = null,\n val oauthClientId: String? = null,\n val origin: PartyOrigin = PartyOrigin.MANAGED,\n val uri: String? = null,\n val jurisdiction: String? = null,\n val ownerId: Uuid? = null,\n val organizationUnitId: Uuid? = null,\n)\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }" - }, - "Service": { - "kind": "data class", - "name": "Service", - "module": "public", - "source": " public data class Service(\n public val uuid: Uuid,\n ) : Filter()\n\n@JsExportCompat\npublic sealed class Filter {\n /**\n * | Platform | Supported | Details |\n * |------------|:---------------:|----------------------------------------------------------------------------------------------|\n * | Android | Yes | Supported natively |\n * | Apple | Yes1 | Supported natively if the only filter type used, otherwise provided by Kable via flow filter |\n * | JavaScript | Yes | Supported natively |\n *\n * 1: The recommended practice is to provide only [service filter][Filter.Service]s on Apple platform.\n * If any filters other than [Filter.Service] are used on Apple platform, then filtering will not be performed natively.\n */\n public data class Service(\n public val uuid: Uuid,\n ) : Filter()\n\n public sealed class Name : Filter() {\n /**\n * | Platform | Supported | Details |\n * |------------|:---------:|-------------------------------------------|\n * | Android | Yes | Supported natively |\n * | Apple | Yes | Support provided by Kable via flow filter |\n * | JavaScript | Yes | Supported natively |\n */\n public data class Exact(\n public val exact: String,\n ) : Name()\n\n /**\n * | Platform | Supported | Details |\n * |------------|:---------:|-------------------------------------------|\n * | Android | Yes | Support provided by Kable via flow filter |\n * | Apple | Yes | Support provided by Kable via flow filter |\n * | JavaScript | Yes | Supported natively |\n */\n public data class Prefix(\n val prefix: String,\n ) : Name()\n }\n\n /**\n * | Platform | Supported | Details |\n * |------------|:---------:|----------------------------------------|\n * | Android | Yes | Supported natively |\n * | Apple | No | Throws [UnsupportedOperationException] |\n * | JavaScript | No | Throws [UnsupportedOperationException] |\n */\n public data class Address(\n public val address: String,\n ) : Filter()\n\n /**\n * Provides support for filtering against advertisement manufacturer data.\n *\n * If only portions of the manufacturer [data] needs to match, then [dataMask] can be used to identify the relevant\n * bits.\n *\n * Some examples to demonstrate the [dataMask] functionality:\n *\n * | [dataMask] value | Bit representation | [data] only needs to match... |\n * |---------------------------|---------------------|----------------------------------------------------------------|\n * | `byteArrayOf(0x0F, 0x00)` | 0000 1111 0000 0000 | bits 0-3 of the first byte of advertisement manufacturer data. |\n * | `byteArrayOf(0x00, 0xFF)` | 0000 0000 1111 1111 | the 2nd byte of advertisement manufacturer data. |\n * | `byteArrayOf(0xF0)` | 1111 0000 | bits 4-7 of the first byte of advertisement manufacturer data. |\n *\n * | Platform | Supported | Details |\n * |------------|:---------:|-------------------------------------------|\n * | Android | Yes | Supported natively |\n * | Apple | Yes | Support provided by Kable via flow filter |\n * | JavaScript | Yes | Supported natively |\n *\n * JavaScript support was added in Chrome 92 according to: https://developer.chrome.com/articles/bluetooth/#manufacturer-data-filter\n */\n public class ManufacturerData(\n /**\n * Company identifier (16-bit).\n * A negative [id] is considered an invalid id.\n *\n * List of assigned numbers can be found at (section: 7 Company Identifiers): https://www.bluetooth.com/specifications/assigned-numbers/\n */\n public val id: Int,\n /** Must be non-`null` if [dataMask] is non-`null`. */\n public val data: ByteArray? = null,\n /**\n * For any bit in the mask, set it to 1 if advertisement manufacturer data needs to match the corresponding bit\n * in [data], otherwise set it to 0. If [dataMask] is not `null`, then it must have the same length as [data].\n */\n public val dataMask: ByteArray? = null,\n ) : Filter() {\n @JvmOverloads\n public constructor(id: ByteArray, data: ByteArray? = null, dataMask: ByteArray? = null) : this(id.toShort(), data, dataMask)\n\n init {\n require(id >= 0) { \"Company identifier cannot be negative, was $id\" }\n require(id <= 65535) { \"Company identifier cannot be more than 16-bits (65535), was $id\" }\n require(data == null || data.isNotEmpty()) { \"If data is present (non-null), it must be non-empty\" }\n if (dataMask != null) {\n requireNotNull(data) { \"Data is null but must be non-null when dataMask is non-null\" }\n requireDataAndMaskHaveSameLength(data, dataMask)\n }\n }\n\n override fun toString(): String = \"ManufacturerData(id=$id, data=${data?.toHexString()}, dataMask=${dataMask?.toHexString()})\"\n }\n\n /**\n * Provides support for filtering against advertisement service data.\n *\n * If only portions of the service [data] needs to match, then [dataMask] can be used to\n * identify the relevant bits.\n *\n * Some examples to demonstrate the [dataMask] functionality:\n *\n * | [dataMask] value | Bit representation | [data] only needs to match... |\n * |---------------------------|---------------------|-----------------------------------------------------------|\n * | `byteArrayOf(0x0F, 0x00)` | 0000 1111 0000 0000 | bits 0-3 of the first byte of advertisement service data. |\n * | `byteArrayOf(0x00, 0xFF)` | 0000 0000 1111 1111 | the 2nd byte of advertisement service data. |\n * | `byteArrayOf(0xF0)` | 1111 0000 | bits 4-7 of the first byte of advertisement service data. |\n *\n * | Platform | Supported | Details |\n * |------------|:---------:|-------------------------------------------|\n * | Android | Yes | Supported natively |\n * | Apple | Yes | Support provided by Kable via flow filter |\n * | JavaScript | Yes | Support provided by Kable via flow filter |\n */\n public class ServiceData(\n public val uuid: Uuid,\n public val data: ByteArray? = null,\n /**\n * For any bit in the mask, set it to 1 if advertisement service data needs to match the\n * corresponding bit in [data], otherwise set it to 0. If [dataMask] is not `null`, then it\n * must have the same length as [data].\n */\n public val dataMask: ByteArray? = null,\n ) : Filter() {\n init {\n require(data == null || data.isNotEmpty()) { \"If data is present (non-null), it must be non-empty\" }\n if (dataMask != null) {\n requireNotNull(data) { \"Data is null but must be non-null when dataMask is non-null\" }\n requireDataAndMaskHaveSameLength(data, dataMask)\n }\n }\n\n override fun toString(): String = \"ServiceData(uuid=$uuid, data=${data?.toHexString()}, dataMask=${dataMask?.toHexString()})\"\n }\n}\n\n public sealed class Name : Filter() {\n /**\n * | Platform | Supported | Details |\n * |------------|:---------:|-------------------------------------------|\n * | Android | Yes | Supported natively |\n * | Apple | Yes | Support provided by Kable via flow filter |\n * | JavaScript | Yes | Supported natively |\n */\n public data class Exact(\n public val exact: String,\n ) : Name()\n\n /**\n * | Platform | Supported | Details |\n * |------------|:---------:|-------------------------------------------|\n * | Android | Yes | Support provided by Kable via flow filter |\n * | Apple | Yes | Support provided by Kable via flow filter |\n * | JavaScript | Yes | Supported natively |\n */\n public data class Prefix(\n val prefix: String,\n ) : Name()\n }\n\n public data class Exact(\n public val exact: String,\n ) : Name()\n\n public data class Prefix(\n val prefix: String,\n ) : Name()\n\n public data class Address(\n public val address: String,\n ) : Filter()\n\n public class ManufacturerData(\n /**\n * Company identifier (16-bit).\n * A negative [id] is considered an invalid id.\n *\n * List of assigned numbers can be found at (section: 7 Company Identifiers): https://www.bluetooth.com/specifications/assigned-numbers/\n */\n public val id: Int,\n /** Must be non-`null` if [dataMask] is non-`null`. */\n public val data: ByteArray? = null,\n /**\n * For any bit in the mask, set it to 1 if advertisement manufacturer data needs to match the corresponding bit\n * in [data], otherwise set it to 0. If [dataMask] is not `null`, then it must have the same length as [data].\n */\n public val dataMask: ByteArray? = null,\n ) : Filter() {\n @JvmOverloads\n public constructor(id: ByteArray, data: ByteArray? = null, dataMask: ByteArray? = null) : this(id.toShort(), data, dataMask)\n\n init {\n require(id >= 0) { \"Company identifier cannot be negative, was $id\" }\n require(id <= 65535) { \"Company identifier cannot be more than 16-bits (65535), was $id\" }\n require(data == null || data.isNotEmpty()) { \"If data is present (non-null), it must be non-empty\" }\n if (dataMask != null) {\n requireNotNull(data) { \"Data is null but must be non-null when dataMask is non-null\" }\n requireDataAndMaskHaveSameLength(data, dataMask)\n }\n }\n\n override fun toString(): String = \"ManufacturerData(id=$id, data=${data?.toHexString()}, dataMask=${dataMask?.toHexString()})\"\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"Data\", exact = true)\n data class Data(\n val value: ByteArray,\n ) : BleResponse()\n\n public class ServiceData(\n public val uuid: Uuid,\n public val data: ByteArray? = null,\n /**\n * For any bit in the mask, set it to 1 if advertisement service data needs to match the\n * corresponding bit in [data], otherwise set it to 0. If [dataMask] is not `null`, then it\n * must have the same length as [data].\n */\n public val dataMask: ByteArray? = null,\n ) : Filter() {\n init {\n require(data == null || data.isNotEmpty()) { \"If data is present (non-null), it must be non-empty\" }\n if (dataMask != null) {\n requireNotNull(data) { \"Data is null but must be non-null when dataMask is non-null\" }\n requireDataAndMaskHaveSameLength(data, dataMask)\n }\n }\n\n override fun toString(): String = \"ServiceData(uuid=$uuid, data=${data?.toHexString()}, dataMask=${dataMask?.toHexString()})\"\n }" - }, - "SetApplicationLoginConfigArgs": { - "kind": "data class", - "name": "SetApplicationLoginConfigArgs", - "module": "service-api", - "source": "@Serializable\ndata class SetApplicationLoginConfigArgs(\n val applicationId: Uuid,\n val allowedMethods: Set = emptySet(),\n val loginIdentifierTypes: Set = emptySet(),\n val allowedIdpIds: Set = emptySet(),\n val selfRegistration: Boolean = false,\n)\n\n@Serializable\n@JvmInline\nvalue class AuthMethod(\n val value: String,\n) {\n companion object {\n /** Username/identifier plus password. */\n val PASSWORD = AuthMethod(\"password\")\n\n /** One-time passcode delivered by email. */\n val EMAIL_OTP = AuthMethod(\"email_otp\")\n\n /** Single-use magic link delivered out of band. */\n val MAGIC_LINK = AuthMethod(\"magic_link\")\n\n /** Time-based one-time password (authenticator app). */\n val TOTP = AuthMethod(\"totp\")\n\n /** Federated login via an external OIDC identity provider. */\n val FEDERATED_OIDC = AuthMethod(\"federated_oidc\")\n\n /** Wallet-based authentication (verifiable presentation). */\n val WALLET = AuthMethod(\"wallet\")\n }\n\n override fun toString(): String = value\n}\n\n@Serializable\n@JvmInline\nvalue class IdentifierType(\n val value: String,\n) {\n companion object {\n /** W3C Decentralized Identifier */\n val DID = IdentifierType(\"did\")\n\n /** X.509 Certificate (has identifier_x509 extension) */\n val X509 = IdentifierType(\"x509\")\n }\n\n override fun toString(): String = value\n}\n\n @JsExportCompat\n @Serializable\n data class Federated(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n /**\n * Owner's stable identifier inside the external IDP — typically the `sub`\n * claim, but can be any claim agreed in [FederationProviderInput.claimMapping].\n */\n val externalSubject: String,\n ) : OwnerInput()" - }, - "ApplicationLoginConfigResult": { - "kind": "data class", - "name": "ApplicationLoginConfigResult", - "module": "persistence-api", - "source": "@Serializable\ndata class ApplicationLoginConfigResult(\n @SerialName(\"applicationId\")\n val applicationId: Uuid,\n\n @SerialName(\"tenantId\")\n val tenantId: String,\n\n @SerialName(\"allowedMethods\")\n val allowedMethods: Set = emptySet(),\n\n @SerialName(\"loginIdentifierTypes\")\n val loginIdentifierTypes: Set = emptySet(),\n\n @SerialName(\"allowedIdpIds\")\n val allowedIdpIds: Set = emptySet(),\n\n @SerialName(\"selfRegistration\")\n val selfRegistration: Boolean = false,\n\n // Audit fields\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null\n) {\n companion object {\n fun from(config: ApplicationLoginConfig) = ApplicationLoginConfigResult(\n applicationId = config.applicationId,\n tenantId = config.tenantId,\n allowedMethods = config.allowedMethods,\n loginIdentifierTypes = config.loginIdentifierTypes,\n allowedIdpIds = config.allowedIdpIds,\n selfRegistration = config.selfRegistration,\n createdAt = config.createdAt,\n createdById = config.createdById,\n updatedAt = config.updatedAt,\n updatedById = config.updatedById,\n deletedAt = config.deletedAt,\n deletedById = config.deletedById\n )\n }\n\n fun toApplicationLoginConfig() = ApplicationLoginConfig(\n applicationId = applicationId,\n tenantId = tenantId,\n allowedMethods = allowedMethods,\n loginIdentifierTypes = loginIdentifierTypes,\n allowedIdpIds = allowedIdpIds,\n selfRegistration = selfRegistration,\n createdAt = createdAt,\n createdById = createdById,\n updatedAt = updatedAt,\n updatedById = updatedById,\n deletedAt = deletedAt,\n deletedById = deletedById\n )\n}\n\n@Serializable\n@JvmInline\nvalue class AuthMethod(\n val value: String,\n) {\n companion object {\n /** Username/identifier plus password. */\n val PASSWORD = AuthMethod(\"password\")\n\n /** One-time passcode delivered by email. */\n val EMAIL_OTP = AuthMethod(\"email_otp\")\n\n /** Single-use magic link delivered out of band. */\n val MAGIC_LINK = AuthMethod(\"magic_link\")\n\n /** Time-based one-time password (authenticator app). */\n val TOTP = AuthMethod(\"totp\")\n\n /** Federated login via an external OIDC identity provider. */\n val FEDERATED_OIDC = AuthMethod(\"federated_oidc\")\n\n /** Wallet-based authentication (verifiable presentation). */\n val WALLET = AuthMethod(\"wallet\")\n }\n\n override fun toString(): String = value\n}\n\n@Serializable\n@JvmInline\nvalue class IdentifierType(\n val value: String,\n) {\n companion object {\n /** W3C Decentralized Identifier */\n val DID = IdentifierType(\"did\")\n\n /** X.509 Certificate (has identifier_x509 extension) */\n val X509 = IdentifierType(\"x509\")\n }\n\n override fun toString(): String = value\n}\n\n@Serializable\ndata class ApplicationLoginConfig(\n /** Application party id - primary key (the `service` login surface) */\n @SerialName(\"applicationId\")\n val applicationId: Uuid,\n\n /** Tenant this login config belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n\n /**\n * The authentication methods this application accepts.\n * Stored as a JSON-encoded TEXT column at the persistence layer.\n */\n @SerialName(\"allowedMethods\")\n val allowedMethods: Set = emptySet(),\n\n /**\n * The identifier types that may be used to log in to this application.\n * Stored as a JSON-encoded TEXT column at the persistence layer.\n */\n @SerialName(\"loginIdentifierTypes\")\n val loginIdentifierTypes: Set = emptySet(),\n\n /**\n * The external IdP ids permitted for federated login to this application.\n * Stored as a JSON-encoded TEXT column at the persistence layer.\n */\n @SerialName(\"allowedIdpIds\")\n val allowedIdpIds: Set = emptySet(),\n\n /** Whether identities may self-register against this application */\n @SerialName(\"selfRegistration\")\n val selfRegistration: Boolean = false,\n\n // Audit fields\n /** When the login config was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n /** Who created the login config (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n\n /** When the login config was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n\n /** Who last updated the login config (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n\n /** When the login config was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n\n /** Who deleted the login config (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null\n) : HasId {\n override val id: String get() = applicationId.toString()\n}\n\n @JsExportCompat\n @Serializable\n data class Federated(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n /**\n * Owner's stable identifier inside the external IDP — typically the `sub`\n * claim, but can be any claim agreed in [FederationProviderInput.claimMapping].\n */\n val externalSubject: String,\n ) : OwnerInput()\n\n@JsExportCompat\n@Serializable\ndata class Tenant\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n val tenantId: String,\n @SerialName(\"tenantType\")\n val tenantType: TenantType,\n val name: String,\n val description: String? = null,\n /**\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\n * platform subdomain label and the dispatcher's peelable path segment.\n */\n val slug: String,\n /**\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\n * time (cycle detection walks up `parent_tenant_id`).\n */\n @SerialName(\"parentTenantId\")\n val parentTenantId: String? = null,\n val status: TenantStatus = TenantStatus.ACTIVE,\n /**\n * Generic \"system tenant\" flag. System tenants are excluded from default\n * listings and from all slug-based / parent-based resolution queries. Customer\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\n * their own system-tenant patterns. EDK does not define what a system tenant\n * is or what privileges it carries.\n */\n val system: Boolean = false,\n @SerialName(\"ownerPartyId\")\n val ownerPartyId: Uuid? = null,\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = tenantId\n }\n\n-- discriminator-tagged sealed-interface JSON via kotlinx-serialization.\n\n /** Filter by schema object ID */\r\n @SerialName(\"schemaId\")\n\n@JsExportCompat\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"HasId\", exact = true)\ninterface HasId {\n val id: String\n}" - }, - "SetIdentityApplicationBindingArgs": { - "kind": "data class", - "name": "SetIdentityApplicationBindingArgs", - "module": "service-api", - "source": "@Serializable\ndata class SetIdentityApplicationBindingArgs(\n val identityId: Uuid,\n val applicationId: Uuid,\n val capabilities: Set = emptySet(),\n val allowedMethods: Set = emptySet(),\n val applicationRole: String? = null,\n val status: BindingStatus = BindingStatus.ACTIVE,\n val validFrom: Instant? = null,\n val validUntil: Instant? = null,\n)\n\n@Serializable\n@JvmInline\nvalue class ApplicationCapability(\n val value: String,\n) {\n companion object {\n /** The application can authenticate identities. */\n val AUTHENTICABLE = ApplicationCapability(\"authenticable\")\n }\n\n override fun toString(): String = value\n}\n\n@Serializable\n@JvmInline\nvalue class AuthMethod(\n val value: String,\n) {\n companion object {\n /** Username/identifier plus password. */\n val PASSWORD = AuthMethod(\"password\")\n\n /** One-time passcode delivered by email. */\n val EMAIL_OTP = AuthMethod(\"email_otp\")\n\n /** Single-use magic link delivered out of band. */\n val MAGIC_LINK = AuthMethod(\"magic_link\")\n\n /** Time-based one-time password (authenticator app). */\n val TOTP = AuthMethod(\"totp\")\n\n /** Federated login via an external OIDC identity provider. */\n val FEDERATED_OIDC = AuthMethod(\"federated_oidc\")\n\n /** Wallet-based authentication (verifiable presentation). */\n val WALLET = AuthMethod(\"wallet\")\n }\n\n override fun toString(): String = value\n}\n\n@JsExportCompat\n@Serializable\nenum class BindingStatus {\n /** The binding is active and may be used to authenticate. */\n @SerialName(\"active\")\n ACTIVE,\n\n /** The binding is temporarily suspended and may not be used to authenticate. */\n @SerialName(\"suspended\")\n SUSPENDED,\n\n /** The binding is permanently revoked. */\n @SerialName(\"revoked\")\n REVOKED,\n}\n\n @JsExportCompat\n @Serializable\n data class Federated(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n /**\n * Owner's stable identifier inside the external IDP — typically the `sub`\n * claim, but can be any claim agreed in [FederationProviderInput.claimMapping].\n */\n val externalSubject: String,\n ) : OwnerInput()" - }, - "IdentityApplicationBindingResult": { - "kind": "data class", - "name": "IdentityApplicationBindingResult", - "module": "persistence-api", - "source": "@Serializable\ndata class IdentityApplicationBindingResult(\n @SerialName(\"id\")\n val bindingId: Uuid,\n\n @SerialName(\"tenantId\")\n val tenantId: String,\n\n @SerialName(\"identityId\")\n val identityId: Uuid,\n\n @SerialName(\"applicationId\")\n val applicationId: Uuid,\n\n @SerialName(\"capabilities\")\n val capabilities: Set = emptySet(),\n\n @SerialName(\"allowedMethods\")\n val allowedMethods: Set = emptySet(),\n\n @SerialName(\"applicationRole\")\n val applicationRole: String? = null,\n\n @SerialName(\"status\")\n val status: BindingStatus = BindingStatus.ACTIVE,\n\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n\n // Audit fields\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null\n) {\n companion object {\n fun from(binding: IdentityApplicationBinding) = IdentityApplicationBindingResult(\n bindingId = binding.bindingId,\n tenantId = binding.tenantId,\n identityId = binding.identityId,\n applicationId = binding.applicationId,\n capabilities = binding.capabilities,\n allowedMethods = binding.allowedMethods,\n applicationRole = binding.applicationRole,\n status = binding.status,\n validFrom = binding.validFrom,\n validUntil = binding.validUntil,\n createdAt = binding.createdAt,\n createdById = binding.createdById,\n updatedAt = binding.updatedAt,\n updatedById = binding.updatedById,\n deletedAt = binding.deletedAt,\n deletedById = binding.deletedById\n )\n }\n\n fun toIdentityApplicationBinding() = IdentityApplicationBinding(\n bindingId = bindingId,\n tenantId = tenantId,\n identityId = identityId,\n applicationId = applicationId,\n capabilities = capabilities,\n allowedMethods = allowedMethods,\n applicationRole = applicationRole,\n status = status,\n validFrom = validFrom,\n validUntil = validUntil,\n createdAt = createdAt,\n createdById = createdById,\n updatedAt = updatedAt,\n updatedById = updatedById,\n deletedAt = deletedAt,\n deletedById = deletedById\n )\n}\n\n@Serializable\n@JvmInline\nvalue class ApplicationCapability(\n val value: String,\n) {\n companion object {\n /** The application can authenticate identities. */\n val AUTHENTICABLE = ApplicationCapability(\"authenticable\")\n }\n\n override fun toString(): String = value\n}\n\n@Serializable\n@JvmInline\nvalue class AuthMethod(\n val value: String,\n) {\n companion object {\n /** Username/identifier plus password. */\n val PASSWORD = AuthMethod(\"password\")\n\n /** One-time passcode delivered by email. */\n val EMAIL_OTP = AuthMethod(\"email_otp\")\n\n /** Single-use magic link delivered out of band. */\n val MAGIC_LINK = AuthMethod(\"magic_link\")\n\n /** Time-based one-time password (authenticator app). */\n val TOTP = AuthMethod(\"totp\")\n\n /** Federated login via an external OIDC identity provider. */\n val FEDERATED_OIDC = AuthMethod(\"federated_oidc\")\n\n /** Wallet-based authentication (verifiable presentation). */\n val WALLET = AuthMethod(\"wallet\")\n }\n\n override fun toString(): String = value\n}\n\n@JsExportCompat\n@Serializable\nenum class BindingStatus {\n /** The binding is active and may be used to authenticate. */\n @SerialName(\"active\")\n ACTIVE,\n\n /** The binding is temporarily suspended and may not be used to authenticate. */\n @SerialName(\"suspended\")\n SUSPENDED,\n\n /** The binding is permanently revoked. */\n @SerialName(\"revoked\")\n REVOKED,\n}\n\n@Serializable\ndata class IdentityApplicationBinding(\n /** Unique identifier for this binding row */\n @SerialName(\"id\")\n val bindingId: Uuid,\n\n /** Tenant this binding belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n\n /** The identity that is bound to the application */\n @SerialName(\"identityId\")\n val identityId: Uuid,\n\n /** The application (party of party-type `service`) the identity is bound to */\n @SerialName(\"applicationId\")\n val applicationId: Uuid,\n\n /**\n * The capabilities this binding grants the identity on the application.\n * Stored as a JSON-encoded TEXT column at the persistence layer.\n */\n @SerialName(\"capabilities\")\n val capabilities: Set = emptySet(),\n\n /**\n * The authentication methods this binding permits the identity to use.\n * Stored as a JSON-encoded TEXT column at the persistence layer.\n */\n @SerialName(\"allowedMethods\")\n val allowedMethods: Set = emptySet(),\n\n /** The identity's role within the application, if any */\n @SerialName(\"applicationRole\")\n val applicationRole: String? = null,\n\n /** Lifecycle status of this binding */\n @SerialName(\"status\")\n val status: BindingStatus = BindingStatus.ACTIVE,\n\n /** When this binding becomes valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n\n /** When this binding stops being valid (null means open-ended) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n\n // Audit fields\n /** When the binding was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n /** Who created the binding (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n\n /** When the binding was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n\n /** Who last updated the binding (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n\n /** When the binding was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n\n /** Who deleted the binding (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null\n) : HasId {\n override val id: String get() = bindingId.toString()\n}\n\n @JsExportCompat\n @Serializable\n data class Federated(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n /**\n * Owner's stable identifier inside the external IDP — typically the `sub`\n * claim, but can be any claim agreed in [FederationProviderInput.claimMapping].\n */\n val externalSubject: String,\n ) : OwnerInput()\n\n@JsExportCompat\n@Serializable\ndata class Tenant\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n val tenantId: String,\n @SerialName(\"tenantType\")\n val tenantType: TenantType,\n val name: String,\n val description: String? = null,\n /**\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\n * platform subdomain label and the dispatcher's peelable path segment.\n */\n val slug: String,\n /**\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\n * time (cycle detection walks up `parent_tenant_id`).\n */\n @SerialName(\"parentTenantId\")\n val parentTenantId: String? = null,\n val status: TenantStatus = TenantStatus.ACTIVE,\n /**\n * Generic \"system tenant\" flag. System tenants are excluded from default\n * listings and from all slug-based / parent-based resolution queries. Customer\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\n * their own system-tenant patterns. EDK does not define what a system tenant\n * is or what privileges it carries.\n */\n val system: Boolean = false,\n @SerialName(\"ownerPartyId\")\n val ownerPartyId: Uuid? = null,\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = tenantId\n }\n\n-- discriminator-tagged sealed-interface JSON via kotlinx-serialization.\n\n /** Filter by schema object ID */\r\n @SerialName(\"schemaId\")\n\n@JsExportCompat\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"HasId\", exact = true)\ninterface HasId {\n val id: String\n}" - }, - "DeleteIdentityApplicationBindingArgs": { - "kind": "data class", - "name": "DeleteIdentityApplicationBindingArgs", - "module": "service-api", - "source": "@Serializable\ndata class DeleteIdentityApplicationBindingArgs(val identityId: Uuid, val applicationId: Uuid)" - }, - "DeleteIdentityApplicationBindingResult": { - "kind": "data class", - "name": "DeleteIdentityApplicationBindingResult", - "module": "service-api", - "source": "@Serializable\ndata class DeleteIdentityApplicationBindingResult(val deleted: Boolean)" - }, - "CreateGroupArgs": { - "kind": "data class", - "name": "CreateGroupArgs", - "module": "service-api", - "source": "@Serializable\ndata class CreateGroupArgs(\n val displayName: String,\n val name: String,\n val origin: PartyOrigin = PartyOrigin.MANAGED,\n val uri: String? = null,\n val jurisdiction: String? = null,\n val ownerId: Uuid? = null,\n val organizationUnitId: Uuid? = null,\n)\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }" - }, - "Group": { - "kind": "data class", - "name": "Group", - "module": "public", - "source": "@JsExportCompat\n@Serializable\n@SerialName(\"group\")\ndata class Group\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n override val partyId: Uuid,\n @SerialName(\"tenantId\")\n override val tenantId: String,\n override val origin: PartyOrigin,\n @SerialName(\"displayName\")\n override val displayName: String,\n override val uri: String? = null,\n override val jurisdiction: String? = null,\n @SerialName(\"ownerId\")\n override val ownerId: Uuid? = null,\n @SerialName(\"organizationUnitId\")\n override val organizationUnitId: Uuid? = null,\n @SerialName(\"createdAt\")\n override val createdAt: Instant,\n @SerialName(\"createdById\")\n override val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n override val updatedAt: Instant,\n @SerialName(\"updatedById\")\n override val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n override val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n override val deletedById: Uuid? = null,\n @SerialName(\"electronicAddresses\")\n override val electronicAddresses: List? = null,\n @SerialName(\"physicalAddresses\")\n override val physicalAddresses: List? = null,\n /** Group name */\n @SerialName(\"name\")\n val name: String,\n /**\n * The member parties of this group, hydrated on demand. Null means the association was\n * not requested (default); an empty list means it was requested and there are none.\n */\n @SerialName(\"members\")\n val members: List? = null,\n ) : PartyEntity {\n override val partyType: PartyType get() = PartyType.GROUP\n\n /** A group never bears specializations. */\n @SerialName(\"specializations\")\n override val specializations: List = emptyList()\n }\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class ElectronicAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Type of address (e.g. EMAIL, PHONE, URL, SOCIAL_MEDIA) */\n @SerialName(\"addressType\")\n val addressType: String,\n /** The address value */\n @SerialName(\"value\")\n val value: String,\n /** Optional label (e.g. \"Work\", \"Personal\", \"Mobile\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Whether this address has been verified */\n @SerialName(\"isVerified\")\n val isVerified: Boolean = false,\n /** When the address was verified */\n @SerialName(\"verifiedAt\")\n val verifiedAt: Instant? = null,\n /** When the address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When the address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n)\n\n@JsExportCompat\n@Serializable\ndata class PhysicalAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type/purpose of this address */\n @SerialName(\"addressType\")\n val addressType: String,\n /** User-friendly label (e.g. \"Headquarters\", \"Home\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Street address (house number, street name, unit) */\n @SerialName(\"streetAddress\")\n val streetAddress: String? = null,\n /** City/municipality name */\n @SerialName(\"city\")\n val city: String? = null,\n /** State/province/region */\n @SerialName(\"province\")\n val province: String? = null,\n /** Postal/ZIP code */\n @SerialName(\"postalCode\")\n val postalCode: String? = null,\n /** Country code (ISO 3166-1 alpha-2) */\n @SerialName(\"countryCode\")\n val countryCode: String? = null,\n /** Latitude coordinate */\n @SerialName(\"latitude\")\n val latitude: Double? = null,\n /** Longitude coordinate */\n @SerialName(\"longitude\")\n val longitude: Double? = null,\n /** When this address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When this address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n /** When the address was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the address (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the address was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the address (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the address was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the address (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n)\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNull\")\n @Serializable(with = CDDLSerializer::class)\n object Null : CDDL(\"null\", MajorType.SPECIAL, 22, arrayOf(nil)) {\n fun newNull() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n@JsExportCompat\n@Serializable\n@JsonClassDiscriminator(\"partyType\")\nsealed interface PartyEntity {\n /** Unique identifier for the party */\n val partyId: Uuid\n\n /** Tenant this party belongs to */\n val tenantId: String\n\n /** The type of party (matches the JSON class discriminator) */\n val partyType: PartyType\n\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin\n\n /** User-friendly display name */\n val displayName: String\n\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String?\n\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String?\n\n /** Reference to the owning party */\n val ownerId: Uuid?\n\n /** The single home organization unit; null means the tenant root */\n val organizationUnitId: Uuid?\n\n /** The specializations (roles) this party bears; multi-typing allows several */\n val specializations: List\n\n /** When the party was created */\n val createdAt: Instant\n\n /** Who created the party (party ID) */\n val createdById: Uuid?\n\n /** When the party was last updated */\n val updatedAt: Instant\n\n /** Who last updated the party (party ID) */\n val updatedById: Uuid?\n\n /** When the party was soft-deleted (null if not deleted) */\n val deletedAt: Instant?\n\n /** Who deleted the party (party ID) */\n val deletedById: Uuid?\n\n /**\n * The party's electronic addresses, hydrated on demand. Null means the association was not\n * requested (default); an empty list means it was requested and there are none.\n */\n val electronicAddresses: List?\n\n /**\n * The party's physical addresses, hydrated on demand. Null means the association was not\n * requested (default); an empty list means it was requested and there are none.\n */\n val physicalAddresses: List?\n}\n\n@Serializable\n@JvmInline\nvalue class PartyType(\n val value: String,\n) {\n companion object {\n /** A human individual */\n val NATURAL_PERSON = PartyType(\"natural_person\")\n\n /** Alias for [NATURAL_PERSON] */\n val PERSON = NATURAL_PERSON\n\n /** A company, institution, or other legal entity */\n val ORGANIZATION = PartyType(\"organization\")\n\n /** A software-backed service participant (endpoint, integration, automated actor) */\n val SERVICE = PartyType(\"service\")\n\n /** A unit within an organization (department, division, sub-tenant scope) */\n val ORGANIZATION_UNIT = PartyType(\"organization_unit\")\n\n /** A collection of parties grouped for addressing or authorization */\n val GROUP = PartyType(\"group\")\n\n /** An autonomous actor acting on behalf of another party */\n val AGENT = PartyType(\"agent\")\n }\n\n override fun toString(): String = value\n}\n\n@JsExportCompat\n@Serializable\ndata class PartySpecialization\n @JvmOverloads\n constructor(\n /** Human role label for this specialization (e.g. \"employee\", \"customer\", \"supplier\", \"student\") */\n @SerialName(\"subtype\")\n val subtype: String,\n /** The bound semantic Profile id; null indicates an untyped declaration */\n @SerialName(\"profileId\")\n val profileId: String? = null,\n /** The profile version the values were validated/captured against */\n @SerialName(\"profileVersion\")\n val profileVersion: String? = null,\n /** Values for THIS specialization; populated only when licensed */\n @SerialName(\"attributes\")\n val attributes: JsonObject? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }\n\n@JsExportCompat\n@Serializable\ndata class Tenant\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n val tenantId: String,\n @SerialName(\"tenantType\")\n val tenantType: TenantType,\n val name: String,\n val description: String? = null,\n /**\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\n * platform subdomain label and the dispatcher's peelable path segment.\n */\n val slug: String,\n /**\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\n * time (cycle detection walks up `parent_tenant_id`).\n */\n @SerialName(\"parentTenantId\")\n val parentTenantId: String? = null,\n val status: TenantStatus = TenantStatus.ACTIVE,\n /**\n * Generic \"system tenant\" flag. System tenants are excluded from default\n * listings and from all slug-based / parent-based resolution queries. Customer\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\n * their own system-tenant patterns. EDK does not define what a system tenant\n * is or what privileges it carries.\n */\n val system: Boolean = false,\n @SerialName(\"ownerPartyId\")\n val ownerPartyId: Uuid? = null,\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = tenantId\n }\n\n enum class Type {\n WORKFLOW_EXECUTION_STARTED,\n WORKFLOW_EXECUTION_COMPLETED,\n WORKFLOW_EXECUTION_FAILED,\n WORKFLOW_EXECUTION_TIMED_OUT,\n WORKFLOW_EXECUTION_CANCELED,\n WORKFLOW_EXECUTION_TERMINATED,\n WORKFLOW_EXECUTION_CONTINUED_AS_NEW,\n WORKFLOW_TASK_SCHEDULED,\n WORKFLOW_TASK_STARTED,\n WORKFLOW_TASK_COMPLETED,\n WORKFLOW_TASK_FAILED,\n WORKFLOW_TASK_TIMED_OUT,\n ACTIVITY_TASK_SCHEDULED,\n ACTIVITY_TASK_STARTED,\n ACTIVITY_TASK_COMPLETED,\n ACTIVITY_TASK_FAILED,\n ACTIVITY_TASK_TIMED_OUT,\n ACTIVITY_TASK_CANCEL_REQUESTED,\n ACTIVITY_TASK_CANCELED,\n TIMER_STARTED,\n TIMER_FIRED,\n TIMER_CANCELED,\n WORKFLOW_EXECUTION_SIGNALED,\n WORKFLOW_EXECUTION_UPDATE_ACCEPTED,\n WORKFLOW_EXECUTION_UPDATE_COMPLETED,\n WORKFLOW_EXECUTION_UPDATE_REJECTED,\n CHILD_WORKFLOW_EXECUTION_STARTED,\n CHILD_WORKFLOW_EXECUTION_COMPLETED,\n CHILD_WORKFLOW_EXECUTION_FAILED,\n MARKER_RECORDED,\n OTHER,\n }\n\n enum class State {\n CLOSED,\n OPEN,\n HALF_OPEN\n }\n\n /** Filter by schema object ID */\r\n @SerialName(\"schemaId\")\n\ninternal object CDDLSerializer : KSerializer {\n override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(\"CDDL\", PrimitiveKind.STRING)\n\n override fun serialize(\n encoder: Encoder,\n value: CDDL,\n ) {\n encoder.encodeString(value.format)\n }\n\n override fun deserialize(decoder: Decoder): CDDL = CDDL.util.fromFormat(decoder.decodeString())\n}" - }, - "AddGroupMemberArgs": { - "kind": "data class", - "name": "AddGroupMemberArgs", - "module": "service-api", - "source": "@Serializable\ndata class AddGroupMemberArgs(\n val groupId: Uuid,\n val memberId: Uuid,\n val role: String = \"member\",\n)" - }, - "GroupMembershipResult": { - "kind": "data class", - "name": "GroupMembershipResult", - "module": "persistence-api", - "source": "@Serializable\ndata class GroupMembershipResult(\n @SerialName(\"id\")\n val membershipId: Uuid,\n\n @SerialName(\"tenantId\")\n val tenantId: String,\n\n @SerialName(\"groupId\")\n val groupId: Uuid,\n\n @SerialName(\"memberPartyId\")\n val memberPartyId: Uuid,\n\n @SerialName(\"role\")\n val role: String,\n\n // Audit fields\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null\n) {\n companion object {\n fun from(membership: GroupMembership) = GroupMembershipResult(\n membershipId = membership.membershipId,\n tenantId = membership.tenantId,\n groupId = membership.groupId,\n memberPartyId = membership.memberPartyId,\n role = membership.role,\n createdAt = membership.createdAt,\n createdById = membership.createdById,\n updatedAt = membership.updatedAt,\n updatedById = membership.updatedById,\n deletedAt = membership.deletedAt,\n deletedById = membership.deletedById\n )\n }\n\n fun toGroupMembership() = GroupMembership(\n membershipId = membershipId,\n tenantId = tenantId,\n groupId = groupId,\n memberPartyId = memberPartyId,\n role = role,\n createdAt = createdAt,\n createdById = createdById,\n updatedAt = updatedAt,\n updatedById = updatedById,\n deletedAt = deletedAt,\n deletedById = deletedById\n )\n}\n\n@Serializable\ndata class GroupMembership(\n /** Unique identifier for this membership row */\n @SerialName(\"id\")\n val membershipId: Uuid,\n\n /** Tenant this membership belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n\n /** The group the member belongs to (party ID of the group) */\n @SerialName(\"groupId\")\n val groupId: Uuid,\n\n /** The party that is a member of the group */\n @SerialName(\"memberPartyId\")\n val memberPartyId: Uuid,\n\n /** The member's role within the group */\n @SerialName(\"role\")\n val role: String,\n\n // Audit fields\n /** When the membership was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n /** Who created the membership (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n\n /** When the membership was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n\n /** Who last updated the membership (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n\n /** When the membership was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n\n /** Who deleted the membership (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null\n) : HasId {\n override val id: String get() = membershipId.toString()\n}\n\n@JsExportCompat\n@Serializable\ndata class Tenant\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n val tenantId: String,\n @SerialName(\"tenantType\")\n val tenantType: TenantType,\n val name: String,\n val description: String? = null,\n /**\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\n * platform subdomain label and the dispatcher's peelable path segment.\n */\n val slug: String,\n /**\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\n * time (cycle detection walks up `parent_tenant_id`).\n */\n @SerialName(\"parentTenantId\")\n val parentTenantId: String? = null,\n val status: TenantStatus = TenantStatus.ACTIVE,\n /**\n * Generic \"system tenant\" flag. System tenants are excluded from default\n * listings and from all slug-based / parent-based resolution queries. Customer\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\n * their own system-tenant patterns. EDK does not define what a system tenant\n * is or what privileges it carries.\n */\n val system: Boolean = false,\n @SerialName(\"ownerPartyId\")\n val ownerPartyId: Uuid? = null,\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = tenantId\n }\n\n /** Filter by schema object ID */\r\n @SerialName(\"schemaId\")\n\n@JsExportCompat\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"HasId\", exact = true)\ninterface HasId {\n val id: String\n}" - }, - "CreateElectronicAddressArgs": { - "kind": "data class", - "name": "CreateElectronicAddressArgs", - "module": "service-api", - "source": "@Serializable\ndata class CreateElectronicAddressArgs(\n val partyId: Uuid,\n val addressType: String,\n val value: String,\n val label: String? = null,\n val isPrimary: Boolean = false,\n val isVerified: Boolean = false,\n val verifiedAt: Instant? = null,\n val validFrom: Instant? = null,\n val validUntil: Instant? = null,\n val identifierId: Uuid? = null,\n)" - }, - "ElectronicAddress": { - "kind": "data class", - "name": "ElectronicAddress", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class ElectronicAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Type of address (e.g. EMAIL, PHONE, URL, SOCIAL_MEDIA) */\n @SerialName(\"addressType\")\n val addressType: String,\n /** The address value */\n @SerialName(\"value\")\n val value: String,\n /** Optional label (e.g. \"Work\", \"Personal\", \"Mobile\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Whether this address has been verified */\n @SerialName(\"isVerified\")\n val isVerified: Boolean = false,\n /** When the address was verified */\n @SerialName(\"verifiedAt\")\n val verifiedAt: Instant? = null,\n /** When the address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When the address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n)\n\n@JsExportCompat\n@Serializable\ndata class Tenant\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n val tenantId: String,\n @SerialName(\"tenantType\")\n val tenantType: TenantType,\n val name: String,\n val description: String? = null,\n /**\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\n * platform subdomain label and the dispatcher's peelable path segment.\n */\n val slug: String,\n /**\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\n * time (cycle detection walks up `parent_tenant_id`).\n */\n @SerialName(\"parentTenantId\")\n val parentTenantId: String? = null,\n val status: TenantStatus = TenantStatus.ACTIVE,\n /**\n * Generic \"system tenant\" flag. System tenants are excluded from default\n * listings and from all slug-based / parent-based resolution queries. Customer\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\n * their own system-tenant patterns. EDK does not define what a system tenant\n * is or what privileges it carries.\n */\n val system: Boolean = false,\n @SerialName(\"ownerPartyId\")\n val ownerPartyId: Uuid? = null,\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = tenantId\n }\n\n enum class Type {\n WORKFLOW_EXECUTION_STARTED,\n WORKFLOW_EXECUTION_COMPLETED,\n WORKFLOW_EXECUTION_FAILED,\n WORKFLOW_EXECUTION_TIMED_OUT,\n WORKFLOW_EXECUTION_CANCELED,\n WORKFLOW_EXECUTION_TERMINATED,\n WORKFLOW_EXECUTION_CONTINUED_AS_NEW,\n WORKFLOW_TASK_SCHEDULED,\n WORKFLOW_TASK_STARTED,\n WORKFLOW_TASK_COMPLETED,\n WORKFLOW_TASK_FAILED,\n WORKFLOW_TASK_TIMED_OUT,\n ACTIVITY_TASK_SCHEDULED,\n ACTIVITY_TASK_STARTED,\n ACTIVITY_TASK_COMPLETED,\n ACTIVITY_TASK_FAILED,\n ACTIVITY_TASK_TIMED_OUT,\n ACTIVITY_TASK_CANCEL_REQUESTED,\n ACTIVITY_TASK_CANCELED,\n TIMER_STARTED,\n TIMER_FIRED,\n TIMER_CANCELED,\n WORKFLOW_EXECUTION_SIGNALED,\n WORKFLOW_EXECUTION_UPDATE_ACCEPTED,\n WORKFLOW_EXECUTION_UPDATE_COMPLETED,\n WORKFLOW_EXECUTION_UPDATE_REJECTED,\n CHILD_WORKFLOW_EXECUTION_STARTED,\n CHILD_WORKFLOW_EXECUTION_COMPLETED,\n CHILD_WORKFLOW_EXECUTION_FAILED,\n MARKER_RECORDED,\n OTHER,\n }\n\n@Serializable\n@JvmInline\nvalue class TenantType(\n val value: String,\n) {\n companion object {\n /** Platform/system tenant (for multi-tenant SaaS platforms) */\n val PLATFORM = TenantType(\"platform\")\n\n /** Enterprise tenant (business, company) */\n val ENTERPRISE = TenantType(\"enterprise\")\n\n /** Partner tenant (external partner organization) */\n val PARTNER = TenantType(\"partner\")\n\n /** Sandbox tenant (for testing and development) */\n val SANDBOX = TenantType(\"sandbox\")\n }\n\n override fun toString(): String = value\n}\n\n @Serializable\n @SerialName(\"lowercase\")\n data object Lowercase : ClaimTransformation\n\n@JsExportCompat\n@Serializable\nenum class TenantStatus {\n ACTIVE,\n SUSPENDED,\n PENDING_VERIFICATION,\n}\n\n data class Generic(\n val exception: Throwable? = null,\n override val message: String = \"Consent error\",\n ) : ConsentError\n\n @Serializable\n data class System(\n override val id: String,\n val commandId: String,\n /** Mapping expression (engine-interpreted) producing the command's input from prior outputs. */\n val inputExpression: String,\n val next: String? = null,\n ) : WorkflowTask()\n\n@JsExportCompat\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"HasId\", exact = true)\ninterface HasId {\n val id: String\n}" - }, - "ListElectronicAddressesArgs": { - "kind": "data class", - "name": "ListElectronicAddressesArgs", - "module": "service-api", - "source": "@Serializable\ndata class ListElectronicAddressesArgs(val partyId: Uuid)" - }, - "GetPartyArgs": { - "kind": "data class", - "name": "GetPartyArgs", - "module": "service-api", - "source": "@Serializable\ndata class GetPartyArgs(val id: Uuid, val include: Set = emptySet())" - }, - "PartyEntity": { - "kind": "sealed interface", - "name": "PartyEntity", - "module": "public", - "source": "@JsExportCompat\n@Serializable\n@JsonClassDiscriminator(\"partyType\")\nsealed interface PartyEntity {\n /** Unique identifier for the party */\n val partyId: Uuid\n\n /** Tenant this party belongs to */\n val tenantId: String\n\n /** The type of party (matches the JSON class discriminator) */\n val partyType: PartyType\n\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin\n\n /** User-friendly display name */\n val displayName: String\n\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String?\n\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String?\n\n /** Reference to the owning party */\n val ownerId: Uuid?\n\n /** The single home organization unit; null means the tenant root */\n val organizationUnitId: Uuid?\n\n /** The specializations (roles) this party bears; multi-typing allows several */\n val specializations: List\n\n /** When the party was created */\n val createdAt: Instant\n\n /** Who created the party (party ID) */\n val createdById: Uuid?\n\n /** When the party was last updated */\n val updatedAt: Instant\n\n /** Who last updated the party (party ID) */\n val updatedById: Uuid?\n\n /** When the party was soft-deleted (null if not deleted) */\n val deletedAt: Instant?\n\n /** Who deleted the party (party ID) */\n val deletedById: Uuid?\n\n /**\n * The party's electronic addresses, hydrated on demand. Null means the association was not\n * requested (default); an empty list means it was requested and there are none.\n */\n val electronicAddresses: List?\n\n /**\n * The party's physical addresses, hydrated on demand. Null means the association was not\n * requested (default); an empty list means it was requested and there are none.\n */\n val physicalAddresses: List?\n}\n\n@JsExportCompat\n@Serializable\ndata class Tenant\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n val tenantId: String,\n @SerialName(\"tenantType\")\n val tenantType: TenantType,\n val name: String,\n val description: String? = null,\n /**\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\n * platform subdomain label and the dispatcher's peelable path segment.\n */\n val slug: String,\n /**\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\n * time (cycle detection walks up `parent_tenant_id`).\n */\n @SerialName(\"parentTenantId\")\n val parentTenantId: String? = null,\n val status: TenantStatus = TenantStatus.ACTIVE,\n /**\n * Generic \"system tenant\" flag. System tenants are excluded from default\n * listings and from all slug-based / parent-based resolution queries. Customer\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\n * their own system-tenant patterns. EDK does not define what a system tenant\n * is or what privileges it carries.\n */\n val system: Boolean = false,\n @SerialName(\"ownerPartyId\")\n val ownerPartyId: Uuid? = null,\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = tenantId\n }\n\n-- discriminator-tagged sealed-interface JSON via kotlinx-serialization.\n\n@Serializable\n@JvmInline\nvalue class PartyType(\n val value: String,\n) {\n companion object {\n /** A human individual */\n val NATURAL_PERSON = PartyType(\"natural_person\")\n\n /** Alias for [NATURAL_PERSON] */\n val PERSON = NATURAL_PERSON\n\n /** A company, institution, or other legal entity */\n val ORGANIZATION = PartyType(\"organization\")\n\n /** A software-backed service participant (endpoint, integration, automated actor) */\n val SERVICE = PartyType(\"service\")\n\n /** A unit within an organization (department, division, sub-tenant scope) */\n val ORGANIZATION_UNIT = PartyType(\"organization_unit\")\n\n /** A collection of parties grouped for addressing or authorization */\n val GROUP = PartyType(\"group\")\n\n /** An autonomous actor acting on behalf of another party */\n val AGENT = PartyType(\"agent\")\n }\n\n override fun toString(): String = value\n}\n\n@JsExportCompat\n@Serializable\nenum class Origin {\n /** Resource was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Resource was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n ;\n\n companion object {\n fun fromValue(value: String): Origin =\n entries.firstOrNull { it.name.equals(value, ignoreCase = true) }\n ?: throw IllegalArgumentException(\"Unknown origin: $value\")\n }\n}\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class PartySpecialization\n @JvmOverloads\n constructor(\n /** Human role label for this specialization (e.g. \"employee\", \"customer\", \"supplier\", \"student\") */\n @SerialName(\"subtype\")\n val subtype: String,\n /** The bound semantic Profile id; null indicates an untyped declaration */\n @SerialName(\"profileId\")\n val profileId: String? = null,\n /** The profile version the values were validated/captured against */\n @SerialName(\"profileVersion\")\n val profileVersion: String? = null,\n /** Values for THIS specialization; populated only when licensed */\n @SerialName(\"attributes\")\n val attributes: JsonObject? = null,\n )\n\n /** Filter by schema object ID */\r\n @SerialName(\"schemaId\")\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNull\")\n @Serializable(with = CDDLSerializer::class)\n object Null : CDDL(\"null\", MajorType.SPECIAL, 22, arrayOf(nil)) {\n fun newNull() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n@JsExportCompat\n@Serializable\ndata class ElectronicAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Type of address (e.g. EMAIL, PHONE, URL, SOCIAL_MEDIA) */\n @SerialName(\"addressType\")\n val addressType: String,\n /** The address value */\n @SerialName(\"value\")\n val value: String,\n /** Optional label (e.g. \"Work\", \"Personal\", \"Mobile\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Whether this address has been verified */\n @SerialName(\"isVerified\")\n val isVerified: Boolean = false,\n /** When the address was verified */\n @SerialName(\"verifiedAt\")\n val verifiedAt: Instant? = null,\n /** When the address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When the address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n)\n\n@JsExportCompat\n@Serializable\ndata class PhysicalAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type/purpose of this address */\n @SerialName(\"addressType\")\n val addressType: String,\n /** User-friendly label (e.g. \"Headquarters\", \"Home\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Street address (house number, street name, unit) */\n @SerialName(\"streetAddress\")\n val streetAddress: String? = null,\n /** City/municipality name */\n @SerialName(\"city\")\n val city: String? = null,\n /** State/province/region */\n @SerialName(\"province\")\n val province: String? = null,\n /** Postal/ZIP code */\n @SerialName(\"postalCode\")\n val postalCode: String? = null,\n /** Country code (ISO 3166-1 alpha-2) */\n @SerialName(\"countryCode\")\n val countryCode: String? = null,\n /** Latitude coordinate */\n @SerialName(\"latitude\")\n val latitude: Double? = null,\n /** Longitude coordinate */\n @SerialName(\"longitude\")\n val longitude: Double? = null,\n /** When this address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When this address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n /** When the address was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the address (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the address was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the address (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the address was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the address (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n)\n\n@Serializable\n@JvmInline\nvalue class TenantType(\n val value: String,\n) {\n companion object {\n /** Platform/system tenant (for multi-tenant SaaS platforms) */\n val PLATFORM = TenantType(\"platform\")\n\n /** Enterprise tenant (business, company) */\n val ENTERPRISE = TenantType(\"enterprise\")\n\n /** Partner tenant (external partner organization) */\n val PARTNER = TenantType(\"partner\")\n\n /** Sandbox tenant (for testing and development) */\n val SANDBOX = TenantType(\"sandbox\")\n }\n\n override fun toString(): String = value\n}\n\n @Serializable\n @SerialName(\"lowercase\")\n data object Lowercase : ClaimTransformation\n\n@JsExportCompat\n@Serializable\nenum class TenantStatus {\n ACTIVE,\n SUSPENDED,\n PENDING_VERIFICATION,\n}" - }, - "CreateRelationshipArgs": { - "kind": "data class", - "name": "CreateRelationshipArgs", - "module": "service-api", - "source": "@Serializable\ndata class CreateRelationshipArgs(\n val leftId: Uuid,\n val rightId: Uuid,\n val relationshipType: String,\n val status: String? = null,\n val validFrom: Instant? = null,\n val validUntil: Instant? = null,\n)" - }, - "PartyRelationshipResult": { - "kind": "data class", - "name": "PartyRelationshipResult", - "module": "persistence-api", - "source": "@Serializable\ndata class PartyRelationshipResult(\n // Core fields\n /** Unique identifier for this relationship */\n @SerialName(\"id\")\n val id: Uuid,\n\n /** Tenant this relationship belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n\n /** The \"left\" party in the relationship */\n @SerialName(\"leftId\")\n val leftPartyId: Uuid,\n\n /** The \"right\" party in the relationship */\n @SerialName(\"rightId\")\n val rightPartyId: Uuid,\n\n /** Type of relationship */\n @SerialName(\"relationshipType\")\n val relationshipType: String,\n\n /** Status of the relationship */\n @SerialName(\"status\")\n val status: String,\n\n /** When the relationship becomes valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant? = null,\n\n /** When the relationship expires */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n\n /** When the relationship was verified */\n @SerialName(\"verifiedAt\")\n val verifiedAt: Instant? = null,\n\n /** Who verified the relationship (party ID) */\n @SerialName(\"verifiedById\")\n val verifiedById: Uuid? = null,\n\n // Audit fields\n /** When the record was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n /** Who created the record (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n\n /** When the record was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n\n /** Who last updated the record (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n\n // Populated associations (based on FetchOptions)\n /**\n * The left party details.\n * Populated when [PartyRelationshipFetchOptions.includeLeftParty] is true.\n */\n @SerialName(\"leftParty\")\n val leftParty: Party? = null,\n\n /**\n * The right party details.\n * Populated when [PartyRelationshipFetchOptions.includeRightParty] is true.\n */\n @SerialName(\"rightParty\")\n val rightParty: Party? = null,\n\n /**\n * The relationship type definition.\n * Populated when [PartyRelationshipFetchOptions.includeRelationshipType] is true.\n */\n @SerialName(\"relationshipTypeDefinition\")\n val relationshipTypeDefinition: RelationshipType? = null,\n\n /**\n * Employment extension data.\n * Populated when [PartyRelationshipFetchOptions.includeEmploymentExtension] is true.\n */\n @SerialName(\"employmentExtension\")\n val employmentExtension: RelationshipEmployment? = null,\n\n /**\n * Membership extension data.\n * Populated when [PartyRelationshipFetchOptions.includeMembershipExtension] is true.\n */\n @SerialName(\"membershipExtension\")\n val membershipExtension: RelationshipMembership? = null,\n\n /**\n * Guardianship extension data.\n * Populated when [PartyRelationshipFetchOptions.includeGuardianshipExtension] is true.\n */\n @SerialName(\"guardianshipExtension\")\n val guardianshipExtension: RelationshipGuardianship? = null,\n\n /**\n * Delegation extension data.\n * Populated when [PartyRelationshipFetchOptions.includeDelegationExtension] is true.\n */\n @SerialName(\"delegationExtension\")\n val delegationExtension: RelationshipDelegation? = null\n) {\n /** Check if the relationship has been verified */\n val isVerified: Boolean get() = verifiedAt != null\n\n companion object {\n /**\n * Create a PartyRelationshipResult from a PartyRelationship entity.\n */\n fun from(\n relationship: PartyRelationship,\n leftParty: Party? = null,\n rightParty: Party? = null,\n relationshipTypeDefinition: RelationshipType? = null,\n employmentExtension: RelationshipEmployment? = null,\n membershipExtension: RelationshipMembership? = null,\n guardianshipExtension: RelationshipGuardianship? = null,\n delegationExtension: RelationshipDelegation? = null\n ) = PartyRelationshipResult(\n id = relationship.id,\n tenantId = relationship.tenantId,\n leftPartyId = relationship.leftPartyId,\n rightPartyId = relationship.rightPartyId,\n relationshipType = relationship.relationshipType,\n status = relationship.status,\n validFrom = relationship.validFrom,\n validUntil = relationship.validUntil,\n verifiedAt = relationship.verifiedAt,\n verifiedById = relationship.verifiedById,\n createdAt = relationship.createdAt,\n createdById = relationship.createdById,\n updatedAt = relationship.updatedAt,\n updatedById = relationship.updatedById,\n leftParty = leftParty,\n rightParty = rightParty,\n relationshipTypeDefinition = relationshipTypeDefinition,\n employmentExtension = employmentExtension,\n membershipExtension = membershipExtension,\n guardianshipExtension = guardianshipExtension,\n delegationExtension = delegationExtension\n )\n }\n\n /** Convert back to the core PartyRelationship entity (without associations) */\n fun toPartyRelationship() = PartyRelationship(\n id = id,\n tenantId = tenantId,\n leftPartyId = leftPartyId,\n rightPartyId = rightPartyId,\n relationshipType = relationshipType,\n status = status,\n validFrom = validFrom,\n validUntil = validUntil,\n verifiedAt = verifiedAt,\n verifiedById = verifiedById,\n createdAt = createdAt,\n createdById = createdById,\n updatedAt = updatedAt,\n updatedById = updatedById\n )\n}\n\n@JsExportCompat\n@Serializable\ndata class Tenant\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n val tenantId: String,\n @SerialName(\"tenantType\")\n val tenantType: TenantType,\n val name: String,\n val description: String? = null,\n /**\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\n * platform subdomain label and the dispatcher's peelable path segment.\n */\n val slug: String,\n /**\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\n * time (cycle detection walks up `parent_tenant_id`).\n */\n @SerialName(\"parentTenantId\")\n val parentTenantId: String? = null,\n val status: TenantStatus = TenantStatus.ACTIVE,\n /**\n * Generic \"system tenant\" flag. System tenants are excluded from default\n * listings and from all slug-based / parent-based resolution queries. Customer\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\n * their own system-tenant patterns. EDK does not define what a system tenant\n * is or what privileges it carries.\n */\n val system: Boolean = false,\n @SerialName(\"ownerPartyId\")\n val ownerPartyId: Uuid? = null,\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = tenantId\n }\n\n enum class Type {\n WORKFLOW_EXECUTION_STARTED,\n WORKFLOW_EXECUTION_COMPLETED,\n WORKFLOW_EXECUTION_FAILED,\n WORKFLOW_EXECUTION_TIMED_OUT,\n WORKFLOW_EXECUTION_CANCELED,\n WORKFLOW_EXECUTION_TERMINATED,\n WORKFLOW_EXECUTION_CONTINUED_AS_NEW,\n WORKFLOW_TASK_SCHEDULED,\n WORKFLOW_TASK_STARTED,\n WORKFLOW_TASK_COMPLETED,\n WORKFLOW_TASK_FAILED,\n WORKFLOW_TASK_TIMED_OUT,\n ACTIVITY_TASK_SCHEDULED,\n ACTIVITY_TASK_STARTED,\n ACTIVITY_TASK_COMPLETED,\n ACTIVITY_TASK_FAILED,\n ACTIVITY_TASK_TIMED_OUT,\n ACTIVITY_TASK_CANCEL_REQUESTED,\n ACTIVITY_TASK_CANCELED,\n TIMER_STARTED,\n TIMER_FIRED,\n TIMER_CANCELED,\n WORKFLOW_EXECUTION_SIGNALED,\n WORKFLOW_EXECUTION_UPDATE_ACCEPTED,\n WORKFLOW_EXECUTION_UPDATE_COMPLETED,\n WORKFLOW_EXECUTION_UPDATE_REJECTED,\n CHILD_WORKFLOW_EXECUTION_STARTED,\n CHILD_WORKFLOW_EXECUTION_COMPLETED,\n CHILD_WORKFLOW_EXECUTION_FAILED,\n MARKER_RECORDED,\n OTHER,\n }\n\n data class Status(\n val response: HttpResponse\n ) : RetryTrigger() {\n override fun toString(): String = \"HTTP ${response.status.value}\"\n }\n\n /** Filter by schema object ID */\r\n @SerialName(\"schemaId\")\n\n@Serializable\ndata class PartyRelationshipFetchOptions(\n /** Include the left party details */\n @SerialName(\"includeLeftParty\")\n val includeLeftParty: Boolean = false,\n\n /** Include the right party details */\n @SerialName(\"includeRightParty\")\n val includeRightParty: Boolean = false,\n\n /** Include the relationship type definition */\n @SerialName(\"includeRelationshipType\")\n val includeRelationshipType: Boolean = false,\n\n /** Include employment extension data (if applicable) */\n @SerialName(\"includeEmploymentExtension\")\n val includeEmploymentExtension: Boolean = false,\n\n /** Include membership extension data (if applicable) */\n @SerialName(\"includeMembershipExtension\")\n val includeMembershipExtension: Boolean = false,\n\n /** Include guardianship extension data (if applicable) */\n @SerialName(\"includeGuardianshipExtension\")\n val includeGuardianshipExtension: Boolean = false,\n\n /** Include delegation extension data (if applicable) */\n @SerialName(\"includeDelegationExtension\")\n val includeDelegationExtension: Boolean = false\n) {\n companion object {\n /** Load only core relationship data (default) */\n val MINIMAL = PartyRelationshipFetchOptions()\n\n /** Load relationship with both parties */\n val WITH_PARTIES = PartyRelationshipFetchOptions(\n includeLeftParty = true,\n includeRightParty = true\n )\n\n /** Load relationship with all extensions */\n val WITH_EXTENSIONS = PartyRelationshipFetchOptions(\n includeEmploymentExtension = true,\n includeMembershipExtension = true,\n includeGuardianshipExtension = true,\n includeDelegationExtension = true\n )\n\n /** Load everything (all associations and extensions) */\n val FULL = PartyRelationshipFetchOptions(\n includeLeftParty = true,\n includeRightParty = true,\n includeRelationshipType = true,\n includeEmploymentExtension = true,\n includeMembershipExtension = true,\n includeGuardianshipExtension = true,\n includeDelegationExtension = true\n )\n }\n\n /** Builder method to include left party */\n fun withLeftParty() = copy(includeLeftParty = true)\n\n /** Builder method to include right party */\n fun withRightParty() = copy(includeRightParty = true)\n\n /** Builder method to include both parties */\n fun withParties() = copy(includeLeftParty = true, includeRightParty = true)\n\n /** Builder method to include relationship type */\n fun withRelationshipType() = copy(includeRelationshipType = true)\n\n /** Builder method to include all extensions */\n fun withAllExtensions() = copy(\n includeEmploymentExtension = true,\n includeMembershipExtension = true,\n includeGuardianshipExtension = true,\n includeDelegationExtension = true\n )\n}\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }\n\n@Serializable\ndata class RelationshipType(\n /** The relationship type identifier (e.g., \"EMPLOYMENT\", \"MEMBERSHIP\") */\n @SerialName(\"type\")\n val type: String,\n\n /** I18n key for describing left→right direction (e.g., \"employee_of\") */\n @SerialName(\"leftToRightI18nKey\")\n val leftToRightI18nKey: String,\n\n /** I18n key for describing right→left direction (e.g., \"employs\") */\n @SerialName(\"rightToLeftI18nKey\")\n val rightToLeftI18nKey: String,\n\n /** Optional description i18n key */\n @SerialName(\"descriptionI18nKey\")\n val descriptionI18nKey: String? = null\n)\n\n@Serializable\ndata class RelationshipEmployment(\n /** The relationship this extends (references party_relationship.id) */\n @SerialName(\"relationshipId\")\n val relationshipId: Uuid,\n\n /** Job title of the employee */\n @SerialName(\"jobTitle\")\n val jobTitle: String? = null,\n\n /** Department within the organization */\n @SerialName(\"department\")\n val department: String? = null,\n\n /** Employee number/ID */\n @SerialName(\"employeeNumber\")\n val employeeNumber: String? = null,\n\n /** Cost center for accounting purposes */\n @SerialName(\"costCenter\")\n val costCenter: String? = null,\n\n /** When the record was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n /** When the record was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant\n)\n\n@Serializable\ndata class RelationshipMembership(\n /** The relationship this extends (references party_relationship.id) */\n @SerialName(\"relationshipId\")\n val relationshipId: Uuid,\n\n /** Role within the membership (e.g., \"ADMIN\", \"MEMBER\", \"OBSERVER\") */\n @SerialName(\"memberRole\")\n val memberRole: String? = null,\n\n /** When the membership started */\n @SerialName(\"memberSince\")\n val memberSince: Instant? = null,\n\n /** Membership tier (e.g., \"GOLD\", \"SILVER\", \"BRONZE\") */\n @SerialName(\"tier\")\n val tier: String? = null,\n\n /** When the record was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n /** When the record was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant\n)\n\n@Serializable\ndata class RelationshipGuardianship(\n /** The relationship this extends (references party_relationship.id) */\n @SerialName(\"relationshipId\")\n val relationshipId: Uuid,\n\n /** Type of guardianship (e.g., \"LEGAL\", \"TEMPORARY\", \"MEDICAL\") */\n @SerialName(\"guardianshipType\")\n val guardianshipType: String? = null,\n\n /** Reference to the court order establishing guardianship */\n @SerialName(\"courtOrderReference\")\n val courtOrderReference: String? = null,\n\n /** Jurisdiction where guardianship was established */\n @SerialName(\"jurisdiction\")\n val jurisdiction: String? = null,\n\n /** When guardianship was granted */\n @SerialName(\"grantedAt\")\n val grantedAt: Instant? = null,\n\n /** When guardianship expires */\n @SerialName(\"expiresAt\")\n val expiresAt: Instant? = null,\n\n /** When the record was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n /** When the record was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant\n)\n\n@Serializable\ndata class RelationshipDelegation(\n /** The relationship this extends (references party_relationship.id) */\n @SerialName(\"relationshipId\")\n val relationshipId: Uuid,\n\n /** Type of delegation (e.g., \"POWER_OF_ATTORNEY\", \"PROXY\", \"MANDATE\") */\n @SerialName(\"delegationType\")\n val delegationType: String? = null,\n\n /** Scope of the delegation (what actions are permitted) */\n @SerialName(\"scope\")\n val scope: String? = null,\n\n /** Reference to the legal document establishing delegation */\n @SerialName(\"legalDocumentRef\")\n val legalDocumentRef: String? = null,\n\n /** Whether witness signature is required for actions */\n @SerialName(\"requiresWitness\")\n val requiresWitness: Boolean? = null,\n\n /** When the record was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n /** When the record was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant\n)\n\n@Serializable\ndata class PartyRelationship(\n /** Unique identifier for this relationship */\n @SerialName(\"id\")\n val id: Uuid,\n\n /** Tenant this relationship belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n\n /** The \"left\" party in the relationship (e.g., employee) */\n @SerialName(\"leftPartyId\")\n val leftPartyId: Uuid,\n\n /** The \"right\" party in the relationship (e.g., employer) */\n @SerialName(\"rightPartyId\")\n val rightPartyId: Uuid,\n\n /** Type of relationship (references relationship_type.type) */\n @SerialName(\"relationshipType\")\n val relationshipType: String,\n\n /** Status of the relationship */\n @SerialName(\"status\")\n val status: String = RelationshipStatus.ACTIVE,\n\n /** When the relationship becomes valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant? = null,\n\n /** When the relationship expires */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n\n /** When the relationship was verified */\n @SerialName(\"verifiedAt\")\n val verifiedAt: Instant? = null,\n\n /** Who verified the relationship (party ID) */\n @SerialName(\"verifiedById\")\n val verifiedById: Uuid? = null,\n\n // Audit fields\n /** When the record was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n /** Who created the record (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n\n /** When the record was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n\n /** Who last updated the record (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null\n) {\n /** Check if the relationship is currently active */\n fun isActive(at: Instant): Boolean {\n if (status != RelationshipStatus.ACTIVE) return false\n val afterStart = validFrom?.let { at >= it } ?: true\n val beforeEnd = validUntil?.let { at <= it } ?: true\n return afterStart && beforeEnd\n }\n\n /** Check if the relationship has been verified */\n val isVerified: Boolean get() = verifiedAt != null\n}\n\n@Serializable\n@JvmInline\nvalue class TenantType(\n val value: String,\n) {\n companion object {\n /** Platform/system tenant (for multi-tenant SaaS platforms) */\n val PLATFORM = TenantType(\"platform\")\n\n /** Enterprise tenant (business, company) */\n val ENTERPRISE = TenantType(\"enterprise\")\n\n /** Partner tenant (external partner organization) */\n val PARTNER = TenantType(\"partner\")\n\n /** Sandbox tenant (for testing and development) */\n val SANDBOX = TenantType(\"sandbox\")\n }\n\n override fun toString(): String = value\n}" - }, - "ListRelationshipsByPartyArgs": { - "kind": "data class", - "name": "ListRelationshipsByPartyArgs", - "module": "service-api", - "source": "@Serializable\ndata class ListRelationshipsByPartyArgs(val partyId: Uuid)" - }, - "CreateTenantIdpArgs": { - "kind": "data class", - "name": "CreateTenantIdpArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class CreateTenantIdpArgs(\n val displayName: String,\n val issuer: String,\n val clientId: String,\n val idpId: String? = null,\n val clientSecret: String? = null,\n val clientSecretRef: String? = null,\n val scopes: List = listOf(\"openid\", \"profile\", \"email\"),\n val claimsMapping: TenantIdpClaimsMapping = TenantIdpClaimsMapping(),\n val enabled: Boolean = false,\n)\n\n@Serializable\ndata class TenantIdpClaimsMapping(\n val subject: String = \"sub\",\n val email: String = \"email\",\n val displayName: String = \"name\",\n)" - }, - "TenantIdpRecord": { - "kind": "data class", - "name": "TenantIdpRecord", - "module": "public", - "source": "@Serializable\ndata class TenantIdpRecord(\n val idpId: String,\n val displayName: String,\n val issuer: String,\n val clientId: String,\n val clientSecretRef: String? = null,\n val scopes: List = listOf(\"openid\", \"profile\", \"email\"),\n val claimsMapping: TenantIdpClaimsMapping = TenantIdpClaimsMapping(),\n val enabled: Boolean = false,\n val createdAt: Instant? = null,\n val updatedAt: Instant? = null,\n)\n\n@Serializable\ndata class TenantIdpClaimsMapping(\n val subject: String = \"sub\",\n val email: String = \"email\",\n val displayName: String = \"name\",\n)" - }, - "RegisterTenantArgs": { - "kind": "data class", - "name": "RegisterTenantArgs", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class RegisterTenantArgs(\n val tenantType: TenantType,\n val name: String,\n val description: String? = null,\n /** URL-safe lowercase slug. Doubles as platform-subdomain label and path segment. */\n val slug: String,\n /** Parent tenant id; null = root tenant. */\n val parentTenantId: String? = null,\n /** Optional Party owner. When null, no Party is linked at registration. */\n val ownerPartyId: Uuid? = null,\n /**\n * When true (default), auto-create the platform subdomain row `.` in\n * `tenant_domain`.\n */\n val initialPlatformSubdomain: Boolean = true,\n /**\n * When true (default), provision a default AS instance (slug `default`) for this\n * tenant. When false, the tenant has no hosted AS — only viable with a\n * [OwnerInput.Federated] owner whose external IDP becomes the trusted issuer.\n */\n val hostedAs: Boolean = true,\n val owner: OwnerInput,\n)\n\n@Serializable\n@JvmInline\nvalue class TenantType(\n val value: String,\n) {\n companion object {\n /** Platform/system tenant (for multi-tenant SaaS platforms) */\n val PLATFORM = TenantType(\"platform\")\n\n /** Enterprise tenant (business, company) */\n val ENTERPRISE = TenantType(\"enterprise\")\n\n /** Partner tenant (external partner organization) */\n val PARTNER = TenantType(\"partner\")\n\n /** Sandbox tenant (for testing and development) */\n val SANDBOX = TenantType(\"sandbox\")\n }\n\n override fun toString(): String = value\n}\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }\n\n@JsExportCompat\n@Serializable\nsealed class OwnerInput {\n abstract val email: String\n abstract val displayName: String\n\n @JsExportCompat\n @Serializable\n data class Local(\n override val email: String,\n override val displayName: String,\n ) : OwnerInput()\n\n @JsExportCompat\n @Serializable\n data class Federated(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n /**\n * Owner's stable identifier inside the external IDP — typically the `sub`\n * claim, but can be any claim agreed in [FederationProviderInput.claimMapping].\n */\n val externalSubject: String,\n ) : OwnerInput()\n\n @JsExportCompat\n @Serializable\n data class Hybrid(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n val externalSubject: String,\n ) : OwnerInput()\n}\n\n @JsExportCompat\n @Serializable\n data class Federated(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n /**\n * Owner's stable identifier inside the external IDP — typically the `sub`\n * claim, but can be any claim agreed in [FederationProviderInput.claimMapping].\n */\n val externalSubject: String,\n ) : OwnerInput()\n\n@JsExportCompat\n@Serializable\ndata class Tenant\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n val tenantId: String,\n @SerialName(\"tenantType\")\n val tenantType: TenantType,\n val name: String,\n val description: String? = null,\n /**\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\n * platform subdomain label and the dispatcher's peelable path segment.\n */\n val slug: String,\n /**\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\n * time (cycle detection walks up `parent_tenant_id`).\n */\n @SerialName(\"parentTenantId\")\n val parentTenantId: String? = null,\n val status: TenantStatus = TenantStatus.ACTIVE,\n /**\n * Generic \"system tenant\" flag. System tenants are excluded from default\n * listings and from all slug-based / parent-based resolution queries. Customer\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\n * their own system-tenant patterns. EDK does not define what a system tenant\n * is or what privileges it carries.\n */\n val system: Boolean = false,\n @SerialName(\"ownerPartyId\")\n val ownerPartyId: Uuid? = null,\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = tenantId\n }\n\n@Serializable\n@JvmInline\nvalue class PartyType(\n val value: String,\n) {\n companion object {\n /** A human individual */\n val NATURAL_PERSON = PartyType(\"natural_person\")\n\n /** Alias for [NATURAL_PERSON] */\n val PERSON = NATURAL_PERSON\n\n /** A company, institution, or other legal entity */\n val ORGANIZATION = PartyType(\"organization\")\n\n /** A software-backed service participant (endpoint, integration, automated actor) */\n val SERVICE = PartyType(\"service\")\n\n /** A unit within an organization (department, division, sub-tenant scope) */\n val ORGANIZATION_UNIT = PartyType(\"organization_unit\")\n\n /** A collection of parties grouped for addressing or authorization */\n val GROUP = PartyType(\"group\")\n\n /** An autonomous actor acting on behalf of another party */\n val AGENT = PartyType(\"agent\")\n }\n\n override fun toString(): String = value\n}\n\n@JsExportCompat\n@Serializable\nenum class Origin {\n /** Resource was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Resource was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n ;\n\n companion object {\n fun fromValue(value: String): Origin =\n entries.firstOrNull { it.name.equals(value, ignoreCase = true) }\n ?: throw IllegalArgumentException(\"Unknown origin: $value\")\n }\n}\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@Serializable\ndata class NaturalPerson(\n /** Party ID - serves as the primary key, references party.id */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n\n /** Tenant this natural person belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n\n /** First name (given name) */\n @SerialName(\"firstName\")\n val firstName: String? = null,\n\n /** Middle name(s) */\n @SerialName(\"middleName\")\n val middleName: String? = null,\n\n /** Last name (family name) */\n @SerialName(\"lastName\")\n val lastName: String? = null,\n\n /** Display name (formatted name for UI) */\n @SerialName(\"displayName\")\n val displayName: String? = null,\n\n /** Date of birth */\n @SerialName(\"birthDate\")\n val birthDate: LocalDate? = null\n) {\n /**\n * Returns the full name by combining first, middle, and last names.\n */\n val fullName: String\n get() = listOfNotNull(firstName, middleName, lastName)\n .filter { it.isNotBlank() }\n .joinToString(\" \")\n\n /**\n * Returns the display name, or falls back to the full name if not set.\n */\n val effectiveDisplayName: String\n get() = displayName?.takeIf { it.isNotBlank() } ?: fullName\n}\n\n@JsExportCompat\n@Serializable\n@SerialName(\"organization\")\ndata class Organization\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n override val partyId: Uuid,\n @SerialName(\"tenantId\")\n override val tenantId: String,\n override val origin: PartyOrigin,\n @SerialName(\"displayName\")\n override val displayName: String,\n override val uri: String? = null,\n override val jurisdiction: String? = null,\n @SerialName(\"ownerId\")\n override val ownerId: Uuid? = null,\n @SerialName(\"organizationUnitId\")\n override val organizationUnitId: Uuid? = null,\n @SerialName(\"specializations\")\n override val specializations: List = emptyList(),\n @SerialName(\"createdAt\")\n override val createdAt: Instant,\n @SerialName(\"createdById\")\n override val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n override val updatedAt: Instant,\n @SerialName(\"updatedById\")\n override val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n override val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n override val deletedById: Uuid? = null,\n @SerialName(\"electronicAddresses\")\n override val electronicAddresses: List? = null,\n @SerialName(\"physicalAddresses\")\n override val physicalAddresses: List? = null,\n /** Registered legal name */\n @SerialName(\"legalName\")\n val legalName: String,\n /** Organization type (e.g. company, foundation, government) */\n @SerialName(\"organizationType\")\n val organizationType: String? = null,\n /** Industry classification */\n @SerialName(\"industry\")\n val industry: String? = null,\n /** Primary contact email */\n @SerialName(\"contactEmail\")\n val contactEmail: String? = null,\n /** Public website URL */\n @SerialName(\"websiteUrl\")\n val websiteUrl: String? = null,\n /** Privacy policy URI */\n @SerialName(\"privacyPolicyUri\")\n val privacyPolicyUri: String? = null,\n /** Terms of service URI */\n @SerialName(\"tosUri\")\n val tosUri: String? = null,\n ) : PartyEntity {\n override val partyType: PartyType get() = PartyType.ORGANIZATION\n }\n\n /** Filter by schema object ID */\r\n @SerialName(\"schemaId\")\n\n@JsExportCompat\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"HasId\", exact = true)\ninterface HasId {\n val id: String\n}\n\n @JsExportCompat\n @Serializable\n data class Local(\n override val email: String,\n override val displayName: String,\n ) : OwnerInput()" - }, - "RegisterTenantResult": { - "kind": "data class", - "name": "RegisterTenantResult", - "module": "public", - "source": "@JsExportCompat\r\n@Serializable\r\ndata class RegisterTenantResult(\r\n val tenant: Tenant,\r\n /** Primary platform subdomain URL, e.g. `https://acme.saas.com`. */\r\n val primaryDomainUrl: String,\r\n /** Default AS issuer URL, null when `hostedAs = false`. */\r\n val issuerUrl: String? = null,\r\n /**\r\n * Default OID4VCI credential-issuer identifier URL, null when `hostedAs = false`.\r\n * For co-located AS + issuer deployments this is the same origin as [issuerUrl]\r\n * with an `/oid4vci` path suffix.\r\n */\r\n val oid4vciIssuerUrl: String? = null,\r\n /** Local user id assigned to the owner. */\r\n val ownerUserId: String,\r\n /** Durable tenant registration log id for onboarding/status polling. */\r\n val correlationId: String = \"\",\r\n /** Single-use invitation token, only for Local/Hybrid owners. */\r\n val invitationToken: String? = null,\r\n)\n\n@JsExportCompat\n@Serializable\ndata class Tenant\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n val tenantId: String,\n @SerialName(\"tenantType\")\n val tenantType: TenantType,\n val name: String,\n val description: String? = null,\n /**\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\n * platform subdomain label and the dispatcher's peelable path segment.\n */\n val slug: String,\n /**\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\n * time (cycle detection walks up `parent_tenant_id`).\n */\n @SerialName(\"parentTenantId\")\n val parentTenantId: String? = null,\n val status: TenantStatus = TenantStatus.ACTIVE,\n /**\n * Generic \"system tenant\" flag. System tenants are excluded from default\n * listings and from all slug-based / parent-based resolution queries. Customer\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\n * their own system-tenant patterns. EDK does not define what a system tenant\n * is or what privileges it carries.\n */\n val system: Boolean = false,\n @SerialName(\"ownerPartyId\")\n val ownerPartyId: Uuid? = null,\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = tenantId\n }\n\n @JsExportCompat\n @Serializable\n data class Local(\n override val email: String,\n override val displayName: String,\n ) : OwnerInput()\n\n @JsExportCompat\n @Serializable\n data class Hybrid(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n val externalSubject: String,\n ) : OwnerInput()\n\n@Serializable\n@JvmInline\nvalue class TenantType(\n val value: String,\n) {\n companion object {\n /** Platform/system tenant (for multi-tenant SaaS platforms) */\n val PLATFORM = TenantType(\"platform\")\n\n /** Enterprise tenant (business, company) */\n val ENTERPRISE = TenantType(\"enterprise\")\n\n /** Partner tenant (external partner organization) */\n val PARTNER = TenantType(\"partner\")\n\n /** Sandbox tenant (for testing and development) */\n val SANDBOX = TenantType(\"sandbox\")\n }\n\n override fun toString(): String = value\n}\n\n @Serializable\n @SerialName(\"lowercase\")\n data object Lowercase : ClaimTransformation\n\n@JsExportCompat\n@Serializable\nenum class TenantStatus {\n ACTIVE,\n SUSPENDED,\n PENDING_VERIFICATION,\n}\n\n data class Generic(\n val exception: Throwable? = null,\n override val message: String = \"Consent error\",\n ) : ConsentError\n\n @Serializable\n data class System(\n override val id: String,\n val commandId: String,\n /** Mapping expression (engine-interpreted) producing the command's input from prior outputs. */\n val inputExpression: String,\n val next: String? = null,\n ) : WorkflowTask()\n\n@JsExportCompat\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"HasId\", exact = true)\ninterface HasId {\n val id: String\n}\n\n@JsExportCompat\n@Serializable\nsealed class OwnerInput {\n abstract val email: String\n abstract val displayName: String\n\n @JsExportCompat\n @Serializable\n data class Local(\n override val email: String,\n override val displayName: String,\n ) : OwnerInput()\n\n @JsExportCompat\n @Serializable\n data class Federated(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n /**\n * Owner's stable identifier inside the external IDP — typically the `sub`\n * claim, but can be any claim agreed in [FederationProviderInput.claimMapping].\n */\n val externalSubject: String,\n ) : OwnerInput()\n\n @JsExportCompat\n @Serializable\n data class Hybrid(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n val externalSubject: String,\n ) : OwnerInput()\n}\n\n@JsExportCompat\n@Serializable\ndata class FederationProviderInput(\n /** Stable slug for this provider within the AS, e.g. `azure`, `okta`. */\n val providerId: String,\n /** Human-friendly label shown in operator UI / login chooser. */\n val displayName: String,\n val issuer: String,\n val clientId: String,\n /**\n * Inline secret. The registration command writes it to KMS and replaces with a\n * reference; never persists the literal value as a config row.\n */\n val clientSecret: String,\n /**\n * Mapping from local subject claim → external claim name.\n *\n * Example: `{\"subject\": \"oid\"}` makes the AS use the external `oid` claim as the\n * federated user's local `sub`. Default mapping is `{\"subject\": \"sub\"}`.\n */\n val claimMapping: Map = mapOf(\"subject\" to \"sub\"),\n /** Scopes requested from the external IDP. */\n val scopes: List = listOf(\"openid\", \"profile\", \"email\"),\n)" - }, - "RequestTenantSignupArgs": { - "kind": "data class", - "name": "RequestTenantSignupArgs", - "module": "service", - "source": "@JsExportCompat\n@Serializable\ndata class RequestTenantSignupArgs(\n val email: String,\n val slug: String,\n /** null → SaaS root signup; non-null → subtenant signup under this parent. */\n val parentTenantId: String? = null,\n val displayName: String,\n /** Hashed source IP for SOC + rate-limit. Adapter computes the hash; command never sees raw IP. */\n val sourceIpHash: String? = null,\n /** Bot-defence challenge proof. Verifier may be no-op in dev / pure-EDK. */\n val challengeProof: String? = null,\n)" - }, - "RequestTenantSignupResult": { - "kind": "data class", - "name": "RequestTenantSignupResult", - "module": "service", - "source": "@JsExportCompat\n@Serializable\ndata class RequestTenantSignupResult(\n val signupRequestId: String,\n /**\n * Plaintext token. Sent out-of-band via the email channel by the calling\n * adapter; never persisted on the server. Returned ONLY in this in-process\n * call result — production REST adapters must NOT include it in the HTTP\n * response (the response is just the request id and expiry).\n */\n val plainVerificationToken: String,\n val expiresAt: Instant,\n val requiresApproval: Boolean,\n)" - }, - "ConfirmTenantSignupArgs": { - "kind": "data class", - "name": "ConfirmTenantSignupArgs", - "module": "service", - "source": "@JsExportCompat\n@Serializable\ndata class ConfirmTenantSignupArgs(\n /** Plaintext token the requester clicked through email. The command hashes and looks up. */\n val plainVerificationToken: String,\n)" - }, - "ConfirmTenantSignupResult": { - "kind": "data class", - "name": "ConfirmTenantSignupResult", - "module": "service", - "source": "@JsExportCompat\n@Serializable\ndata class ConfirmTenantSignupResult(\n val signupRequestId: String,\n val status: TenantSignupStatus,\n val registration: RegisterTenantResult? = null,\n)\n\n@JsExportCompat\nenum class TenantSignupStatus {\n PENDING_EMAIL,\n PENDING_APPROVAL,\n CONFIRMED,\n REGISTERED,\n REJECTED,\n EXPIRED,\n FAILED,\n}\n\n@JsExportCompat\r\n@Serializable\r\ndata class RegisterTenantResult(\r\n val tenant: Tenant,\r\n /** Primary platform subdomain URL, e.g. `https://acme.saas.com`. */\r\n val primaryDomainUrl: String,\r\n /** Default AS issuer URL, null when `hostedAs = false`. */\r\n val issuerUrl: String? = null,\r\n /**\r\n * Default OID4VCI credential-issuer identifier URL, null when `hostedAs = false`.\r\n * For co-located AS + issuer deployments this is the same origin as [issuerUrl]\r\n * with an `/oid4vci` path suffix.\r\n */\r\n val oid4vciIssuerUrl: String? = null,\r\n /** Local user id assigned to the owner. */\r\n val ownerUserId: String,\r\n /** Durable tenant registration log id for onboarding/status polling. */\r\n val correlationId: String = \"\",\r\n /** Single-use invitation token, only for Local/Hybrid owners. */\r\n val invitationToken: String? = null,\r\n)\n\n@JsExportCompat\n@Serializable\ndata class Tenant\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n val tenantId: String,\n @SerialName(\"tenantType\")\n val tenantType: TenantType,\n val name: String,\n val description: String? = null,\n /**\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\n * platform subdomain label and the dispatcher's peelable path segment.\n */\n val slug: String,\n /**\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\n * time (cycle detection walks up `parent_tenant_id`).\n */\n @SerialName(\"parentTenantId\")\n val parentTenantId: String? = null,\n val status: TenantStatus = TenantStatus.ACTIVE,\n /**\n * Generic \"system tenant\" flag. System tenants are excluded from default\n * listings and from all slug-based / parent-based resolution queries. Customer\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\n * their own system-tenant patterns. EDK does not define what a system tenant\n * is or what privileges it carries.\n */\n val system: Boolean = false,\n @SerialName(\"ownerPartyId\")\n val ownerPartyId: Uuid? = null,\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = tenantId\n }\n\n @JsExportCompat\n @Serializable\n data class Local(\n override val email: String,\n override val displayName: String,\n ) : OwnerInput()\n\n @JsExportCompat\n @Serializable\n data class Hybrid(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n val externalSubject: String,\n ) : OwnerInput()" - }, - "ResendTenantSignupVerificationArgs": { - "kind": "data class", - "name": "ResendTenantSignupVerificationArgs", - "module": "service", - "source": "@JsExportCompat\n@Serializable\ndata class ResendTenantSignupVerificationArgs(\n val signupRequestId: String,\n /** Hashed source IP for rate-limit + audit. The adapter computes the hash. */\n val sourceIpHash: String? = null,\n)" - }, - "ResendTenantSignupVerificationResult": { - "kind": "data class", - "name": "ResendTenantSignupVerificationResult", - "module": "service", - "source": "@JsExportCompat\n@Serializable\ndata class ResendTenantSignupVerificationResult(\n val signupRequestId: String,\n /**\n * Fresh plaintext token. Same security model as\n * [RequestTenantSignupResult.plainVerificationToken] — sent out-of-band\n * via the email channel by the calling adapter; never persisted; never\n * returned in the public HTTP response.\n */\n val plainVerificationToken: String,\n val expiresAt: Instant,\n /**\n * Whether the parent tenant's signup policy requires operator\n * approval after email verification. Carried so the resend\n * notification email matches the actual post-click journey — the\n * request-time email already carries this flag and the resend must\n * not contradict it.\n */\n val requiresApproval: Boolean,\n)\n\n@JsExportCompat\n@Serializable\ndata class RequestTenantSignupResult(\n val signupRequestId: String,\n /**\n * Plaintext token. Sent out-of-band via the email channel by the calling\n * adapter; never persisted on the server. Returned ONLY in this in-process\n * call result — production REST adapters must NOT include it in the HTTP\n * response (the response is just the request id and expiry).\n */\n val plainVerificationToken: String,\n val expiresAt: Instant,\n val requiresApproval: Boolean,\n)" - }, - "ReconcileExpiredTenantSignupsArgs": { - "kind": "data class", - "name": "ReconcileExpiredTenantSignupsArgs", - "module": "service", - "source": "@JsExportCompat\n@Serializable\ndata class ReconcileExpiredTenantSignupsArgs(val now: Instant)" - }, - "ReconcileExpiredTenantSignupsResult": { - "kind": "data class", - "name": "ReconcileExpiredTenantSignupsResult", - "module": "service", - "source": "@JsExportCompat\n@Serializable\ndata class ReconcileExpiredTenantSignupsResult(\n val expiredCount: Int,\n)" - }, - "ApplicationTenantBootstrapRequest": { - "kind": "data class", - "name": "ApplicationTenantBootstrapRequest", - "module": "public", - "source": "@Serializable\ndata class ApplicationTenantBootstrapRequest(\n val operatorEmail: String? = null,\n val operatorDisplayName: String? = null,\n)" - }, - "ApplicationTenantStatusSnapshot": { - "kind": "data class", - "name": "ApplicationTenantStatusSnapshot", - "module": "public", - "source": "@Serializable\ndata class ApplicationTenantStatusSnapshot(\n val tenantId: String,\n val status: ApplicationTenantStatus,\n val hostedAsAvailable: Boolean,\n val hostedAsIssuerUrl: String? = null,\n val canRegisterFirstRealTenant: Boolean,\n)\n\n@Serializable\nenum class ApplicationTenantStatus {\n @SerialName(\"ACTIVE\")\n ACTIVE,\n\n @SerialName(\"SUSPENDED\")\n SUSPENDED,\n\n @SerialName(\"PENDING_VERIFICATION\")\n PENDING_VERIFICATION,\n}" - }, - "ApproveTenantSignupArgs": { - "kind": "data class", - "name": "ApproveTenantSignupArgs", - "module": "service", - "source": "@JsExportCompat\n@Serializable\ndata class ApproveTenantSignupArgs(\n val signupRequestId: String,\n val notes: String? = null,\n)" - }, - "ApproveTenantSignupResult": { - "kind": "data class", - "name": "ApproveTenantSignupResult", - "module": "service", - "source": "@JsExportCompat\n@Serializable\ndata class ApproveTenantSignupResult(\n val signupRequestId: String,\n val status: TenantSignupStatus,\n val registration: RegisterTenantResult? = null,\n)\n\n@JsExportCompat\nenum class TenantSignupStatus {\n PENDING_EMAIL,\n PENDING_APPROVAL,\n CONFIRMED,\n REGISTERED,\n REJECTED,\n EXPIRED,\n FAILED,\n}\n\n@JsExportCompat\r\n@Serializable\r\ndata class RegisterTenantResult(\r\n val tenant: Tenant,\r\n /** Primary platform subdomain URL, e.g. `https://acme.saas.com`. */\r\n val primaryDomainUrl: String,\r\n /** Default AS issuer URL, null when `hostedAs = false`. */\r\n val issuerUrl: String? = null,\r\n /**\r\n * Default OID4VCI credential-issuer identifier URL, null when `hostedAs = false`.\r\n * For co-located AS + issuer deployments this is the same origin as [issuerUrl]\r\n * with an `/oid4vci` path suffix.\r\n */\r\n val oid4vciIssuerUrl: String? = null,\r\n /** Local user id assigned to the owner. */\r\n val ownerUserId: String,\r\n /** Durable tenant registration log id for onboarding/status polling. */\r\n val correlationId: String = \"\",\r\n /** Single-use invitation token, only for Local/Hybrid owners. */\r\n val invitationToken: String? = null,\r\n)\n\n@JsExportCompat\n@Serializable\ndata class Tenant\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n val tenantId: String,\n @SerialName(\"tenantType\")\n val tenantType: TenantType,\n val name: String,\n val description: String? = null,\n /**\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\n * platform subdomain label and the dispatcher's peelable path segment.\n */\n val slug: String,\n /**\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\n * time (cycle detection walks up `parent_tenant_id`).\n */\n @SerialName(\"parentTenantId\")\n val parentTenantId: String? = null,\n val status: TenantStatus = TenantStatus.ACTIVE,\n /**\n * Generic \"system tenant\" flag. System tenants are excluded from default\n * listings and from all slug-based / parent-based resolution queries. Customer\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\n * their own system-tenant patterns. EDK does not define what a system tenant\n * is or what privileges it carries.\n */\n val system: Boolean = false,\n @SerialName(\"ownerPartyId\")\n val ownerPartyId: Uuid? = null,\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = tenantId\n }\n\n @JsExportCompat\n @Serializable\n data class Local(\n override val email: String,\n override val displayName: String,\n ) : OwnerInput()\n\n @JsExportCompat\n @Serializable\n data class Hybrid(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n val externalSubject: String,\n ) : OwnerInput()" - }, - "RejectTenantSignupArgs": { - "kind": "data class", - "name": "RejectTenantSignupArgs", - "module": "service", - "source": "@JsExportCompat\n@Serializable\ndata class RejectTenantSignupArgs(\n val signupRequestId: String,\n val reason: String? = null,\n)" - }, - "RejectTenantSignupResult": { - "kind": "data class", - "name": "RejectTenantSignupResult", - "module": "service", - "source": "@JsExportCompat\n@Serializable\ndata class RejectTenantSignupResult(val rejected: Boolean)" - }, - "LicenseSnapshotProjection": { - "kind": "data class", - "name": "LicenseSnapshotProjection", - "module": "public", - "source": "@Serializable\ndata class LicenseSnapshotProjection(\n val status: LicenseStatus,\n val features: LicenseFeatureFlags,\n val limits: LicenseLimitProjection,\n)\n\n@Serializable\nenum class LicenseStatus {\n ACTIVE,\n EXPIRED,\n INVALID,\n MISSING,\n}\n\n@Serializable\ndata class LicenseFeatureFlags(\n val selfSignup: Boolean,\n val subtenants: Boolean,\n)\n\n@Serializable\ndata class LicenseLimitProjection(\n val maxRootTenants: Long,\n val maxTotalTenants: Long,\n val maxHierarchyDepth: Int,\n val subtenantsAllowed: Boolean,\n)" - }, - "SecretBackendSelection": { - "kind": "data class", - "name": "SecretBackendSelection", - "module": "public", - "source": "@Serializable\ndata class SecretBackendSelection(\n val backend: SecretBackendType,\n val configRef: String? = null,\n)\n\n@Serializable\nenum class SecretBackendType {\n @SerialName(\"azure-key-vault\")\n AZURE_KEY_VAULT,\n\n @SerialName(\"hashicorp-vault\")\n HASHICORP_VAULT,\n\n @SerialName(\"kubernetes-secret-mount\")\n KUBERNETES_SECRET_MOUNT,\n\n @SerialName(\"config-system-dev-only\")\n CONFIG_SYSTEM_DEV_ONLY,\n}" - }, - "SecretBackendStatusSnapshot": { - "kind": "data class", - "name": "SecretBackendStatusSnapshot", - "module": "public", - "source": "@Serializable\ndata class SecretBackendStatusSnapshot(\n val configured: Boolean,\n val selection: SecretBackendSelection? = null,\n)\n\n@Serializable\ndata class SecretBackendSelection(\n val backend: SecretBackendType,\n val configRef: String? = null,\n)\n\n@Serializable\nenum class SecretBackendType {\n @SerialName(\"azure-key-vault\")\n AZURE_KEY_VAULT,\n\n @SerialName(\"hashicorp-vault\")\n HASHICORP_VAULT,\n\n @SerialName(\"kubernetes-secret-mount\")\n KUBERNETES_SECRET_MOUNT,\n\n @SerialName(\"config-system-dev-only\")\n CONFIG_SYSTEM_DEV_ONLY,\n}" - }, - "OnboardingPolicyUpdate": { - "kind": "data class", - "name": "OnboardingPolicyUpdate", - "module": "public", - "source": "@Serializable\ndata class OnboardingPolicyUpdate(\n val rootTenantCreationEnabled: Boolean? = null,\n val adminInviteEnabled: Boolean? = null,\n val selfSignupEnabled: Boolean? = null,\n val subtenantSignupEnabled: Boolean? = null,\n val requireApprovalForSelfSignup: Boolean? = null,\n)" - }, - "OnboardingPolicySnapshot": { - "kind": "data class", - "name": "OnboardingPolicySnapshot", - "module": "public", - "source": "@Serializable\ndata class OnboardingPolicySnapshot(\n val rootTenantCreationEnabled: Boolean,\n val adminInviteEnabled: Boolean,\n val selfSignupEnabled: Boolean,\n val subtenantSignupEnabled: Boolean,\n val requireApprovalForSelfSignup: Boolean,\n val updatedAt: Instant? = null,\n)" - }, - "RedeemOwnerInvitationArgs": { - "kind": "data class", - "name": "RedeemOwnerInvitationArgs", - "module": "tenant-owner-bootstrap", - "source": "@JsExportCompat\n@Serializable\ndata class RedeemOwnerInvitationArgs(\n val token: String,\n val credential: String,\n)" - }, - "RedeemOwnerInvitationResult": { - "kind": "data class", - "name": "RedeemOwnerInvitationResult", - "module": "tenant-owner-bootstrap", - "source": "@JsExportCompat\n@Serializable\ndata class RedeemOwnerInvitationResult(\n val ownerUserId: String,\n val tenantId: String,\n)" - }, - "UpsertTenantPublicEndpointArgs": { - "kind": "data class", - "name": "UpsertTenantPublicEndpointArgs", - "module": "service", - "source": "@JsExportCompat\n@Serializable\ndata class UpsertTenantPublicEndpointArgs(\n val tenantId: String,\n val serviceType: TenantPublicEndpointServiceType,\n val host: String? = null,\n val pathPrefix: String? = null,\n val wellKnownPath: String? = null,\n val enabled: Boolean = true,\n val primaryEndpoint: Boolean = false,\n)\n\n@JsExportCompat\n@Serializable\nenum class TenantPublicEndpointServiceType {\n OID4VCI_ISSUER,\n OID4VP_VERIFIER,\n OAUTH2_AUTHORIZATION_SERVER,\n}" - }, - "TenantPublicEndpoint": { - "kind": "data class", - "name": "TenantPublicEndpoint", - "module": "public", - "source": "@JsExportCompat\n@Serializable\ndata class TenantPublicEndpoint\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n val endpointId: String,\n val tenantId: String,\n val serviceType: TenantPublicEndpointServiceType,\n /**\n * Identifies which software instance (the VDX `partyId` / the IDK instance id)\n * this public endpoint belongs to. Null is the single default/legacy binding\n * for the (tenant, service type); non-null values let a tenant own multiple\n * concurrent public endpoints for the same service type, one per instance.\n */\n val instanceId: String? = null,\n /** Lowercased host without scheme or port. Null means use the runtime host/default base. */\n val host: String? = null,\n /** Protocol route prefix, for example `/acme/oid4vci`. */\n val pathPrefix: String? = null,\n /** Well-known route, for example `/.well-known/openid-credential-issuer/acme`. */\n val wellKnownPath: String? = null,\n val enabled: Boolean = true,\n val primaryEndpoint: Boolean = false,\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = endpointId\n }\n\n@JsExportCompat\n@Serializable\nenum class TenantPublicEndpointServiceType {\n OID4VCI_ISSUER,\n OID4VP_VERIFIER,\n OAUTH2_AUTHORIZATION_SERVER,\n}\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNull\")\n @Serializable(with = CDDLSerializer::class)\n object Null : CDDL(\"null\", MajorType.SPECIAL, 22, arrayOf(nil)) {\n fun newNull() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n@JsExportCompat\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"HasId\", exact = true)\ninterface HasId {\n val id: String\n}\n\ninternal object CDDLSerializer : KSerializer {\n override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(\"CDDL\", PrimitiveKind.STRING)\n\n override fun serialize(\n encoder: Encoder,\n value: CDDL,\n ) {\n encoder.encodeString(value.format)\n }\n\n override fun deserialize(decoder: Decoder): CDDL = CDDL.util.fromFormat(decoder.decodeString())\n}\n\n@Suppress(\"UNCHECKED_CAST\")\n@JsExportCompat\n@Serializable(with = CDDLSerializer::class)\nsealed class CDDL(\n override val format: String,\n override val majorType: MajorType? = null,\n override val info: Int? = null,\n override val aliasFor: Array = arrayOf(),\n) : CDDLType {\n override fun newCborItemFromJson(\n element: JsonElement?,\n cddl: CDDLType?,\n ): CborItem {\n val jsonPrimitive: JsonPrimitive? = (element as? JsonPrimitive)?.jsonPrimitive\n val jsonArray: JsonArray? = (element as? JsonArray)?.jsonArray\n val jsonObject: JsonObject? = (element as? JsonObject)?.jsonObject\n val isNull: Boolean = element == JsonNull || element === null\n val isString: Boolean = jsonPrimitive?.isString == true\n\n if (isNull) {\n return CborNull()\n } else if (isString && jsonPrimitive !== null) {\n return CborString(jsonPrimitive.content)\n } else if (jsonArray !== null) {\n return list.fromJson(jsonArray)\n } else if (jsonObject !== null) {\n if (CborItemJson.isCborItemValueJson(jsonObject)) {\n val key =\n if (CborItemJson.isCborItemJson(jsonObject)) {\n (jsonObject[\"key\"] as? JsonPrimitive)?.content\n } else {\n null\n }\n val cddlStr = (jsonObject[\"cddl\"] as? JsonPrimitive)?.content\n\n if (cddlStr === null) {\n // cddl key found, but wasn't a primitive, returning a null value\n return CborNull()\n }\n val cddlObject = util.fromFormat(cddlStr)\n val cborObject = newCborItemFromJson(jsonObject[jsonObject.keys.find { it != CDDL_LITERAL && it != KEY_LITERAL }], cddlObject)\n if (key === null) {\n return cborObject\n }\n return CborMap(mutableMapOf(Pair(CborString(key), cborObject)))\n }\n // number label keys?\n return CborMap(mutableMapOf(* jsonObject.map { Pair(CborString(it.key), newCborItemFromJson(it.value)) }.toTypedArray()))\n } else if (jsonPrimitive !== null) {\n if (cddl == null) {\n return newCborItem(jsonPrimitive)\n }\n return when (cddl) {\n // Needed because we cannot have inheritance with Kotlin to JS, unfortunately. The fromJson would cause clashes if we put it in the interface\n tstr -> tstr.fromJson(jsonPrimitive)\n\n Null -> CborNull()\n\n False -> CborSimple.FALSE\n\n True -> CborSimple.TRUE\n\n bool -> bool.fromJson(jsonPrimitive)\n\n bstr -> bstr.fromJson(jsonPrimitive)\n\n bytes -> bytes.fromJson(jsonPrimitive)\n\n float -> float.fromJson(jsonPrimitive)\n\n float16 -> float16.fromJson(jsonPrimitive)\n\n float32 -> float32.fromJson(jsonPrimitive)\n\n float64 -> float64.fromJson(jsonPrimitive)\n\n full_date -> full_date.fromJson(jsonPrimitive)\n\n int -> int.fromJson(jsonPrimitive)\n\n nil -> nil.newNil()\n\n nint -> nint.fromJson(jsonPrimitive)\n\n tdate -> tdate.fromJson(jsonPrimitive)\n\n text -> text.fromJson(jsonPrimitive)\n\n time -> time.fromJson(jsonPrimitive)\n\n uint -> uint.fromJson(jsonPrimitive)\n\n undefined -> undefined.newUndefined()\n\n else -> cddl.newCborItem(jsonPrimitive)\n }\n }\n return newCborItem(element)\n }\n\n override fun newCborItem(origValue: T?): CborItem {\n // We are not using inheritance for the methods as that would impact JS export.\n // Since this is a sealed class anyway that is not too bad\n var value = origValue\n val jsonElement: JsonElement? =\n when (value) {\n is JsonPrimitive -> value\n is JsonArray -> value\n is JsonObject -> value\n is JsonNull -> value\n else -> null\n }\n if (value == null) {\n return nil.newNil()\n } else if (value == Unit) {\n return undefined.newUndefined()\n }\n return when (this) {\n tstr -> {\n if (jsonElement === null) {\n tstr.newString(value.toString())\n } else {\n tstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n False -> {\n False.newFalse()\n }\n\n Null -> {\n Null.newNull()\n }\n\n True -> {\n True.newTrue()\n }\n\n any -> {\n return when (value) {\n is JsonPrimitive -> {\n val prim = value\n when {\n prim.isString -> tstr.fromJson(prim)\n prim.content == \"true\" || prim.content == \"false\" -> bool.fromJson(prim)\n prim.content.contains('.') || prim.content.contains('e') || prim.content.contains('E') -> float64.fromJson(prim)\n else -> int.fromJson(prim) // Assume integer if not string, boolean, or float\n }\n }\n\n is cddl_tstr -> {\n if (jsonElement === null) {\n tstr.newString(value)\n } else {\n tstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_bstr -> {\n if (jsonElement === null) {\n bstr.newByteString(value)\n } else {\n bstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_tdate -> {\n if (jsonElement === null) {\n tdate.newTDate(value)\n } else {\n tdate.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_full_date -> {\n if (jsonElement === null) {\n full_date.newFullDate(value)\n } else {\n full_date.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_bool -> {\n if (jsonElement === null) {\n bool.newBool(value)\n } else {\n bool.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n // Use consolidated Number handling for JS/WasmJs compatibility\n // (on JS, all numeric `is` checks match any Number, making individual checks unreliable)\n is Number -> {\n if (jsonElement === null) {\n value.toCborItem()\n } else {\n val d = value.toDouble()\n if (d != kotlin.math.floor(d) || d.isInfinite() || d.isNaN()) {\n float64.fromJson(jsonElement.jsonPrimitive)\n } else {\n int.fromJson(jsonElement.jsonPrimitive)\n }\n }\n }\n\n is cddl_list<*> -> {\n if (jsonElement === null) {\n list.newList(\n value\n .map {\n if (it is CborItem<*>) {\n it\n } else {\n any.newCborItem(\n it,\n )\n }\n }.toMutableList(),\n )\n } else {\n list.fromJson(jsonElement.jsonArray)\n }\n }\n\n is cddl_map<*, *> -> {\n if (jsonElement === null) {\n map.newMap(\n mutableMapOf(\n * value\n .map {\n Pair(\n if (it.key is CborItem<*>) {\n it.key as CborItem<*>\n } else {\n any.newCborItem(it.key)\n },\n if (it.value is CborItem<*>) {\n it.value as CborItem<*>\n } else {\n any.newCborItem(it.value)\n },\n )\n }.toTypedArray(),\n ),\n )\n } else {\n map.fromJson(jsonElement.jsonObject)\n }\n }\n\n else -> {\n throw IllegalArgumentException(\"newCborItem for $value Not implemented yet\")\n }\n }\n }\n\n bool -> {\n if (jsonElement === null) {\n bool.newBool(value == true)\n } else {\n bool.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n bstr -> {\n if (jsonElement === null) {\n bstr.newByteString(value as ByteArray)\n } else {\n bstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n bstr_indef_length -> {\n if (jsonElement === null) {\n bstr_indef_length.newByteString(value as List)\n } else {\n TODO(\"indef cddl from json not implemented yet\")\n }\n }\n\n bytes -> {\n if (jsonElement === null) {\n bytes.newBytes(value as ByteArray)\n } else {\n bytes.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float -> {\n if (jsonElement === null) {\n float.newFloat(value as Float)\n } else {\n float.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float16 -> {\n if (jsonElement === null) {\n float16.newFloat16(value as Float)\n } else {\n float16.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float32 -> {\n if (jsonElement === null) {\n float32.newFloat32(value as Float)\n } else {\n float32.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float64 -> {\n if (jsonElement === null) {\n float64.newFloat64(value as Double)\n } else {\n float64.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n full_date -> {\n if (jsonElement === null) {\n full_date.newFullDate(value as cddl_full_date)\n } else {\n full_date.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n int -> {\n if (jsonElement === null) {\n int.newInt(value as Int)\n } else {\n int.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n list -> {\n if (jsonElement === null) {\n if (value is CborArray<*>) {\n value\n } else {\n list.newList(\n (value as List<*>)\n .map {\n if (it is CborItem<*>) {\n it\n } else {\n any.newCborItem(\n it,\n )\n }\n }.toMutableList(),\n )\n }\n } else {\n list.fromJson(jsonElement.jsonArray)\n }\n }\n\n map -> {\n if (jsonElement === null) {\n if (value is CborMap<*, *>) {\n value\n } else {\n map.newMap(\n mutableMapOf(\n * (value as Map<*, *>)\n .map {\n Pair(\n if (it.key is CborItem<*>) {\n it.key as CborItem<*>\n } else {\n any.newCborItem(it.key)\n },\n if (it.value is CborItem<*>) {\n it.value as CborItem<*>\n } else {\n any.newCborItem(it.value)\n },\n )\n }.toTypedArray(),\n ),\n ) // fixme. Needs inspection of keys and values and map type\n }\n } else {\n return map.fromJson(jsonElement.jsonObject)\n }\n }\n\n nil -> {\n nil.newNil()\n }\n\n nint -> {\n if (jsonElement === null) {\n nint.newNInt(\n if (value is Number) {\n value.toLong()\n } else {\n value as Long\n }\n )\n } else {\n nint.fromJson(\n jsonElement.jsonPrimitive,\n )\n }\n }\n\n tdate -> {\n if (jsonElement === null) {\n tdate.newTDate(value as cddl_tdate)\n } else {\n tdate.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n text -> {\n if (jsonElement === null) {\n text.newText(value as cddl_text)\n } else {\n text.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n time -> {\n if (jsonElement === null) {\n time.newTime(value as cddl_time)\n } else {\n time.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n tstr_indef_length -> {\n if (jsonElement !== null) {\n tstr_indef_length.newStringIndefLength(value as List)\n } else {\n TODO(\"tstr indef length from json to cbor not implemented\")\n }\n }\n\n uint -> {\n if (jsonElement === null) {\n uint.newUint(\n if (value is Long) {\n value\n } else if (value is Number) {\n value.toLong()\n } else {\n value as Long\n },\n )\n } else {\n uint.fromJson(\n jsonElement.jsonPrimitive,\n )\n }\n }\n\n undefined -> {\n undefined.newUndefined()\n }\n }\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTstr\")\n object tstr : CDDL(\"tstr\", MajorType.UNICODE_STRING) {\n fun newString(value: cddl_tstr) = CborString(value)\n\n fun fromJson(value: JsonPrimitive) = CborString(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlUint\")\n object uint : CDDL(\"uint\", MajorType.UNSIGNED_INTEGER) {\n fun newUint(value: cddl_uint) = CborUInt(value)\n\n fun fromJson(value: JsonPrimitive) = CborUInt(value.content.toLong())\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNint\")\n object nint : CDDL(\"nint\", MajorType.NEGATIVE_INTEGER) {\n fun newNInt(value: cddl_nint) = CborNInt(value)\n\n fun fromJson(value: JsonPrimitive) = CborNInt(value.content.toLong())\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlInt\")\n object int :\n CDDL(\"int\", null, null, aliasFor = arrayOf(uint, nint)) {\n fun newInt(value: Int) =\n if (value < 0) {\n CborNInt(value.toLong())\n } else {\n CborUInt(value.toLong())\n }\n\n fun newLong(value: Long) =\n if (value < 0) {\n CborNInt(value)\n } else {\n CborUInt(value)\n }\n\n fun fromJson(value: JsonPrimitive) =\n if (value.long < 0) {\n CborNInt(value.long)\n } else {\n CborUInt(value.long)\n }\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBstr\")\n object bstr : CDDL(\"bstr\", MajorType.BYTE_STRING) {\n fun newByteString(value: cddl_bstr) = CborByteString(value)\n\n fun fromJson(\n value: JsonPrimitive,\n encoding: Encoding = Encoding.BASE64URL,\n ) = CborByteString(value.content.decodeFrom(encoding))\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBstrIndefLength\")\n object bstr_indef_length : CDDL(\"bstr\", MajorType.BYTE_STRING) {\n fun newByteString(value: List) = CborByteStringIndefLength(value)\n\n fun fromJson(\n value: JsonArray,\n encoding: Encoding = Encoding.BASE64URL,\n ): CborByteStringIndefLength = TODO(\"indef length from json to cbor not implemented yet\")\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBytes\")\n object bytes : CDDL(\"bytes\", MajorType.BYTE_STRING, aliasFor = arrayOf(bstr)) {\n fun newBytes(value: cddl_bstr) = CborByteString(value)\n\n fun fromJson(\n value: JsonPrimitive,\n encoding: Encoding = Encoding.BASE64URL,\n ) = CborByteString(value.content.decodeFrom(encoding))\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTstrIndefLength\")\n object tstr_indef_length : CDDL(\"tstr\", MajorType.UNICODE_STRING) {\n fun newStringIndefLength(value: List) = CborStringIndefLength(value)\n\n fun fromJson(\n value: JsonArray,\n encoding: Encoding = Encoding.BASE64URL,\n ): CborStringIndefLength = TODO(\"indef length from json to cbor not implemented yet\")\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlText\")\n object text : CDDL(\"text\", MajorType.UNICODE_STRING, aliasFor = arrayOf(tstr)) {\n fun newText(value: cddl_text) = CborString(value)\n\n fun fromJson(value: JsonPrimitive) = CborString(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTdate\")\n object tdate : CDDL(\n \"tdate\",\n MajorType.TAG,\n DATE_TIME_STRING,\n ) { // RFC 7049, section 2.4.1, a tdate data item shall contain a date-time string as specified in RFC 3339\n fun newTDate(value: cddl_tdate) = CborTDate(value)\n\n fun fromJson(value: JsonPrimitive) = CborTDate(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFullDate\")\n object full_date : CDDL(\n \"full-date\",\n MajorType.TAG,\n CborTagged.FULL_DATE_STRING,\n ) { // #6.1004(tstr) In accordance with RFC 8943, a full-date data item shall contain a full-datestring as specified in RFC 3339.\n fun newFullDate(value: cddl_full_date) = CborFullDate(value)\n\n fun fromJson(value: JsonPrimitive) = CborFullDate(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTime\")\n object time : CDDL(\n \"time\",\n MajorType.TAG,\n CborTagged.DATE_TIME_NUMBER,\n ) { // RFC 7049, section 2.4.1, a tdate data item shall contain a date-time number as specified in RFC 3339\n fun newTime(value: cddl_time) = CborTime(value)\n\n fun fromJson(value: JsonPrimitive) = CborTime(value.content.toLong())\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat16\")\n object float16 : CDDL(\"float16\", MajorType.SPECIAL, 25) {\n fun newFloat16(value: cddl_float16) = CborFloat16(value)\n\n fun fromJson(value: JsonPrimitive) = CborFloat16(value.float)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat32\")\n object float32 : CDDL(\"float32\", MajorType.SPECIAL, 26) {\n fun newFloat32(value: cddl_float32) = CborFloat32(value)\n\n fun fromJson(value: JsonPrimitive) = CborFloat32(value.float)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat64\")\n object float64 : CDDL(\"float64\", MajorType.SPECIAL, 27) {\n fun newFloat64(value: cddl_float64) = CborDouble(value)\n\n fun fromJson(value: JsonPrimitive) = CborDouble(value.double)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat\")\n object float : CDDL(\"float\", MajorType.SPECIAL, aliasFor = arrayOf(float16, float32, float64)) {\n fun newFloat(value: cddl_float) = CborFloat32(value)\n\n fun fromJson(value: JsonPrimitive) = CborFloat32(value.float)\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFalse\")\n @Serializable(with = CDDLSerializer::class)\n object False : CDDL(\"false\", MajorType.SPECIAL, 20) {\n fun newFalse() = CborSimple.FALSE\n\n fun fromJson(value: JsonPrimitive) = CborSimple.FALSE\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTrue\")\n @Serializable(with = CDDLSerializer::class)\n object True : CDDL(\"true\", MajorType.SPECIAL, 21) {\n fun newTrue() = CborSimple.TRUE\n\n fun fromJson(value: JsonPrimitive) = CborSimple.TRUE\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBool\")\n object bool :\n CDDL(\"bool\", MajorType.SPECIAL, aliasFor = arrayOf(False, True)) {\n fun newBool(value: cddl_bool) =\n if (value) {\n CborSimple.TRUE\n } else {\n CborSimple.FALSE\n }\n\n fun fromJson(value: JsonPrimitive) =\n if (value.boolean) {\n CborSimple.TRUE\n } else {\n CborSimple.FALSE\n }\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNil\")\n object nil : CDDL(\"nil\", MajorType.SPECIAL, 22) {\n fun newNil() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNull\")\n @Serializable(with = CDDLSerializer::class)\n object Null : CDDL(\"null\", MajorType.SPECIAL, 22, arrayOf(nil)) {\n fun newNull() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlUndefined\")\n object undefined :\n CDDL(\"undefined\", MajorType.SPECIAL, 23) {\n fun newUndefined() = CborSimple.UNDEFINED\n\n fun fromJson(value: JsonElement) = CborSimple.UNDEFINED\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlMap\")\n object map :\n CDDL(\n \"map\",\n MajorType.MAP,\n ) {\n fun newMap(value: MutableMap, CborItem<*>>): CborItem, CborItem<*>>> = CborMap(value)\n\n /**\n * Please note that this method is not able to map onto the exact Cbor items as the json values have no type information!\n */\n fun fromJson(value: JsonObject): CborMap> =\n CborMap(\n value.entries\n .map {\n Pair(\n CborString(it.key),\n when (it.value) {\n is JsonPrimitive -> any.fromJson(it.value)\n is JsonArray -> list.fromJson(it.value as JsonArray)\n is JsonObject -> fromJson(it.value as JsonObject)\n else -> throw IllegalArgumentException(\"Unknown type encountered\")\n },\n )\n }.toMap()\n .toMutableMap(),\n )\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlList\")\n object list :\n CDDL(\n \"list\",\n MajorType.ARRAY,\n ) {\n fun > newList(value: cddl_list) = CborArray(value)\n\n /**\n * Please note that this method is not able to map onto the exact Cbor items as the json values have no type information!\n */\n fun fromJson(value: JsonArray): CborArray> =\n CborArray(\n value\n .map { elt ->\n when (elt) {\n is JsonPrimitive -> {\n any.fromJson(elt)\n }\n\n is JsonArray -> {\n fromJson(elt)\n }\n\n is JsonObject -> {\n if (CborItemJson.isCborItemValueJson(elt)) {\n newCborItemFromJson(\n elt,\n elt[CDDL_LITERAL]?.jsonPrimitive?.content?.let { CDDL.util.fromFormat(it) },\n )\n } else {\n map.fromJson(elt)\n }\n }\n\n else -> {\n throw IllegalArgumentException(\"Unknown type encountered\")\n }\n }\n }.toMutableList(),\n )\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlAny\")\n object any :\n CDDL(\n \"any\",\n ) {\n fun newAny(value: cddl_any) = CborAny(value)\n\n fun fromJson(value: JsonElement): CborItem<*> {\n return newCborItemFromJson(value)\n// TODO(\"Json any to cbor not implemeted yet\")\n }\n }\n\n override fun toTag(additionalInfo: Int?): String {\n if (aliasFor.isNotEmpty()) {\n if (additionalInfo == null) {\n return aliasFor[0].toTag(additionalInfo)\n }\n\n // fixme: this is not correct. We first need to traverse the aliases, as an alias could go without major and additional info\n return util.entries\n .first { it.majorType == majorType && it.info == additionalInfo }\n .toTag(additionalInfo)\n }\n\n var tag = \"#\"\n if (majorType != null) {\n tag += majorType\n }\n if (additionalInfo != null) {\n tag += \".$additionalInfo\"\n }\n return tag\n }\n\n override fun toString(): String = \"CDDL(format='$format', majorType=$majorType, info=$info, aliasFor=${aliasFor.contentToString()})\"\n\n override fun equals(other: Any?): Boolean {\n if (this === other) {\n return true\n }\n if (other !is CDDL) {\n return false\n }\n\n if (format != other.format) {\n return false\n }\n if (majorType != other.majorType) {\n return false\n }\n if (info != other.info) {\n return false\n }\n if (!aliasFor.contentEquals(other.aliasFor)) {\n return false\n }\n\n return true\n }\n\n override fun hashCode(): Int {\n var result = format.hashCode()\n result = 31 * result + (majorType?.hashCode() ?: 0)\n result = 31 * result + (info ?: 0)\n result = 31 * result + aliasFor.contentHashCode()\n return result\n }\n\n object util {\n // Lazy for serialization as this class is used as object in the above CDDL class\n val entries by lazy {\n arrayOf(\n any,\n uint,\n int,\n nint,\n bstr,\n bstr_indef_length,\n bytes,\n tstr,\n tstr_indef_length,\n text,\n tdate,\n full_date,\n time,\n float,\n False,\n True,\n bool,\n nil,\n Null,\n undefined,\n float16,\n float32,\n float64,\n map,\n list,\n )\n }\n\n fun fromFormat(format: String) = entries.first { it.format == format }\n\n fun fromTag(tag: String): CDDL {\n require(tag.startsWith(\"#\")) { \"Invalid tag supplied $tag\" }\n val parts = tag.split(\"#\", \".\")\n if (parts.size == 1) {\n return any\n }\n val majorVal = parts[1].toIntOrNull()\n return fromMajorType(majorVal?.let { MajorType.fromInt(it) }, parts[2].toIntOrNull())\n }\n\n fun fromBytes(input: Int): CDDL {\n val majorType = input shr 5\n\n // todo additionalInto\n return fromMajorType(MajorType.fromInt(majorType))\n }\n\n fun fromMajorType(\n majorType: MajorType? = null,\n additionalInfo: Int? = null,\n ) = entries.first {\n it.majorType == majorType && it.info == additionalInfo\n }\n }\n}\n\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"MajorType\", exact = true)\n@Serializable\n@JsExportCompat\nenum class MajorType(\n val type: Int,\n) {\n /**\n * Major type 0.\n *\n * An unsigned integer in the range 0..2^64-1 inclusive. The value of the encoded item is the\n * argument itself. For example, the integer 10 is denoted as the one byte 0b000_01010 (major\n * type 0, additional information 10). The integer 500 would be 0b000_11001 (major type 0,\n * additional information 25) followed by the two bytes 0x01f4, which is 500 in decimal.\n */\n UNSIGNED_INTEGER(0),\n\n /**\n * Major type 1.\n *\n * A negative integer in the range -2^64..-1 inclusive. The value of the item is -1 minus\n * the argument. For example, the integer -500 would be 0b001_11001 (major type 1, additional\n * information 25) followed by the two bytes 0x01f3, which is 499 in decimal.\n */\n NEGATIVE_INTEGER(1),\n\n /**\n * Major type 2.\n *\n * A byte string. The number of bytes in the string is equal to the argument. For example,\n * a byte string whose length is 5 would have an initial byte of 0b010_00101 (major type 2,\n * additional information 5 for the length), followed by 5 bytes of binary content. A byte\n * string whose length is 500 would have 3 initial bytes of 0b010_11001 (major type 2,\n * additional information 25 to indicate a two-byte length) followed by the two bytes 0x01f4\n * for a length of 500, followed by 500 bytes of binary content.\n */\n BYTE_STRING(2),\n\n /**\n * Major type 3.\n *\n * A text string (Section 2) encoded as UTF-8 [RFC3629]. The number of bytes in the string\n * is equal to the argument. A string containing an invalid UTF-8 sequence is well-formed\n * but invalid (Section 1.2). This type is provided for systems that need to interpret or\n * display human-readable text, and allows the differentiation between unstructured bytes\n * and text that has a specified repertoire (that of Unicode) and encoding (UTF-8). In\n * contrast to formats such as JSON, the Unicode characters in this type are never escaped.\n * Thus, a newline character (U+000A) is always represented in a string as the byte 0x0a,\n * and never as the bytes 0x5c6e (the characters \"\\\" and \"n\") nor as 0x5c7530303061 (the\n * characters \"\\\", \"u\", \"0\", \"0\", \"0\", and \"a\").\n */\n UNICODE_STRING(3),\n\n /**\n * Major type 4.\n * An array of data items. In other formats, arrays are also called lists, sequences, or\n * tuples (a \"CBOR sequence\" is something slightly different, though [RFC8742]). The argument\n * is the number of data items in the array. Items in an array do not need to all be of the\n * same type. For example, an array that contains 10 items of any type would have an initial\n * byte of 0b100_01010 (major type 4, additional information 10 for the length) followed by\n * the 10 remaining items.\n */\n ARRAY(4),\n\n /**\n * Major type 5.\n *\n * A map of pairs of data items. Maps are also called tables, dictionaries, hashes, or\n * objects (in JSON). A map is comprised of pairs of data items, each pair consisting of a\n * key that is immediately followed by a value. The argument is the number of pairs of data\n * items in the map. For example, a map that contains 9 pairs would have an initial byte of\n * 0b101_01001 (major type 5, additional information 9 for the number of pairs) followed by\n * the 18 remaining items. The first item is the first key, the second item is the first\n * value, the third item is the second key, and so on. Because items in a map come in pairs,\n * their total number is always even: a map that contains an odd number of items (no value\n * data present after the last key data item) is not well-formed. A map that has duplicate\n * keys may be well-formed, but it is not valid, and thus it causes indeterminate decoding;\n * see also Section 5.6.\n */\n MAP(5),\n\n /**\n * Major type 6.\n *\n * A tagged data item (\"tag\") whose tag number, an integer in the range 0..2^64-1 inclusive,\n * is the argument and whose enclosed data item (tag content) is the single encoded data item\n * that follows the head. See Section 3.4.\n */\n TAG(6),\n\n /**\n * Major type 7.\n *\n * Floating-point numbers and simple values, as well as the \"break\" stop code. See Section 3.3.\n */\n SPECIAL(7),\n ;\n\n companion object {\n /**\n * Gets a [MajorType] instance from type.\n *\n * @param value an integer between 0 and 7, both inclusive\n * @return a [MajorType] for the given value.\n */\n @JsStatic\n @JvmStatic\n fun fromInt(value: Int): MajorType =\n entries.find { it.type == value }\n ?: throw IllegalArgumentException(\"Unknown major type with value $value\")\n }\n}\n\nabstract class CborSimple(\n value: Type,\n cddl: CDDL,\n) : CborItem(value, cddl) {\n init {\n val info =\n when (cddl) {\n is CDDL.bool -> {\n when (value) {\n true -> CDDL.True.info\n else -> CDDL.False.info\n }\n }\n\n else -> {\n cddl.info\n }\n }\n require(info != null)\n require(info is Int)\n check(info < 24 || (info in 32..255))\n }\n\n override fun encode(builder: ByteStringBuilder) {\n val majorTypeShifted = (majorType!!.type shl 5).toByte()\n builder.append(majorTypeShifted.or(info!!.toByte()))\n }\n\n override fun equals(other: Any?): Boolean = other is CborSimple<*> && value == other.value\n\n override fun hashCode(): Int = value.hashCode()\n\n override fun toString() =\n when (this) {\n FALSE -> \"Simple(FALSE)\"\n TRUE -> \"Simple(TRUE)\"\n NULL -> \"Simple(NULL)\"\n UNDEFINED -> \"Simple(UNDEFINED)\"\n else -> \"Simple($value)\"\n }\n\n companion object {\n /** The [Simple] value for FALSE */\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"CBOR_FALSE\")\n @JsStatic\n @JvmStatic\n val FALSE = CborFalse()\n\n /** The [Simple] value for TRUE */\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"CBOR_TRUE\")\n @JsStatic\n @JvmStatic\n val TRUE = CborTrue()\n\n /** The [Simple] value for NULL */\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"CBOR_NULL\")\n @JsStatic\n @JvmStatic\n val NULL = CborNull()\n\n /** The [Simple] value for UNDEFINED */\n @JsStatic\n @JvmStatic\n val UNDEFINED = CborUndefined()\n }\n}" - } -} diff --git a/connector-components.yml b/connector-components.yml index 4219015..7065ae3 100644 --- a/connector-components.yml +++ b/connector-components.yml @@ -230,6 +230,11 @@ components: format: uuid description: Stable identifier for a described external or internal resource shape. example: 41436f49-040c-4f5f-9c7f-657f43762e2b + ConnectorId: + type: string + format: uuid + description: Stable identifier for a connector instance. + example: 5f1b2f49-1397-44a7-bf5e-11340b4777c7 FieldDescriptorId: type: string format: uuid @@ -364,6 +369,7 @@ components: type: string description: Product or protocol lifecycle stage at which a connector invocation can run. enum: + - OID4VCI_START - OID4VCI_AUTHORIZATION - OID4VCI_PRE_AUTHORIZED - OID4VCI_TOKEN @@ -381,7 +387,7 @@ components: - FORM_SUBMIT - PORTAL_FLOW - WORKFLOW_STEP_EXECUTION - example: OID4VCI_POST_ISSUANCE + example: OID4VCI_CREDENTIAL_REQUEST ConnectorInvocationRole: type: string description: Role the connector performs for a lifecycle invocation. @@ -1711,21 +1717,21 @@ components: $ref: '#/components/schemas/ConnectorInvocationBinding' example: binding: - invocationBindingId: issuer-config-1:post-issuance:proof-vault + invocationBindingId: issuer-config-1:credential-request:hr-profile ownerSurface: OID4VCI ownerReference: issuer-config-1 - stage: OID4VCI_POST_ISSUANCE - role: VAULT_RETENTION + stage: OID4VCI_CREDENTIAL_REQUEST + role: ENRICHMENT_SOURCE target: routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f - exchangeMode: PLATFORM_INITIATED_PUSH - dataDirection: OUT_OF_VDX + exchangeMode: PLATFORM_INITIATED_PULL + dataDirection: INTO_VDX initiationSide: PLATFORM logicalContext: tenantId: acme organizationUnitId: nl-ops brandId: brand-a - logicalConnectionBindingId: brand-a-proof-vault + logicalConnectionBindingId: brand-a-hr-profile physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b ConnectorInvocationBinding: @@ -1780,21 +1786,21 @@ components: metadata: $ref: '#/components/schemas/StringMap' example: - invocationBindingId: issuer-config-1:post-issuance:proof-vault + invocationBindingId: issuer-config-1:credential-request:hr-profile ownerSurface: OID4VCI ownerReference: issuer-config-1 - stage: OID4VCI_POST_ISSUANCE - role: VAULT_RETENTION + stage: OID4VCI_CREDENTIAL_REQUEST + role: ENRICHMENT_SOURCE target: routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f - exchangeMode: PLATFORM_INITIATED_PUSH - dataDirection: OUT_OF_VDX + exchangeMode: PLATFORM_INITIATED_PULL + dataDirection: INTO_VDX initiationSide: PLATFORM logicalContext: tenantId: acme organizationUnitId: nl-ops brandId: brand-a - logicalConnectionBindingId: brand-a-proof-vault + logicalConnectionBindingId: brand-a-hr-profile physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b ConnectorInvocationTarget: @@ -1846,7 +1852,7 @@ components: type: object description: Field selection, lookup, output mapping, provenance, and minimization rules used by an invocation or exposure. properties: - lookupInputs: + inputFields: type: array items: $ref: '#/components/schemas/ConnectorFieldSelector' @@ -1878,7 +1884,7 @@ components: type: string example: min-proof-source example: - lookupInputs: + inputFields: - protocolClaimPath: credential_subject.id selectedFields: - canonicalFieldPath: proof.status @@ -1891,7 +1897,7 @@ components: canonicalFieldPath: type: string example: proof.status - lookupKey: + connectorField: type: string example: employee_id protocolClaimPath: @@ -3618,7 +3624,7 @@ components: description: Request to start a route run. The input object is connector- and route-specific; the route's source binding decides how it is interpreted. properties: input: - description: Optional input payload, lookup keys, or batch reference passed to the route. + description: Optional input payload, connector fields, or batch reference passed to the route. nullable: true example: employee_id: E12345 @@ -4109,14 +4115,14 @@ components: $ref: '#/components/schemas/Page' example: data: - - invocationBindingId: issuer-config-1:post-issuance:proof-vault + - invocationBindingId: issuer-config-1:credential-request:hr-profile ownerSurface: OID4VCI ownerReference: issuer-config-1 - stage: OID4VCI_POST_ISSUANCE - role: VAULT_RETENTION + stage: OID4VCI_CREDENTIAL_REQUEST + role: ENRICHMENT_SOURCE target: routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f - exchangeMode: PLATFORM_INITIATED_PUSH + exchangeMode: PLATFORM_INITIATED_PULL logicalContext: tenantId: acme pagination: @@ -4644,7 +4650,7 @@ components: example: issuer-config-1 stage: type: string - example: OID4VCI_POST_ISSUANCE + example: OID4VCI_CREDENTIAL_REQUEST sessionId: type: string example: protocol-session-1 @@ -4655,6 +4661,152 @@ components: type: string example: protocol-correlation-1 + ConnectorRecordPayload: + type: object + description: Connector record payload. Inline payloads carry a value; reference payloads carry a URI or resource descriptor reference. + properties: + value: + description: Inline payload value. + representationKind: + $ref: '#/components/schemas/RepresentationKind' + contentType: + type: string + example: application/json + uri: + type: string + example: https://hr.example.test/employees/E1042 + resourceDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + contentHash: + type: string + example: sha256:4bf4... + length: + type: integer + format: int64 + example: 4096 + metadata: + type: object + additionalProperties: + type: string + + ConnectorRecord: + type: object + description: Runtime connector record emitted by a source connector or passed to a destination connector. + required: + - recordId + - payload + properties: + recordId: + type: string + example: hr:E1042 + payload: + $ref: '#/components/schemas/ConnectorRecordPayload' + invocationBindingId: + $ref: '#/components/schemas/ConnectorInvocationBindingId' + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + physicalConnectorInstanceId: + $ref: '#/components/schemas/ConnectorId' + exchangeMode: + $ref: '#/components/schemas/ConnectorExchangeMode' + governance: + $ref: '#/components/schemas/ConnectorGovernanceEnvelope' + semanticCoordinates: + type: array + items: + type: object + additionalProperties: true + partyAnchors: + $ref: '#/components/schemas/ConnectorPartyAnchorSet' + industrialDiscovery: + type: object + additionalProperties: true + industrialObservation: + type: object + additionalProperties: true + dataspace: + type: object + additionalProperties: true + protocolContext: + $ref: '#/components/schemas/ConnectorProtocolEventContext' + integrity: + $ref: '#/components/schemas/ConnectorIntegrityReference' + cursor: + $ref: '#/components/schemas/ConnectorCursor' + connectorResourceId: + $ref: '#/components/schemas/ConnectorResourceId' + resourceDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + operationBindingId: + $ref: '#/components/schemas/OperationBindingId' + occurredAt: + type: string + format: date-time + metadata: + type: object + additionalProperties: + type: string + + ConnectorWriteStatus: + type: string + description: Aggregate or per-record destination write status. + enum: + - ACCEPTED + - COMMITTED + - DEFERRED + - PARTIAL + - FAILED + example: COMMITTED + + ConnectorRecordWriteOutcome: + type: object + description: Per-record delivery outcome reported by a destination runtime. + required: + - recordId + - status + properties: + recordId: + type: string + example: hr:E1042 + status: + $ref: '#/components/schemas/ConnectorWriteStatus' + metadata: + type: object + additionalProperties: + type: string + + ConnectorWriteResult: + type: object + description: Destination connector write result, including aggregate and optional per-record outcomes. + required: + - status + properties: + status: + $ref: '#/components/schemas/ConnectorWriteStatus' + recordsAccepted: + type: integer + format: int64 + default: 0 + example: 1 + recordsCommitted: + type: integer + format: int64 + default: 0 + example: 1 + externalRunRef: + type: string + example: hr-export-20260705-001 + lastCursor: + $ref: '#/components/schemas/ConnectorCursor' + recordOutcomes: + type: array + items: + $ref: '#/components/schemas/ConnectorRecordWriteOutcome' + metadata: + type: object + additionalProperties: + type: string + ConnectorInvocationRequest: type: object description: Runtime request passed from a protocol, form, portal, or workflow stage into a connector invocation binding. @@ -4709,7 +4861,7 @@ components: subjectCorrelationHandle: type: string example: subject:E-100 - revocationReissueLookupKey: + revocationReissueConnectorField: type: string example: reissue:E-100 selectedFields: @@ -4730,6 +4882,8 @@ components: type: object description: Runtime result emitted by a connector invocation, including produced fields, written records, route lineage, and vault writes. properties: + invocationBindingId: + $ref: '#/components/schemas/ConnectorInvocationBindingId' producedFields: type: object additionalProperties: true @@ -4748,7 +4902,7 @@ components: Oid4vciConnectorPipelineRequest: type: object - description: EDK-neutral OID4VCI connector pipeline request used to run connector-native enrichment, export, or vault-retention bindings. + description: EDK-neutral OID4VCI connector pipeline request used to run connector-native enrichment, export, notification, route, or vault-retention bindings at any issuance stage. required: - protocolContext - initialFields @@ -4771,7 +4925,7 @@ components: Oid4vciConnectorPipelineResult: type: object - description: Result of an OID4VCI connector pipeline run, including accumulated fields and post-issuance vault writes. + description: Result of an OID4VCI connector pipeline run, including accumulated fields, invocation lineage, and vault writes. required: - fields - invocationResults @@ -4796,3 +4950,5 @@ components: example: owner_team: people-ops domain: employee-licensing + + diff --git a/connector-integration-openapi.yml b/connector-integration-openapi.yml index 53b96f4..aabb834 100644 --- a/connector-integration-openapi.yml +++ b/connector-integration-openapi.yml @@ -675,7 +675,7 @@ paths: description: Filter by product or protocol lifecycle stage. schema: $ref: '#/components/schemas/ConnectorInvocationStage' - example: OID4VCI_POST_ISSUANCE + example: OID4VCI_CREDENTIAL_REQUEST - name: role in: query required: false @@ -1504,6 +1504,12 @@ components: application/json: schema: $ref: '#/components/schemas/ErrorResponse' + Forbidden: + description: The caller is authenticated but not authorized for this connector operation. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' NotFound: description: The requested resource was not found. content: @@ -1779,6 +1785,11 @@ components: format: uuid description: Stable identifier for a described external or internal resource shape. example: 41436f49-040c-4f5f-9c7f-657f43762e2b + ConnectorId: + type: string + format: uuid + description: Stable identifier for a connector instance. + example: 5f1b2f49-1397-44a7-bf5e-11340b4777c7 FieldDescriptorId: type: string format: uuid @@ -1834,6 +1845,8 @@ components: type: string description: Extensible connector family identifier. This names the connector implementation or adapter family, not the transport, resource kind, or representation. example: http.openapi + TenantId: + type: string description: Tenant identifier used by tenant-scoped connector registration, routing, and execution. example: acme @@ -1911,6 +1924,7 @@ components: type: string description: Product or protocol lifecycle stage at which a connector invocation can run. enum: + - OID4VCI_START - OID4VCI_AUTHORIZATION - OID4VCI_PRE_AUTHORIZED - OID4VCI_TOKEN @@ -1928,7 +1942,7 @@ components: - FORM_SUBMIT - PORTAL_FLOW - WORKFLOW_STEP_EXECUTION - example: OID4VCI_POST_ISSUANCE + example: OID4VCI_CREDENTIAL_REQUEST ConnectorInvocationRole: type: string description: Role the connector performs for a lifecycle invocation. @@ -3258,21 +3272,21 @@ components: $ref: '#/components/schemas/ConnectorInvocationBinding' example: binding: - invocationBindingId: issuer-config-1:post-issuance:proof-vault + invocationBindingId: issuer-config-1:credential-request:hr-profile ownerSurface: OID4VCI ownerReference: issuer-config-1 - stage: OID4VCI_POST_ISSUANCE - role: VAULT_RETENTION + stage: OID4VCI_CREDENTIAL_REQUEST + role: ENRICHMENT_SOURCE target: routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f - exchangeMode: PLATFORM_INITIATED_PUSH - dataDirection: OUT_OF_VDX + exchangeMode: PLATFORM_INITIATED_PULL + dataDirection: INTO_VDX initiationSide: PLATFORM logicalContext: tenantId: acme organizationUnitId: nl-ops brandId: brand-a - logicalConnectionBindingId: brand-a-proof-vault + logicalConnectionBindingId: brand-a-hr-profile physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b ConnectorInvocationBinding: @@ -3327,21 +3341,21 @@ components: metadata: $ref: '#/components/schemas/StringMap' example: - invocationBindingId: issuer-config-1:post-issuance:proof-vault + invocationBindingId: issuer-config-1:credential-request:hr-profile ownerSurface: OID4VCI ownerReference: issuer-config-1 - stage: OID4VCI_POST_ISSUANCE - role: VAULT_RETENTION + stage: OID4VCI_CREDENTIAL_REQUEST + role: ENRICHMENT_SOURCE target: routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f - exchangeMode: PLATFORM_INITIATED_PUSH - dataDirection: OUT_OF_VDX + exchangeMode: PLATFORM_INITIATED_PULL + dataDirection: INTO_VDX initiationSide: PLATFORM logicalContext: tenantId: acme organizationUnitId: nl-ops brandId: brand-a - logicalConnectionBindingId: brand-a-proof-vault + logicalConnectionBindingId: brand-a-hr-profile physicalConnectorInstanceId: 8a7f09af-7ac9-4d96-91f9-a2a252f4aa4b ConnectorInvocationTarget: @@ -3393,7 +3407,7 @@ components: type: object description: Field selection, lookup, output mapping, provenance, and minimization rules used by an invocation or exposure. properties: - lookupInputs: + inputFields: type: array items: $ref: '#/components/schemas/ConnectorFieldSelector' @@ -3425,7 +3439,7 @@ components: type: string example: min-proof-source example: - lookupInputs: + inputFields: - protocolClaimPath: credential_subject.id selectedFields: - canonicalFieldPath: proof.status @@ -3438,7 +3452,7 @@ components: canonicalFieldPath: type: string example: proof.status - lookupKey: + connectorField: type: string example: employee_id protocolClaimPath: @@ -5165,7 +5179,7 @@ components: description: Request to start a route run. The input object is connector- and route-specific; the route's source binding decides how it is interpreted. properties: input: - description: Optional input payload, lookup keys, or batch reference passed to the route. + description: Optional input payload, connector fields, or batch reference passed to the route. nullable: true example: employee_id: E12345 @@ -5479,30 +5493,6 @@ components: total: 1 totalPages: 1 hasMore: false - description: Page of connector identities. - required: [data, pagination] - properties: - data: - type: array - items: - $ref: '#/components/schemas/ConnectorIdentity' - pagination: - $ref: '#/components/schemas/Page' - example: - data: - - identityId: 3a5cf979-2d89-4057-a721-c7ab884f0c68 - identityRole: external-system - displayName: Workday tenant acme-prod - isDefault: true - identifiers: [] - pagination: - limit: 20 - offset: 0 - page: 0 - size: 20 - total: 1 - totalPages: 1 - hasMore: false ConnectorResourcePage: type: object description: Page of resources attached to connectors. @@ -5654,14 +5644,14 @@ components: $ref: '#/components/schemas/Page' example: data: - - invocationBindingId: issuer-config-1:post-issuance:proof-vault + - invocationBindingId: issuer-config-1:credential-request:hr-profile ownerSurface: OID4VCI ownerReference: issuer-config-1 - stage: OID4VCI_POST_ISSUANCE - role: VAULT_RETENTION + stage: OID4VCI_CREDENTIAL_REQUEST + role: ENRICHMENT_SOURCE target: routeId: 1e8ff011-2274-4f16-a7dd-bf0b4fd5262f - exchangeMode: PLATFORM_INITIATED_PUSH + exchangeMode: PLATFORM_INITIATED_PULL logicalContext: tenantId: acme pagination: @@ -6189,7 +6179,7 @@ components: example: issuer-config-1 stage: type: string - example: OID4VCI_POST_ISSUANCE + example: OID4VCI_CREDENTIAL_REQUEST sessionId: type: string example: protocol-session-1 @@ -6200,6 +6190,152 @@ components: type: string example: protocol-correlation-1 + ConnectorRecordPayload: + type: object + description: Connector record payload. Inline payloads carry a value; reference payloads carry a URI or resource descriptor reference. + properties: + value: + description: Inline payload value. + representationKind: + $ref: '#/components/schemas/RepresentationKind' + contentType: + type: string + example: application/json + uri: + type: string + example: https://hr.example.test/employees/E1042 + resourceDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + contentHash: + type: string + example: sha256:4bf4... + length: + type: integer + format: int64 + example: 4096 + metadata: + type: object + additionalProperties: + type: string + + ConnectorRecord: + type: object + description: Runtime connector record emitted by a source connector or passed to a destination connector. + required: + - recordId + - payload + properties: + recordId: + type: string + example: hr:E1042 + payload: + $ref: '#/components/schemas/ConnectorRecordPayload' + invocationBindingId: + $ref: '#/components/schemas/ConnectorInvocationBindingId' + logicalConnectionBindingId: + $ref: '#/components/schemas/LogicalConnectionBindingId' + physicalConnectorInstanceId: + $ref: '#/components/schemas/ConnectorId' + exchangeMode: + $ref: '#/components/schemas/ConnectorExchangeMode' + governance: + $ref: '#/components/schemas/ConnectorGovernanceEnvelope' + semanticCoordinates: + type: array + items: + type: object + additionalProperties: true + partyAnchors: + $ref: '#/components/schemas/ConnectorPartyAnchorSet' + industrialDiscovery: + type: object + additionalProperties: true + industrialObservation: + type: object + additionalProperties: true + dataspace: + type: object + additionalProperties: true + protocolContext: + $ref: '#/components/schemas/ConnectorProtocolEventContext' + integrity: + $ref: '#/components/schemas/ConnectorIntegrityReference' + cursor: + $ref: '#/components/schemas/ConnectorCursor' + connectorResourceId: + $ref: '#/components/schemas/ConnectorResourceId' + resourceDescriptorId: + $ref: '#/components/schemas/ResourceDescriptorId' + operationBindingId: + $ref: '#/components/schemas/OperationBindingId' + occurredAt: + type: string + format: date-time + metadata: + type: object + additionalProperties: + type: string + + ConnectorWriteStatus: + type: string + description: Aggregate or per-record destination write status. + enum: + - ACCEPTED + - COMMITTED + - DEFERRED + - PARTIAL + - FAILED + example: COMMITTED + + ConnectorRecordWriteOutcome: + type: object + description: Per-record delivery outcome reported by a destination runtime. + required: + - recordId + - status + properties: + recordId: + type: string + example: hr:E1042 + status: + $ref: '#/components/schemas/ConnectorWriteStatus' + metadata: + type: object + additionalProperties: + type: string + + ConnectorWriteResult: + type: object + description: Destination connector write result, including aggregate and optional per-record outcomes. + required: + - status + properties: + status: + $ref: '#/components/schemas/ConnectorWriteStatus' + recordsAccepted: + type: integer + format: int64 + default: 0 + example: 1 + recordsCommitted: + type: integer + format: int64 + default: 0 + example: 1 + externalRunRef: + type: string + example: hr-export-20260705-001 + lastCursor: + $ref: '#/components/schemas/ConnectorCursor' + recordOutcomes: + type: array + items: + $ref: '#/components/schemas/ConnectorRecordWriteOutcome' + metadata: + type: object + additionalProperties: + type: string + ConnectorInvocationRequest: type: object description: Runtime request passed from a protocol, form, portal, or workflow stage into a connector invocation binding. @@ -6254,7 +6390,7 @@ components: subjectCorrelationHandle: type: string example: subject:E-100 - revocationReissueLookupKey: + revocationReissueConnectorField: type: string example: reissue:E-100 selectedFields: @@ -6275,6 +6411,8 @@ components: type: object description: Runtime result emitted by a connector invocation, including produced fields, written records, route lineage, and vault writes. properties: + invocationBindingId: + $ref: '#/components/schemas/ConnectorInvocationBindingId' producedFields: type: object additionalProperties: true @@ -6293,7 +6431,7 @@ components: Oid4vciConnectorPipelineRequest: type: object - description: EDK-neutral OID4VCI connector pipeline request used to run connector-native enrichment, export, or vault-retention bindings. + description: EDK-neutral OID4VCI connector pipeline request used to run connector-native enrichment, export, notification, route, or vault-retention bindings at any issuance stage. required: - protocolContext - initialFields @@ -6316,7 +6454,7 @@ components: Oid4vciConnectorPipelineResult: type: object - description: Result of an OID4VCI connector pipeline run, including accumulated fields and post-issuance vault writes. + description: Result of an OID4VCI connector pipeline run, including accumulated fields, invocation lineage, and vault writes. required: - fields - invocationResults @@ -6341,3 +6479,5 @@ components: example: owner_team: people-ops domain: employee-licensing + + diff --git a/connector-openapi.yml b/connector-openapi.yml index 1396845..92cf746 100644 --- a/connector-openapi.yml +++ b/connector-openapi.yml @@ -698,7 +698,7 @@ paths: description: Filter by product or protocol lifecycle stage. schema: $ref: './connector-components.yml#/components/schemas/ConnectorInvocationStage' - example: OID4VCI_POST_ISSUANCE + example: OID4VCI_CREDENTIAL_REQUEST - name: role in: query required: false diff --git a/credential-design-openapi.yml b/credential-design-openapi.yml index a144a9d..e54602d 100644 --- a/credential-design-openapi.yml +++ b/credential-design-openapi.yml @@ -1287,22 +1287,6 @@ paths: schema: type: string format: binary - image/png: - schema: - type: string - format: binary - image/jpeg: - schema: - type: string - format: binary - image/svg+xml: - schema: - type: string - format: binary - application/pdf: - schema: - type: string - format: binary '401': $ref: './common-components.yml#/components/responses/Unauthorized' '404': diff --git a/docs-groups.json b/docs-groups.json index 5e2c1a7..d4ffa7b 100644 --- a/docs-groups.json +++ b/docs-groups.json @@ -5,7 +5,7 @@ { "key": "verifiable-credentials", "label": "Digital Credentials", "apis": ["oid4vci-issuer", "oid4vci-issuer-session", "oid4vp-universal", "oid4vp-verifier", "credential-design", "dcql", "dcql-edk", "dcql-vdx", "statuslist-hosting", "statuslist-management"] }, { "key": "semantics", "label": "Semantics & Catalog", "apis": ["semantic-model-authoring", "semantic-binding", "semantic-vocabulary"] }, { "key": "parties", "label": "Parties & Accounts", "apis": ["party-manager", "user-manager", "identity-auth"] }, - { "key": "services", "label": "Services", "apis": ["software-manager", "attribute-source", "connector", "resource-manager", "email"] }, + { "key": "services", "label": "Services", "apis": ["software-manager", "connector", "resource-manager", "email"] }, { "key": "platform", "label": "Tenancy & Platform", "apis": ["platform-admin", "platform-setup", "platform-bootstrap", "platform-config", "invitation", "forms"] } ], "labels": { @@ -32,7 +32,6 @@ "user-manager": "User Manager", "resource-manager": "Resource & Booking", "software-manager": "Software / Instance Manager", - "attribute-source": "Attribute Sources", "connector": "Connectors", "platform-admin": "Platform Admin", "platform-setup": "Platform Setup", diff --git a/manifest-catalog.json b/manifest-catalog.json index 9f9a84e..6534f50 100644 --- a/manifest-catalog.json +++ b/manifest-catalog.json @@ -29,7 +29,6 @@ { "division": "vdx", "domain": "party-manager", "specPath": "party-manager-openapi.yml", "ownerModule": "data-store-party-api", "targets": ["edk","vdx"] }, { "division": "vdx", "domain": "license-portal", "specPath": "license-portal-openapi.yaml", "ownerModule": "vdx-service-license-portal", "targets": ["vdx"], "note": "Authenticated license issuer portal API under /api/license-portal/v1 for partners, customers, deployments, imported customer license requests, issuance, protected setup bundles, and license revocation." }, { "division": "vdx", "domain": "identity-manager", "specPath": "identity-manager-openapi.yaml", "ownerModule": "vdx-data-store-identity-rest", "targets": ["vdx"], "note": "Identity and identity identifier management surface under /api/identity/v1." }, - { "division": "vdx", "domain": "attribute-source", "specPath": "attribute-source-openapi.yml", "ownerModule": "data-store-service-rest", "targets": ["vdx"], "note": "VDX REST facade under /api/attribute/source/v1 for canonical EDK attribute-source registry commands." }, { "division": "vdx", "domain": "resource-manager", "specPath": "resource-manager-openapi.yml", "ownerModule": "data-store-resource-api", "targets": ["vdx"] }, { "division": "vdx", "domain": "user-manager", "specPath": "user-manager-openapi.yml", "ownerModule": "data-store-user-api", "targets": ["vdx"] }, { "division": "vdx", "domain": "software-manager", "specPath": "software-manager-openapi.yml", "ownerModule": "data-store-service-api", "targets": ["vdx"], "note": "Software and instance manager surface (generic ServiceInstances + typed AuthorizationServers/Oid4vciIssuers/Oid4vpVerifiers). Served by the VDX service-rest adapters (ServiceInstanceHttpAdapter, AuthorizationServerHttpAdapter, Oid4vciIssuerHttpAdapter, Oid4vpVerifierAdminHttpAdapter) under one base path /api/services/v1. Models are codegen'd by data-store-service-api from this single spec." }, @@ -71,7 +70,6 @@ "credential-design-components.yml", "party-manager-components.yml", "identity-manager-components.yml", - "attribute-source-components.yml", "connector-components.yml", "branding-components.yml", "software-manager-components.yml", diff --git a/oid4vci-issuer-components.yml b/oid4vci-issuer-components.yml index 11559b0..e8b0771 100644 --- a/oid4vci-issuer-components.yml +++ b/oid4vci-issuer-components.yml @@ -4,10 +4,10 @@ info: version: 0.1.0 description: | Entity schemas, enums, and path parameters for the OID4VCI Issuer server-to-server - integration API (offer management and the attribute-provisioning pipeline). Shapes mirror the - backing service-command request and response models. Property names are the wire names: the - pipeline-session request envelopes use snake_case, while the nested attribute and lookup-key - records use camelCase, exactly as serialized by the service. + integration API (offer management and the connector-backed attribute-provisioning pipeline). + Shapes mirror the backing service-command request and response models. Property names are the + wire names: compact OID4VCI endpoint DTOs use camelCase, while command envelopes keep their + explicit snake_case names where declared by the service. paths: {} components: parameters: @@ -27,7 +27,7 @@ components: in: path required: true description: | - Opaque capability token minted by the issuer when an asynchronous attribute source was + Opaque capability token minted by the issuer when an asynchronous connector contributor was dispatched. It authorises an out-of-band contribution to a specific session and is cross-checked against the path correlation id. schema: @@ -43,7 +43,7 @@ components: A single attribute contributed to a pipeline session bag, with full provenance. The bag uses `priority` (then `timestamp`) to decide which record wins for a given `path`. type: object - required: [path, value, sourceId, phase, timestamp] + required: [path, value, producerId, phase, timestamp] properties: path: type: string @@ -53,12 +53,12 @@ components: identity key. value: $ref: '#/components/schemas/AttributeValue' - sourceId: + producerId: type: string - description: Opaque identifier of the source that produced this record. - sourceDetail: + description: Opaque identifier of the connector contributor that produced this record. + producerDetail: type: string - description: Source-specific detail (e.g. an IDV node id, an OIDC issuer, an HR-API endpoint). + description: Contributor-specific detail (e.g. an IDV node id, an OIDC issuer, an HR-API endpoint). phase: type: string description: | @@ -196,49 +196,14 @@ components: type: boolean default: false - LookupKey: + ConnectorFields: description: | - A correlation token a pipeline source uses to look attributes up (e.g. `email`, - `employee_id`, `student_nr`, `business_key`). A lookup key is not an attribute: it is a - key other sources fetch with. Its `value` is PII and is encrypted at rest. + Opaque field inputs for connector invocations. Field names are part of the connector + invocation binding contract; values may be any JSON value and are stored as sensitive + pipeline session data. type: object - required: [name, value, producedBy, phase, timestamp] - properties: - name: - type: string - description: Unique name within the session (e.g. `email`, `employee_id`). - value: - type: string - description: The key value. PII; encrypted at rest. - type: - type: string - description: | - Optional well-known classification. Advisory only; the pipeline keys on `name`. - Common values include `email`, `employee_id`, `student_nr`, `business_key`, `phone`, - and `did`. - producedBy: - type: string - description: Provenance only. The single source that produced this lookup key. - sourceDetail: - type: string - description: Source-specific detail (e.g. an IDV node id, an HR-API endpoint). - phase: - type: string - description: The pipeline phase during which this key was contributed. - timestamp: - type: string - format: date-time - description: When this key was contributed. - promotedToAttributePath: - type: string - description: | - If present, the lookup key is also emitted as an attribute at this path before - credential assembly. Leave absent when the key is purely operational and should not - appear in the credential. - metadata: - type: object - additionalProperties: - type: string + additionalProperties: + description: Any JSON value (string, number, boolean, object, array, null). # --------------------------------------------------------------------------- # Pipeline configuration (init-session request). @@ -246,25 +211,26 @@ components: PipelineConfiguration: description: | - A registered pipeline: the ordered attribute-source bindings that feed it, the - credential-claims bindings it can assemble, and the lookup keys the caller is expected to - supply at session init. `sourceBindings` and `claimsBindings` are issuer-side wiring - structures; integration callers usually reference an already-registered pipeline by its - `pipelineId` and leave the binding lists empty. + A registered pipeline: the connector invocation bindings that can run at each issuance + phase, the credential-claims bindings it can assemble, and the connector fields the caller is + expected to supply at session init. `invocationBindings` and `claimsBindings` are + issuer-side wiring structures; integration callers usually reference an already-registered + pipeline by its `pipelineId` and leave the binding lists empty. type: object required: [pipelineId] properties: pipelineId: type: string description: Stable identifier of the pipeline this session runs. - sourceBindings: + invocationBindings: type: array description: | - The attribute sources bound into this pipeline, each with its phases and binding - config. An issuer-side wiring structure; modelled here as opaque objects. + Connector invocation bindings bound into this pipeline. Each binding declares the + owner surface, owner reference, issuance stage, role, execution policy, target route or + operation, subset mapping, and protocol/governance context for connector-native + execution across the issuance lifecycle. items: - type: object - additionalProperties: true + $ref: './connector-components.yml#/components/schemas/ConnectorInvocationBinding' claimsBindings: type: array description: | @@ -273,13 +239,211 @@ components: items: type: object additionalProperties: true - expectedInitialLookupKeys: + expectedInitialConnectorFields: type: array description: | - Names of lookup keys the caller is expected to provide at session init. A source may - consume one of these without any other source producing it. + Names of connector fields the caller is expected to provide at session init. A connector + invocation may consume one of these without any earlier invocation producing it. + items: + type: string + + CompactRetentionPolicy: + description: | + Retention override used by compact OID4VCI provisioning bodies. The compact wire shape uses + `kind` as discriminator. + oneOf: + - $ref: '#/components/schemas/CompactEphemeralRetention' + - $ref: '#/components/schemas/CompactSessionRetention' + - $ref: '#/components/schemas/CompactRetainedRetention' + discriminator: + propertyName: kind + mapping: + ephemeral: '#/components/schemas/CompactEphemeralRetention' + session: '#/components/schemas/CompactSessionRetention' + retained: '#/components/schemas/CompactRetainedRetention' + + CompactEphemeralRetention: + type: object + required: [kind] + properties: + kind: + type: string + enum: [ephemeral] + + CompactSessionRetention: + type: object + required: [kind] + properties: + kind: + type: string + enum: [session] + encryptionRequired: + type: boolean + + CompactRetainedRetention: + type: object + required: [kind, retentionDays, legalBasis] + properties: + kind: + type: string + enum: [retained] + retentionDays: + type: integer + legalBasis: + type: string + regulatoryFramework: + type: string + territoryId: + type: string + territoryRestriction: + type: string + encryptionRequired: + type: boolean + purpose: + type: string + consentObtained: + type: boolean + + SemanticSetAttributeItem: + type: object + required: [term, value] + properties: + term: + type: string + value: + description: Any JSON value. + retention: + $ref: '#/components/schemas/CompactRetentionPolicy' + priority: + type: integer + assurance: + type: string + enum: [low, substantial, high] + verified: + type: boolean + contributorDetail: + type: string + sdPolicy: + type: string + + SemanticSetEntry: + type: object + required: [bundleId] + properties: + bundleId: + type: string + version: + type: string + retention: + $ref: '#/components/schemas/CompactRetentionPolicy' + values: + type: object + additionalProperties: + description: Any JSON value keyed by semantic term. + attributes: + type: array + items: + $ref: '#/components/schemas/SemanticSetAttributeItem' + + RawAttributeItem: + type: object + required: [path, value] + properties: + path: + type: string + value: + description: Any JSON value. + retention: + $ref: '#/components/schemas/CompactRetentionPolicy' + priority: + type: integer + assurance: + type: string + enum: [low, substantial, high] + verified: + type: boolean + contributorDetail: + type: string + sdPolicy: + type: string + + AttributeProvisionGroup: + type: object + required: [contributorId, phase] + description: | + Compact provisioning group carrying one provenance pair plus attributes and connector + fields for any OID4VCI lifecycle phase. + properties: + contributorId: + type: string + description: Opaque contributor id for records created from this group. + phase: + type: string + description: Pipeline phase string attached to records created from this group. + timestamp: + type: string + format: date-time + contributorDetail: + type: string + retention: + $ref: '#/components/schemas/CompactRetentionPolicy' + semanticAttributeSets: + type: array + items: + $ref: '#/components/schemas/SemanticSetEntry' + attributes: + type: array + items: + $ref: '#/components/schemas/RawAttributeItem' + connectorFields: + $ref: '#/components/schemas/ConnectorFields' + + ContributeAttributesCompactRequestBody: + type: object + properties: + groups: + type: array + items: + $ref: '#/components/schemas/AttributeProvisionGroup' + + CreateOfferRequestBody: + type: object + required: [issuerId] + properties: + issuerId: + type: string + credentialConfigurationIds: + type: array items: type: string + preAuthorizedCodeGrant: + type: boolean + default: false + authorizationCodeGrant: + type: boolean + default: false + txCodeRequired: + type: boolean + default: false + offerTtlSeconds: + type: integer + format: int64 + default: 600 + boundUsageToken: + type: string + postIssuanceHookAllowList: + type: array + items: + type: string + scheme: + type: string + uriLifecycle: + type: string + enum: [SINGLE_USE, REUSABLE_FRESH_PER_FETCH] + preSeededGroups: + type: array + items: + $ref: '#/components/schemas/AttributeProvisionGroup' # --------------------------------------------------------------------------- # Pipeline request bodies. @@ -288,7 +452,7 @@ components: InitPipelineSessionRequestBody: description: | Allocates a new issuance pipeline session for a registered pipeline configuration, - optionally seeded with attributes and lookup keys known up front. No phase runs here; the + optionally seeded with attributes and connector fields known up front. No phase runs here; the caller drives phases afterwards via the contribute endpoint. type: object required: [pipeline_configuration] @@ -302,10 +466,8 @@ components: type: array items: $ref: '#/components/schemas/AttributeRecord' - initial_lookup_keys: - type: array - items: - $ref: '#/components/schemas/LookupKey' + initial_connector_fields: + $ref: '#/components/schemas/ConnectorFields' ttl_seconds: type: integer format: int64 @@ -324,33 +486,25 @@ components: ContributeAttributesRequestBody: description: | - Pushes attributes and lookup keys into an active session as input for the - credential-request phase. The session is identified by the path correlation id. + Compact contribution payload. Each group carries one contributor/phase provenance pair, + optional semantic-set values, raw attributes, and connector fields. type: object properties: - attributes: - type: array - items: - $ref: '#/components/schemas/AttributeRecord' - lookup_keys: + groups: type: array items: - $ref: '#/components/schemas/LookupKey' + $ref: '#/components/schemas/AttributeProvisionGroup' ContributeViaCallbackRequestBody: description: | - Identical payload to the contribute request, fed into the pipeline as a deferred - contribution. Used by the asynchronous-callback endpoint. + Compact callback contribution payload. It has the same shape as direct contribution and is + fed into the pipeline as a deferred contribution. type: object properties: - attributes: - type: array - items: - $ref: '#/components/schemas/AttributeRecord' - lookup_keys: + groups: type: array items: - $ref: '#/components/schemas/LookupKey' + $ref: '#/components/schemas/AttributeProvisionGroup' ContributeAttributesResult: description: The session state after the contributing phase ran. @@ -397,29 +551,29 @@ components: type: string enum: [APPROVE, REJECT] - FailPipelineSourceRequestBody: + RecordPipelineContributorFailureRequestBody: description: | - Marks a single attribute source's contribution as failed. Recorded on the session so a - later completeness evaluation can treat an unsatisfied required source as a hard miss + Marks a single connector contributor's contribution as failed. Recorded on the session so a + later completeness evaluation can treat an unsatisfied required contributor as a hard miss rather than waiting indefinitely. type: object - required: [source_id] + required: [contributor_id] properties: - source_id: + contributor_id: type: string - description: The opaque source identifier whose contribution failed. + description: The opaque contributor identifier whose contribution failed. reason: type: string description: Optional human-readable reason recorded with the failure marker. - FailPipelineSourceResult: - description: The session correlation id and the source id that was marked as failed. + RecordPipelineContributorFailureResult: + description: The session correlation id and the contributor id that was marked as failed. type: object - required: [correlationId, sourceId] + required: [correlationId, contributorId] properties: correlationId: type: string - sourceId: + contributorId: type: string EvaluateAttributeCompletenessResult: @@ -465,10 +619,10 @@ components: GetSessionAttributesResult: description: | - The attributes accumulated in a session bag, plus the names of any lookup keys promoted to - an attribute path. Lookup-key values are PII and are never returned over this API. + The attributes accumulated in a session bag, plus the names of connector fields stored on + the session. Connector field values are sensitive and are never returned over this API. type: object - required: [attributes, promotedLookupKeyNames] + required: [attributes, connectorFieldNames] properties: attributes: type: object @@ -478,11 +632,10 @@ components: are omitted. additionalProperties: description: Any JSON value (string, number, boolean, object, array, null). - promotedLookupKeyNames: + connectorFieldNames: type: array description: | - Names of lookup keys that will be emitted as attributes during credential assembly. - The key values are omitted because they are PII. + Names of connector fields currently present on the session. Values are omitted. items: type: string diff --git a/oid4vci-issuer-openapi.yaml b/oid4vci-issuer-openapi.yaml index e29feb6..c43b6b7 100644 --- a/oid4vci-issuer-openapi.yaml +++ b/oid4vci-issuer-openapi.yaml @@ -17,14 +17,14 @@ info: With the pipeline endpoints a backend resolves the attributes for an issuance: - initialise a pipeline session for a registered pipeline configuration, optionally seeded - with attributes and lookup keys known up front; - - contribute attributes from one or more sources, each carrying provenance (the producing - source, the phase, the time of capture, assurance, and a retention policy); + with attributes and connector fields known up front; + - contribute attributes from one or more connector contributors, each carrying provenance (the + contributor, the phase, the time of capture, assurance, and a retention policy); - read back the attributes accumulated so far; - evaluate completeness against the credential's requirements, getting a verdict per binding; - - approve or fail a session that is gated on an approval decision or on a source that could + - approve or fail a session that is gated on an approval decision or on a contributor that could not deliver; - - contribute asynchronously through a callback, for sources that answer out of band after the + - contribute asynchronously through a callback, for contributors that answer out of band after the synchronous credential window has closed. This is a backend integration surface for confidential issuer systems, not a browser or wallet @@ -97,7 +97,7 @@ paths: summary: Initialise an issuance pipeline session description: | Allocates a new issuance pipeline session for a registered pipeline configuration, - optionally seeded with attributes and lookup keys known at init time. No phase runs here; + optionally seeded with attributes and connector fields known at init time. No phase runs here; this only opens the session. Drive phases afterwards with the contribute endpoint. The response returns the session id and the resolved correlation handle. operationId: initPipelineSession @@ -112,15 +112,11 @@ paths: example: pipeline_configuration: pipelineId: pid-issuance - expectedInitialLookupKeys: + expectedInitialConnectorFields: - employee_id correlation_id: order-2026-000931 - initial_lookup_keys: - - name: employee_id - value: E1042 - producedBy: hr-backend - phase: session_init - timestamp: '2026-06-07T10:15:00Z' + initial_connector_fields: + employee_id: E1042 ttl_seconds: 600 responses: '200': @@ -143,8 +139,8 @@ paths: summary: Read accumulated session attributes description: | Returns the attribute values accumulated in the session bag, keyed by attribute path, - plus the names of any lookup keys promoted to an attribute path. Lookup-key values are PII - and are never returned over this API. + plus the names of any connector fields present on the session. Connector-field values are + sensitive and are never returned over this API. operationId: getSessionAttributes security: - bearerAuth: [] @@ -162,7 +158,7 @@ paths: given_name: Alice family_name: Smith birth_date: '1990-04-01' - promotedLookupKeyNames: + connectorFieldNames: - email '401': $ref: '#/components/responses/Unauthorized' @@ -172,10 +168,10 @@ paths: tags: [Pipeline] summary: Contribute attributes to a session description: | - Pushes attributes and lookup keys into an active session as input for the + Pushes compact attribute groups and connector fields into an active session as input for the credential-request phase. The session is identified by the path correlation id; the - attributes and lookup keys come from the body. Each record carries provenance: the - producing source, the phase, the capture time, an optional assurance level, a + attributes and connector fields come from the body. Each record carries provenance: the + producing contributor, the phase, the capture time, an optional assurance level, a conflict-resolution priority, and a retention policy. operationId: contributeAttributes security: @@ -189,30 +185,18 @@ paths: schema: $ref: '#/components/schemas/ContributeAttributesRequestBody' example: - attributes: - - path: given_name - value: - type: data - value: Alice - sourceId: hr-backend + groups: + - contributorId: hr-backend phase: oid4vci_credential_request timestamp: '2026-06-07T10:16:00Z' - verified: true - - path: family_name - value: - type: data - value: Smith - sourceId: hr-backend - phase: oid4vci_credential_request - timestamp: '2026-06-07T10:16:00Z' - lookup_keys: - - name: email - value: alice@acme.io - type: email - producedBy: hr-backend - phase: oid4vci_credential_request - timestamp: '2026-06-07T10:16:00Z' - promotedToAttributePath: email + attributes: + - path: given_name + value: Alice + verified: true + - path: family_name + value: Smith + connectorFields: + email: alice@acme.io responses: '200': description: Contribution accepted; session state after the phase ran. @@ -309,12 +293,12 @@ paths: /api/oid4vci/v1/backend/sessions/{correlationId}/fail: post: tags: [Pipeline] - summary: Mark a source's contribution as failed + summary: Mark a contributor's contribution as failed description: | - Records that a single attribute source could not deliver its contribution to the session. - A later completeness evaluation can then treat an unsatisfied required source as a hard + Records that a single connector contributor could not deliver its contribution to the session. + A later completeness evaluation can then treat an unsatisfied required contributor as a hard miss rather than waiting indefinitely. - operationId: failPipelineSource + operationId: recordPipelineContributorFailure security: - bearerAuth: [] parameters: @@ -324,9 +308,9 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/FailPipelineSourceRequestBody' + $ref: '#/components/schemas/RecordPipelineContributorFailureRequestBody' example: - source_id: hr-backend + contributor_id: hr-backend reason: HR API returned 503 after retries. responses: '200': @@ -334,10 +318,10 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/FailPipelineSourceResult' + $ref: '#/components/schemas/RecordPipelineContributorFailureResult' example: correlationId: order-2026-000931 - sourceId: hr-backend + contributorId: hr-backend '401': $ref: '#/components/responses/Unauthorized' '400': @@ -350,8 +334,8 @@ paths: tags: [Pipeline] summary: Contribute attributes via an asynchronous callback description: | - Inbound contribution endpoint for an attribute source that answers out of band. The - callback token is the opaque capability artefact minted by the issuer when the source was + Inbound contribution endpoint for a connector contributor that answers out of band. The + callback token is the opaque capability artefact minted by the issuer when the contributor was dispatched; it is validated and cross-checked against the path correlation id. The body is fed into the pipeline as a deferred contribution. Authorisation is carried by the callback token in the path, so this endpoint does not require a bearer token. @@ -367,16 +351,15 @@ paths: schema: $ref: '#/components/schemas/ContributeViaCallbackRequestBody' example: - attributes: - - path: birth_date - value: - type: data - value: '1990-04-01' - sourceId: idv-provider + groups: + - contributorId: idv-provider phase: oid4vci_deferred timestamp: '2026-06-07T11:02:00Z' - assurance: high - verified: true + attributes: + - path: birth_date + value: '1990-04-01' + assurance: high + verified: true responses: '200': description: Contribution accepted; session state after the deferred phase ran. @@ -450,8 +433,8 @@ components: $ref: './oid4vci-issuer-components.yml#/components/schemas/SessionRetention' RetainedRetention: $ref: './oid4vci-issuer-components.yml#/components/schemas/RetainedRetention' - LookupKey: - $ref: './oid4vci-issuer-components.yml#/components/schemas/LookupKey' + ConnectorFields: + $ref: './oid4vci-issuer-components.yml#/components/schemas/ConnectorFields' PipelineConfiguration: $ref: './oid4vci-issuer-components.yml#/components/schemas/PipelineConfiguration' InitPipelineSessionRequestBody: @@ -462,6 +445,20 @@ components: $ref: './oid4vci-issuer-components.yml#/components/schemas/ContributeAttributesRequestBody' ContributeViaCallbackRequestBody: $ref: './oid4vci-issuer-components.yml#/components/schemas/ContributeViaCallbackRequestBody' + ContributeAttributesCompactRequestBody: + $ref: './oid4vci-issuer-components.yml#/components/schemas/ContributeAttributesCompactRequestBody' + AttributeProvisionGroup: + $ref: './oid4vci-issuer-components.yml#/components/schemas/AttributeProvisionGroup' + SemanticSetEntry: + $ref: './oid4vci-issuer-components.yml#/components/schemas/SemanticSetEntry' + SemanticSetAttributeItem: + $ref: './oid4vci-issuer-components.yml#/components/schemas/SemanticSetAttributeItem' + RawAttributeItem: + $ref: './oid4vci-issuer-components.yml#/components/schemas/RawAttributeItem' + CompactRetentionPolicy: + $ref: './oid4vci-issuer-components.yml#/components/schemas/CompactRetentionPolicy' + CreateOfferRequestBody: + $ref: './oid4vci-issuer-components.yml#/components/schemas/CreateOfferRequestBody' ContributeAttributesResult: $ref: './oid4vci-issuer-components.yml#/components/schemas/ContributeAttributesResult' ApprovePipelineSessionRequestBody: @@ -470,10 +467,10 @@ components: $ref: './oid4vci-issuer-components.yml#/components/schemas/ApprovePipelineSessionResult' ApprovalDecision: $ref: './oid4vci-issuer-components.yml#/components/schemas/ApprovalDecision' - FailPipelineSourceRequestBody: - $ref: './oid4vci-issuer-components.yml#/components/schemas/FailPipelineSourceRequestBody' - FailPipelineSourceResult: - $ref: './oid4vci-issuer-components.yml#/components/schemas/FailPipelineSourceResult' + RecordPipelineContributorFailureRequestBody: + $ref: './oid4vci-issuer-components.yml#/components/schemas/RecordPipelineContributorFailureRequestBody' + RecordPipelineContributorFailureResult: + $ref: './oid4vci-issuer-components.yml#/components/schemas/RecordPipelineContributorFailureResult' EvaluateAttributeCompletenessResult: $ref: './oid4vci-issuer-components.yml#/components/schemas/EvaluateAttributeCompletenessResult' BindingCompletenessVerdict: diff --git a/oid4vci-issuer-session-components.yml b/oid4vci-issuer-session-components.yml index 55cbbf9..4987c78 100644 --- a/oid4vci-issuer-session-components.yml +++ b/oid4vci-issuer-session-components.yml @@ -65,13 +65,6 @@ components: description: Session time-to-live in seconds. uri_lifecycle: $ref: '#/components/schemas/OfferUriLifecycle' - initial_lookup_keys: - type: array - description: | - Lookup keys seeded into the pipeline session at offer-creation time so attribute - sources can start resolving subject data before the wallet presents a proof. - items: - $ref: '#/components/schemas/LookupKey' rate_limit: $ref: '#/components/schemas/OfferRateLimit' @@ -216,51 +209,6 @@ components: format: int64 description: Length of the rolling time window in seconds. - LookupKey: - type: object - description: | - A correlation token a pipeline source uses to look attributes up, an `email`, - `employee_id`, `student_nr`, `business_key`, etc. A lookup key is not an attribute; it is a - key other sources fetch with, and it may or may not be promoted into the final credential. - required: [name, value, produced_by, phase, timestamp] - properties: - name: - type: string - description: Unique name within the session, e.g. `email`, `employee_id`. - example: employee_id - value: - type: string - description: The key value. PII; encrypted at rest. - type: - type: string - description: Optional well-known classification of the key (e.g. `email`, `employee_id`). - produced_by: - type: string - description: | - Provenance only: the single source that produced this lookup key (one producer, one - phase, one timestamp). Not the source(s) that consume it. - source_detail: - type: string - description: Source-specific detail (e.g. IDV node id, HR-API endpoint). - phase: - type: string - description: The pipeline phase during which this key was contributed. - example: session_init - timestamp: - type: string - format: date-time - description: When this key was contributed. - promoted_to_attribute_path: - type: string - description: | - If set, the lookup key is also emitted as an attribute at this path before credential - assembly, so claim mapping can pick it up. Leave unset when the key is purely operational. - metadata: - type: object - additionalProperties: - type: string - description: Free-form metadata; e.g. verification status, source TTL. - CreateCredentialOfferOutput: type: object description: Response body for a successful credential-offer creation. diff --git a/oid4vci-issuer-session-openapi.yml b/oid4vci-issuer-session-openapi.yml index 9236c20..363ec7f 100644 --- a/oid4vci-issuer-session-openapi.yml +++ b/oid4vci-issuer-session-openapi.yml @@ -260,9 +260,6 @@ components: OfferRateLimit: $ref: './oid4vci-issuer-session-components.yml#/components/schemas/OfferRateLimit' - LookupKey: - $ref: './oid4vci-issuer-session-components.yml#/components/schemas/LookupKey' - CredentialOfferSessionStatus: $ref: './oid4vci-issuer-session-components.yml#/components/schemas/CredentialOfferSessionStatus' diff --git a/platform-admin-components.yml b/platform-admin-components.yml index 6448d50..81b4d52 100644 --- a/platform-admin-components.yml +++ b/platform-admin-components.yml @@ -676,7 +676,7 @@ components: readiness (email transport, secret backend, application tenant). Reason strings follow a stable `_` convention, for example `license_missing_self_signup` or `config_disabled_self_signup`. - required: [applicationTenant, rootTenantCreation, adminInvite, selfSignup, subtenants, email, secretBackend] + required: [applicationTenant, rootTenantCreation, adminInvite, selfSignup, subtenants, email, password, secretBackend] properties: applicationTenant: $ref: '#/components/schemas/AvailabilityApplicationTenant' @@ -690,6 +690,8 @@ components: $ref: '#/components/schemas/AvailabilityDecision' email: $ref: '#/components/schemas/AvailabilityEmail' + password: + $ref: '#/components/schemas/AvailabilityPassword' secretBackend: $ref: '#/components/schemas/AvailabilitySecretBackend' example: @@ -711,6 +713,9 @@ components: email: configured: true healthy: true + password: + configured: false + healthy: false secretBackend: configured: true AvailabilityApplicationTenant: @@ -756,6 +761,20 @@ components: example: configured: true healthy: true + AvailabilityPassword: + type: object + description: Owner/admin password-delivery readiness inputs to the availability evaluation. + required: [configured, healthy] + properties: + configured: + type: boolean + description: True when generated/operator password delivery is backed by a credential writer. + healthy: + type: boolean + description: True when the configured credential writer passes its readiness probe. + example: + configured: false + healthy: false AvailabilitySecretBackend: type: object description: Secret-backend readiness input to the availability evaluation. @@ -1080,12 +1099,11 @@ components: TenantRegistrationStep: type: object description: > - Identifier for a single registration step. The set is open - the platform - defines standard side-effect steps (`routing-inserted`, - `isolation-provisioned`, `tenant-schemas-ensured`, `user-schema-ensured`, - `as-provisioned`, `issuer-provisioned`, `owner-provisioned`, - `owner-invitation-minted`) and higher layers mint additional stable - kebab-case identifiers. + Identifier for a single registration step. The set is open. Standard + side-effect steps include routing/isolation, tenant schemas, default + authorization server and key-store binding, organization/contact + materialization, owner account provisioning, issuer/verifier endpoints, + keys/DIDs, sample data, and invitation or password delivery. required: [id] properties: id: @@ -1119,14 +1137,15 @@ components: OwnerDeliveryMode: type: string description: > - How the owner invitation is delivered. `none` mints the invitation without - sending it. `email` sends the invitation through the configured email - transport. `manual` is not accepted through this API. - enum: [none, email, manual] + How the owner account setup is delivered. `email` sends an invite through + the configured email transport. `generated_password` and + `operator_password` require a credential writer binding. `none` prepares + the owner account without external delivery. + enum: [email, generated_password, operator_password, none] example: email OwnerDeliveryStatus: type: string - description: Result of the owner invitation delivery attempt. + description: Result of the owner account delivery attempt. enum: [NOT_REQUESTED, SENT, MANUAL_READY, SKIPPED] example: SENT SignupEmailDeliveryStatus: diff --git a/platform-admin-openapi.yaml b/platform-admin-openapi.yaml index 4ab2514..d59b68b 100644 --- a/platform-admin-openapi.yaml +++ b/platform-admin-openapi.yaml @@ -421,9 +421,9 @@ paths: tags: [Tenants] summary: Register a tenant description: | - Registers a tenant with a default authorization server and an owner - bootstrap. The owner is supplied as local contact details; choose how the - owner invitation is delivered with `ownerDelivery.mode`. + Registers an organization tenant with required natural-person contacts, + a mandatory default authorization server and key store, optional issuer + and verifier surfaces, and owner/admin account delivery. operationId: registerTenant requestBody: required: true @@ -432,18 +432,35 @@ paths: schema: $ref: '#/components/schemas/RegisterTenantRequest' example: - tenantType: organization - name: Acme Corporation - description: Acme issuing and verification tenant - slug: acme - parentTenantId: null - initialPlatformSubdomain: true - owner: - type: local - email: admin@acme.example - displayName: Acme Administrator - ownerDelivery: - mode: email + tenant: + tenantType: organization + name: Acme Corporation + description: Acme issuing and verification tenant + slug: acme + parentTenantId: null + initialPlatformSubdomain: true + contacts: + technical: + email: tech@acme.example + displayName: Acme Technical Contact + administrativeSameAsTechnical: false + administrative: + email: admin-office@acme.example + displayName: Acme Administrative Contact + ownerAdmin: + source: new + person: + email: owner@acme.example + displayName: Acme Owner + login: + enabled: true + deliveryMode: email + defaultAuthorizationServerRequired: true + provisioning: + issuer: true + verifier: true + keysAndDids: true + sampleData: true responses: '201': description: Tenant registered. @@ -468,15 +485,27 @@ paths: updatedById: null deletedAt: null deletedById: null - primaryDomainUrl: https://acme.wallet.platform.example - issuerUrl: https://acme.wallet.platform.example/acme/oid4vci - ownerUserId: 2c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4b + tenantUrl: https://acme.wallet.platform.example + serviceUrls: + authorizationServerUrl: https://acme.wallet.platform.example + issuerUrl: https://acme.wallet.platform.example + oid4vciIssuerUrl: https://acme.wallet.platform.example + oid4vpVerifierUrl: https://acme.wallet.platform.example correlationId: reg-acme-7f12a7c4 - ownerDelivery: + created: + ownerPartyId: 2c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4b + technicalContactPartyId: 3c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4c + administrativeContactPartyId: 4c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4d + ownerAdminPartyId: 5c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4e + ownerAccountId: 6c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4f + ownerIdentityId: 7c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a40 + relationshipIds: [8c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a41] + delivery: mode: email status: SENT deliveryId: del-7f12a7c4 providerMessageId: msg-001 + oneTimeCredentials: null '400': $ref: '#/components/responses/ValidationError' '401': @@ -1125,11 +1154,18 @@ paths: updatedById: null deletedAt: null deletedById: null - primaryDomainUrl: https://acme.wallet.platform.example - issuerUrl: https://acme.wallet.platform.example/acme/oid4vci - ownerUserId: 2c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4b + tenantUrl: https://acme.wallet.platform.example + serviceUrls: + authorizationServerUrl: https://acme.wallet.platform.example + issuerUrl: https://acme.wallet.platform.example + oid4vciIssuerUrl: https://acme.wallet.platform.example + oid4vpVerifierUrl: https://acme.wallet.platform.example correlationId: reg-acme-7f12a7c4 - ownerDelivery: + created: + ownerPartyId: 2c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4b + ownerAccountId: 6c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4f + relationshipIds: [] + delivery: mode: none status: NOT_REQUESTED deliveryId: null @@ -1735,12 +1771,56 @@ components: # ---- Tenants request/response bodies (inline) ---- RegisterTenantRequest: type: object - description: Tenant registration request. The owner is supplied as local contact details. - required: [tenantType, name, slug, owner] + description: Tenant onboarding request for provisioning an organization tenant and its required natural-person contacts. + required: [tenant, contacts] + properties: + tenant: + $ref: '#/components/schemas/RegisterTenantSection' + contacts: + $ref: '#/components/schemas/TenantOnboardingContacts' + login: + $ref: '#/components/schemas/TenantOnboardingLogin' + provisioning: + $ref: '#/components/schemas/TenantOnboardingProvisioning' + example: + tenant: + tenantType: organization + name: Acme Corporation + description: Acme issuing and verification tenant + slug: acme + parentTenantId: null + initialPlatformSubdomain: true + contacts: + technical: + email: tech@acme.example + displayName: Acme Technical Contact + administrativeSameAsTechnical: false + administrative: + email: admin-office@acme.example + displayName: Acme Administrative Contact + ownerAdmin: + source: new + person: + email: owner@acme.example + displayName: Acme Owner + login: + enabled: true + deliveryMode: email + defaultAuthorizationServerRequired: true + provisioning: + issuer: true + verifier: true + keysAndDids: true + sampleData: true + RegisterTenantSection: + type: object + description: Organization tenant identity and routing input. + required: [name, slug] properties: tenantType: type: string - description: Open tenant type label. + default: organization + description: Open tenant type label. Defaults to organization onboarding. name: type: string description: Human-readable tenant name. @@ -1751,7 +1831,7 @@ components: slug: type: string pattern: '^[a-z][a-z0-9-]{0,62}$' - description: Globally unique URL-safe slug. + description: Globally unique URL-safe subdomain slug. parentTenantId: type: string nullable: true @@ -1760,91 +1840,121 @@ components: type: string format: uuid nullable: true - description: Existing party id to use as the owner, when provided. + description: Existing party id to use as the tenant owner reference, when provided. initialPlatformSubdomain: type: boolean default: true description: Whether to auto-create the platform subdomain at registration. - addIssuer: + TenantOnboardingContacts: + type: object + description: Required natural-person contacts and owner/admin selection for the tenant organization. + required: [technical, ownerAdmin] + properties: + technical: + $ref: '#/components/schemas/TenantOnboardingPerson' + administrative: + allOf: + - $ref: '#/components/schemas/TenantOnboardingPerson' + nullable: true + administrativeSameAsTechnical: + type: boolean + default: false + ownerAdmin: + $ref: '#/components/schemas/TenantOnboardingOwnerAdmin' + TenantOnboardingPerson: + type: object + description: Natural-person contact input. + required: [email, displayName] + properties: + email: + type: string + format: email + displayName: + type: string + givenName: + type: string + nullable: true + familyName: + type: string + nullable: true + phone: + type: string + nullable: true + existingPartyId: + type: string + format: uuid + nullable: true + description: Reuse an existing natural-person party instead of creating one. + TenantOnboardingOwnerAdmin: + type: object + required: [source] + properties: + source: + $ref: '#/components/schemas/TenantOnboardingOwnerAdminSource' + person: + allOf: + - $ref: '#/components/schemas/TenantOnboardingPerson' + nullable: true + description: Required when source is new. + TenantOnboardingOwnerAdminSource: + type: string + enum: [technical, administrative, new] + default: new + TenantOnboardingLogin: + type: object + properties: + enabled: type: boolean default: true - description: > - When true, also provision a default OID4VCI credential issuer for the - tenant. The authorization server and key store are always provisioned. - addVerifier: + deliveryMode: + $ref: '#/components/schemas/OwnerDeliveryMode' + defaultAuthorizationServerRequired: type: boolean default: true - description: > - When true, also provision a default OID4VP presentation verifier for - the tenant. The authorization server and key store are always - provisioned. - owner: - $ref: '#/components/schemas/LocalOwnerInput' - ownerDelivery: - $ref: '#/components/schemas/OwnerDeliveryRequest' - example: - tenantType: organization - name: Acme Corporation - description: Acme issuing and verification tenant - slug: acme - parentTenantId: null - initialPlatformSubdomain: true - addIssuer: true - addVerifier: true - owner: - type: local - email: admin@acme.example - displayName: Acme Administrator - ownerDelivery: - mode: email - OwnerDeliveryRequest: + description: Must stay true; tenant onboarding always provisions the default authorization server. + operatorPassword: + type: string + nullable: true + description: Explicit operator-entered temporary password for operator_password mode. + TenantOnboardingProvisioning: type: object - description: How to deliver the owner invitation. properties: - mode: - allOf: - - $ref: '#/components/schemas/OwnerDeliveryMode' - default: none - description: > - Delivery mode. `none` mints the invitation without sending it; `email` - sends it through the configured email transport. `manual` is not - accepted and is rejected with a `403`. - example: - mode: email + issuer: + type: boolean + default: true + verifier: + type: boolean + default: true + keysAndDids: + type: boolean + default: true + sampleData: + type: boolean + default: true RegisterTenantResponse: type: object - description: Result of registering a tenant, including the owner-delivery outcome. - required: [tenant, primaryDomainUrl, ownerUserId, correlationId, ownerDelivery] + description: Result of registering and provisioning a tenant. + required: [tenant, tenantUrl, serviceUrls, correlationId, created, delivery] properties: tenant: $ref: '#/components/schemas/Tenant' - primaryDomainUrl: + tenantUrl: type: string format: uri description: Primary reachable URL for the tenant. - issuerUrl: - type: string - format: uri - nullable: true - description: Issuer URL of the default authorization server, when provisioned. - oid4vciIssuerUrl: - type: string - format: uri - nullable: true - description: OID4VCI credential-issuer URL; null when no issuer was provisioned. - oid4vpVerifierUrl: - type: string - format: uri - nullable: true - description: OID4VP verifier URL; null when no verifier was provisioned. - ownerUserId: - type: string - description: Identifier of the created owner user. + serviceUrls: + $ref: '#/components/schemas/TenantOnboardingServiceUrls' correlationId: type: string description: Durable registration-log id for polling onboarding status. - ownerDelivery: + created: + $ref: '#/components/schemas/TenantOnboardingCreatedRefs' + delivery: $ref: '#/components/schemas/OwnerDeliveryResponse' + oneTimeCredentials: + allOf: + - $ref: '#/components/schemas/OneTimeCredentials' + nullable: true example: tenant: id: 7b3c2d9e-1f4a-4c8b-9e2d-5a6f7c8b9d01 @@ -1862,20 +1972,89 @@ components: updatedById: null deletedAt: null deletedById: null - primaryDomainUrl: https://acme.wallet.platform.example - issuerUrl: https://acme.wallet.platform.example/acme/oid4vci - oid4vciIssuerUrl: https://acme.wallet.platform.example/acme/oid4vci - oid4vpVerifierUrl: https://acme.wallet.platform.example/acme/oid4vp - ownerUserId: 2c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4b + tenantUrl: https://acme.wallet.platform.example + serviceUrls: + authorizationServerUrl: https://acme.wallet.platform.example + issuerUrl: https://acme.wallet.platform.example + oid4vciIssuerUrl: https://acme.wallet.platform.example + oid4vpVerifierUrl: https://acme.wallet.platform.example correlationId: reg-acme-7f12a7c4 - ownerDelivery: + created: + ownerPartyId: 2c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4b + technicalContactPartyId: 3c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4c + administrativeContactPartyId: 4c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4d + ownerAdminPartyId: 5c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4e + ownerAccountId: 6c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4f + ownerIdentityId: 7c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a40 + relationshipIds: [8c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a41] + delivery: mode: email status: SENT deliveryId: del-7f12a7c4 providerMessageId: msg-001 + oneTimeCredentials: null + TenantOnboardingServiceUrls: + type: object + properties: + authorizationServerUrl: + type: string + format: uri + nullable: true + issuerUrl: + type: string + format: uri + nullable: true + oid4vciIssuerUrl: + type: string + format: uri + nullable: true + oid4vpVerifierUrl: + type: string + format: uri + nullable: true + TenantOnboardingCreatedRefs: + type: object + properties: + ownerPartyId: + type: string + format: uuid + nullable: true + technicalContactPartyId: + type: string + format: uuid + nullable: true + administrativeContactPartyId: + type: string + format: uuid + nullable: true + ownerAdminPartyId: + type: string + format: uuid + nullable: true + ownerAccountId: + type: string + nullable: true + ownerIdentityId: + type: string + format: uuid + nullable: true + relationshipIds: + type: array + items: + type: string + format: uuid + OneTimeCredentials: + type: object + required: [username, temporaryPassword] + properties: + username: + type: string + temporaryPassword: + type: string + description: Temporary credential shown once for generated_password mode. OwnerDeliveryResponse: type: object - description: Outcome of the owner invitation delivery. + description: Outcome of the owner account delivery path. required: [mode, status] properties: mode: @@ -2114,11 +2293,18 @@ components: updatedById: null deletedAt: null deletedById: null - primaryDomainUrl: https://acme.wallet.platform.example - issuerUrl: https://acme.wallet.platform.example/acme/oid4vci - ownerUserId: 2c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4b + tenantUrl: https://acme.wallet.platform.example + serviceUrls: + authorizationServerUrl: https://acme.wallet.platform.example + issuerUrl: https://acme.wallet.platform.example + oid4vciIssuerUrl: https://acme.wallet.platform.example + oid4vpVerifierUrl: https://acme.wallet.platform.example correlationId: reg-acme-7f12a7c4 - ownerDelivery: + created: + ownerPartyId: 2c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4b + ownerAccountId: 6c4e6a80-3b5d-4f70-9a12-8c0d1e2f3a4f + relationshipIds: [] + delivery: mode: none status: NOT_REQUESTED deliveryId: null diff --git a/redocly.yaml b/redocly.yaml index 0d6e0c4..e9b5796 100644 --- a/redocly.yaml +++ b/redocly.yaml @@ -69,8 +69,6 @@ apis: root: party-manager-openapi.yml vdx-license-portal: root: license-portal-openapi.yaml - vdx-attribute-source: - root: attribute-source-openapi.yml vdx-connector: root: connector-openapi.yml vdx-connector-integration: diff --git a/semantic-binding-components.yml b/semantic-binding-components.yml index 0cfada1..85a3745 100644 --- a/semantic-binding-components.yml +++ b/semantic-binding-components.yml @@ -433,8 +433,8 @@ components: createdAt: "2026-01-15T09:30:00Z" updatedAt: "2026-01-15T09:30:00Z" description: | - Binds a registered attribute source (a software/server party carrying an `ATTRIBUTE_SOURCE` - capability) to attributes of a version-pinned catalog, so the source's native fields map onto + Binds a registered connector/software party carrying a `CONNECTOR` + capability to attributes of a version-pinned catalog, so the connector's native fields map onto catalog attributes and inherit their governance overlays (classification / processing / residency / assurance plus the catalog jurisdictions). Complementary to the static `CatalogSchemaBinding` (declarative schema equivalence): this binds a LIVE source. Governance is @@ -454,11 +454,11 @@ components: sourcePartyId: type: string format: uuid - description: The software/server party that carries the `ATTRIBUTE_SOURCE` capability. + description: The software/server party that carries the `CONNECTOR` capability. capabilityId: type: string format: uuid - description: The `ATTRIBUTE_SOURCE` capability id on that party. + description: The `CONNECTOR` capability id on that party. catalogRef: $ref: '#/components/schemas/CatalogRef' entityBindings: diff --git a/semantic-binding-openapi.yml b/semantic-binding-openapi.yml index 8e1eeca..8e6ca5c 100644 --- a/semantic-binding-openapi.yml +++ b/semantic-binding-openapi.yml @@ -624,15 +624,15 @@ paths: /sourcebindings: post: tags: [SourceBindings] - summary: Bind a registered attribute source to catalog attributes + summary: Bind a registered connector to catalog attributes operationId: createSemanticSourceBinding x-license-protection: entitlementKey: vdx.semantic.binding.create-source-binding deploymentShapePredicates: [packaging=container, environment=production] protectionMode: licensed description: | - Binds a registered attribute source (a software/server party carrying an `ATTRIBUTE_SOURCE` - capability) to the attributes of a version-pinned catalog. The source's native fields map onto + Binds a registered connector/software party carrying a `CONNECTOR` + capability to the attributes of a version-pinned catalog. The connector's native fields map onto catalog attribute paths and inherit those attributes' governance overlays; whether the resolved values are stored or only referenced is controlled by `materialization`. The id, tenant and timestamps are assigned by the command (tenant from the session). @@ -670,7 +670,7 @@ paths: parameters: - name: sourcePartyId in: query - description: Restrict to bindings whose attribute source is this exact software/server party. + description: Restrict to bindings whose connector is this exact software/server party. schema: type: string format: uuid @@ -1126,11 +1126,11 @@ components: sourcePartyId: type: string format: uuid - description: The software/server party that carries the `ATTRIBUTE_SOURCE` capability. + description: The software/server party that carries the `CONNECTOR` capability. capabilityId: type: string format: uuid - description: The `ATTRIBUTE_SOURCE` capability id on that party. + description: The `CONNECTOR` capability id on that party. catalogRef: $ref: '#/components/schemas/CatalogRef' entityBindings: From dc4d6c44c6dd57f56322a4724da31aba73b50be7 Mon Sep 17 00:00:00 2001 From: Niels Klomp Date: Mon, 6 Jul 2026 21:04:36 +0200 Subject: [PATCH 7/8] chore: fixes --- asset-components.yml | 113 +++ asset-openapi.yml | 272 +++++++ branding-components.yml | 180 ----- credential-design-components.yml | 92 +-- docs-groups.json | 5 +- manifest-catalog.json | 5 +- redocly.yaml | 2 + resource-manager-components.yml | 2 - theme-components.yml | 806 +++++++++++++++++-- theme-openapi.yml | 1241 ++++++++++++++++++++++++++++-- 10 files changed, 2318 insertions(+), 400 deletions(-) create mode 100644 asset-components.yml create mode 100644 asset-openapi.yml delete mode 100644 branding-components.yml diff --git a/asset-components.yml b/asset-components.yml new file mode 100644 index 0000000..1e494bd --- /dev/null +++ b/asset-components.yml @@ -0,0 +1,113 @@ +openapi: 3.0.4 +info: + title: Asset Components + version: 0.1.0 + description: | + Shared schemas for the tenant asset service: content-addressed asset references, + blob store descriptors, and asset library listings. These shapes are shared with the + credential design API, which re-references them from here. +paths: {} +components: + schemas: + AssetNamespace: + type: string + description: | + Logical namespace an asset belongs to. `brand` holds theming and branding assets + (logos, favicons, backgrounds); `design` holds credential design assets. + enum: [brand, design] + + BlobInfo: + type: object + description: | + A reference to a binary stored in the platform blob store. Present on assets and source + snapshots that have been persisted locally. The pair `(storeId, path)` locates the bytes. + properties: + storeId: + type: string + nullable: true + description: Identifier of the blob store holding the bytes. + path: + type: string + nullable: true + description: Path of the blob within the store. + tenantId: + type: string + nullable: true + description: Tenant the blob belongs to. + contentType: + type: string + nullable: true + description: MIME type of the stored bytes. + example: image/png + metadata: + type: object + additionalProperties: + type: string + description: Free-form key/value metadata recorded with the blob. + + AssetReference: + type: object + description: A pointer to a branding asset, either external (by URI) or stored locally (by blob). + required: [uri] + properties: + uri: + type: string + description: Resolvable URI of the asset. For locally stored assets this is the asset download URL. + example: https://cdn.example.com/logos/identity.png + integrity: + type: string + nullable: true + description: Optional subresource-integrity digest (for example `sha256-...`). + altText: + type: string + nullable: true + description: Accessible alt text for the asset. + contentType: + type: string + nullable: true + description: MIME type of the asset. + example: image/png + localBlob: + type: object + allOf: + - $ref: '#/components/schemas/BlobInfo' + nullable: true + description: Set when the asset is stored in the platform blob store. + example: + uri: https://cdn.example.com/logos/identity.png + contentType: image/png + altText: Identity issuer logo + + AssetInfo: + type: object + description: >- + A descriptor for a content-addressed, tenant-scoped asset blob, returned by the + asset library listing surface. `hash` is the lowercase-hex SHA-256 of the bytes and + `uri` is the stable relative public path (the per-tenant absolute host is applied at serve time). + required: [uri, contentType, hash] + properties: + uri: + type: string + description: >- + Stable relative public path of the asset, for example + `/public/assets/{tenantId}/brand/{sha256}.png`. Credential design assets keep their + existing `/public/assets/design/{sha256}.png` form. + example: /public/assets/acme/brand/0f4636c78f65d3639ece5a064b5ae753e3408614a14fb18ab4d7540d2c248543.png + contentType: + type: string + description: MIME type the asset was stored as. + example: image/png + hash: + type: string + description: Lowercase-hex SHA-256 digest (64 chars) of the asset bytes. + example: 0f4636c78f65d3639ece5a064b5ae753e3408614a14fb18ab4d7540d2c248543 + sizeBytes: + type: integer + format: int64 + nullable: true + description: Size of the asset in bytes, when the blob store reports it. + createdAt: + type: string + format: date-time + nullable: true + description: Creation timestamp of the asset blob, when the blob store reports it. diff --git a/asset-openapi.yml b/asset-openapi.yml new file mode 100644 index 0000000..975e0df --- /dev/null +++ b/asset-openapi.yml @@ -0,0 +1,272 @@ +openapi: 3.0.4 +info: + title: Asset API + version: 0.1.0 + x-products: [edk, vdx] + description: | + Tenant asset service: a content-addressed library of binary assets (logos, favicons, + backgrounds, design artwork) over the platform blob store, plus the public hosting + surface that serves the stored bytes. + + Assets are addressed by the SHA-256 hash of their bytes and deduplicated per tenant: + uploading the same bytes twice returns the same asset. Assets are grouped into + namespaces (`brand` for theming and branding, `design` for credential design). + Library endpoints are tenant-admin operations; the tenant is taken from the + authenticated context and never appears in library paths. + + Public asset URLs are tenant scoped and host independent: + `/public/assets/{tenantId}/{namespace}/{hash}.{ext}`. Because the tenant id is in the + path, the URL resolves identically whether assets are served from the tenant's own + domain or from the platform domain. The asset id is the SHA-256 content hash and is + stable across hosts and re-uploads of the same bytes, so responses are cacheable + forever (`Cache-Control: public, max-age=31536000, immutable`). + +servers: + - url: https://api.example.com/api/assets/v1 + description: Production server. + - url: http://localhost:8080/api/assets/v1 + description: Local development server. + +security: + - bearer: [] + +tags: + - name: AssetLibrary + description: >- + Tenant-admin asset library: upload, list, get, and delete content-addressed assets + per namespace. The tenant is resolved from the bearer token. + - name: AssetHosting + description: >- + Public, unauthenticated hosting of stored asset bytes at stable tenant-scoped, + content-addressed URLs. + +paths: + + /library/{namespace}: + parameters: + - $ref: '#/components/parameters/Namespace' + post: + tags: [AssetLibrary] + summary: Upload an asset + operationId: uploadAsset + x-command-id: asset.rest-library.upload + description: >- + Uploads an asset into the caller-tenant's library as raw bytes. The stored content + type is taken from the request `Content-Type` header, which is authoritative. The + asset is content-addressed by the SHA-256 hash of its bytes and deduplicated within + the tenant and namespace: re-uploading identical bytes returns a reference to the + already-stored asset instead of creating a new one. Returns an [AssetReference] + whose `uri` is the stable public hosting path. + requestBody: + required: true + content: + application/octet-stream: + schema: + type: string + format: binary + image/png: + schema: + type: string + format: binary + image/jpeg: + schema: + type: string + format: binary + image/svg+xml: + schema: + type: string + format: binary + application/pdf: + schema: + type: string + format: binary + responses: + '201': + description: A reference to the stored asset. Returned for new uploads and for deduplicated re-uploads alike. + content: + application/json: + schema: + $ref: '#/components/schemas/AssetReference' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '500': + $ref: './common-components.yml#/components/responses/Error' + get: + tags: [AssetLibrary] + summary: List assets + operationId: listAssets + x-command-id: asset.rest-library.list + description: >- + Lists the caller-tenant's assets in the namespace as a plain array. The optional + `contentType` filter restricts to assets whose content type starts with the given + value (for example `image/`). + parameters: + - $ref: '#/components/parameters/FilterContentType' + responses: + '200': + description: The tenant's assets in this namespace. + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/AssetInfo' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '500': + $ref: './common-components.yml#/components/responses/Error' + + /library/{namespace}/{hash}: + parameters: + - $ref: '#/components/parameters/Namespace' + - $ref: '#/components/parameters/AssetHash' + get: + tags: [AssetLibrary] + summary: Get an asset + operationId: getAsset + x-command-id: asset.rest-library.get + description: >- + Returns the descriptor of one stored asset by its SHA-256 content hash. The asset + bytes themselves are served from the public hosting path in the descriptor's `uri`. + responses: + '200': + description: The asset descriptor. + content: + application/json: + schema: + $ref: '#/components/schemas/AssetInfo' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + delete: + tags: [AssetLibrary] + summary: Delete an asset + operationId: deleteAsset + x-command-id: asset.rest-library.delete + description: >- + Deletes a stored asset by its SHA-256 content hash and returns no response body when + successful. The public hosting URL stops resolving for this tenant and namespace. + responses: + '204': + description: The asset was deleted. + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + /public/assets/{tenantId}/{namespace}/{asset}: + servers: + - url: / + description: Host root. Public asset hosting is an unversioned mount, not under `/api/assets/v1`. + parameters: + - name: tenantId + in: path + required: true + description: Tenant the asset belongs to. An unknown tenant returns 404. + schema: + type: string + - $ref: '#/components/parameters/Namespace' + - name: asset + in: path + required: true + description: Content-addressed asset leaf, for example `{sha256}.png`. May include a file extension. + schema: + type: string + get: + tags: [AssetHosting] + summary: Download a public asset + operationId: getPublicAsset + x-command-id: asset.rest-hosting.get + security: [] + description: | + Serves the raw bytes of a stored asset from its stable tenant-scoped, content-addressed + public URL. The response `Content-Type` is whatever the asset was stored as. Because the + asset id is the SHA-256 content hash, the body can never change for a given URL, so the + response is served with `Cache-Control: public, max-age=31536000, immutable`. Returns 404 + for an unknown tenant, namespace, or asset. + responses: + '200': + description: Public asset bytes. + headers: + Cache-Control: + description: Always `public, max-age=31536000, immutable` (content addressed, safe to cache forever). + schema: + type: string + example: public, max-age=31536000, immutable + content: + application/octet-stream: + schema: + type: string + format: binary + image/png: + schema: + type: string + format: binary + image/jpeg: + schema: + type: string + format: binary + image/svg+xml: + schema: + type: string + format: binary + application/pdf: + schema: + type: string + format: binary + '404': + $ref: './common-components.yml#/components/responses/NotFound' + +components: + securitySchemes: + bearer: + $ref: './common-components.yml#/components/securitySchemes/bearer' + + parameters: + Namespace: + name: namespace + in: path + required: true + description: Asset namespace. + schema: + $ref: './asset-components.yml#/components/schemas/AssetNamespace' + AssetHash: + name: hash + in: path + required: true + description: Lowercase-hex SHA-256 digest (64 chars) of the asset bytes. + schema: + type: string + FilterContentType: + name: contentType + in: query + required: false + description: Restrict to assets whose content type starts with this value (for example `image/`). + schema: + type: string + + schemas: + # ---- Re-exported entity schemas from asset-components.yml ---- + AssetNamespace: + $ref: './asset-components.yml#/components/schemas/AssetNamespace' + AssetReference: + $ref: './asset-components.yml#/components/schemas/AssetReference' + AssetInfo: + $ref: './asset-components.yml#/components/schemas/AssetInfo' + BlobInfo: + $ref: './asset-components.yml#/components/schemas/BlobInfo' diff --git a/branding-components.yml b/branding-components.yml deleted file mode 100644 index 2d74b7b..0000000 --- a/branding-components.yml +++ /dev/null @@ -1,180 +0,0 @@ -openapi: 3.0.3 -info: - title: Branding Components - version: 0.1.0 - description: Shared branding schemas for visual identity management across the data store. -paths: {} -components: - schemas: - BrandingProfile: - type: object - description: | - Unified visual branding definition. Replaces tenant_branding, issuer_branding, - rp_branding, and credential_branding tables. Contains only visual properties; - legal/contact info belongs on the organization table. - required: - - id - - name - - createdAt - - updatedAt - properties: - id: - type: string - format: uuid - name: - type: string - description: Internal name for managing this branding profile. - example: "Acme Corp Brand" - primaryColor: - type: string - pattern: '^#[0-9A-Fa-f]{6}$' - description: Primary brand color in hex format. - example: "#1E40AF" - secondaryColor: - type: string - pattern: '^#[0-9A-Fa-f]{6}$' - description: Secondary brand color in hex format. - example: "#3B82F6" - textColor: - type: string - pattern: '^#[0-9A-Fa-f]{6}$' - description: Text color for contrast. - example: "#FFFFFF" - accentColor: - type: string - pattern: '^#[0-9A-Fa-f]{6}$' - description: Accent color for highlights. - example: "#F59E0B" - logoAssetId: - type: string - format: uuid - description: Reference to logo asset. - backgroundAssetId: - type: string - format: uuid - description: Reference to background/hero image asset. - createdByUserId: - type: string - format: uuid - updatedByUserId: - type: string - format: uuid - createdAt: - type: string - format: date-time - updatedAt: - type: string - format: date-time - - BrandingProfileLocale: - type: object - description: Locale-specific asset overrides for a branding profile. - required: - - id - - brandingProfileId - - locale - - createdAt - - updatedAt - properties: - id: - type: string - format: uuid - brandingProfileId: - type: string - format: uuid - locale: - type: string - description: BCP 47 locale tag (e.g., 'en-US', 'nl-NL'). - example: "nl-NL" - localizedLogoAssetId: - type: string - format: uuid - description: Locale-specific logo override. Falls back to parent if null. - localizedBackgroundAssetId: - type: string - format: uuid - description: Locale-specific background override. Falls back to parent if null. - createdAt: - type: string - format: date-time - updatedAt: - type: string - format: date-time - - BrandingProfileCreateRequest: - type: object - required: - - name - properties: - name: - type: string - primaryColor: - type: string - pattern: '^#[0-9A-Fa-f]{6}$' - secondaryColor: - type: string - pattern: '^#[0-9A-Fa-f]{6}$' - textColor: - type: string - pattern: '^#[0-9A-Fa-f]{6}$' - accentColor: - type: string - pattern: '^#[0-9A-Fa-f]{6}$' - logoAssetId: - type: string - format: uuid - backgroundAssetId: - type: string - format: uuid - - BrandingProfileUpdateRequest: - type: object - properties: - name: - type: string - primaryColor: - type: string - pattern: '^#[0-9A-Fa-f]{6}$' - secondaryColor: - type: string - pattern: '^#[0-9A-Fa-f]{6}$' - textColor: - type: string - pattern: '^#[0-9A-Fa-f]{6}$' - accentColor: - type: string - pattern: '^#[0-9A-Fa-f]{6}$' - logoAssetId: - type: string - format: uuid - nullable: true - backgroundAssetId: - type: string - format: uuid - nullable: true - - BrandingProfileLocaleCreateRequest: - type: object - required: - - locale - properties: - locale: - type: string - localizedLogoAssetId: - type: string - format: uuid - localizedBackgroundAssetId: - type: string - format: uuid - - BrandingProfileLocaleUpdateRequest: - type: object - properties: - localizedLogoAssetId: - type: string - format: uuid - nullable: true - localizedBackgroundAssetId: - type: string - format: uuid - nullable: true diff --git a/credential-design-components.yml b/credential-design-components.yml index 04be591..e1239ce 100644 --- a/credential-design-components.yml +++ b/credential-design-components.yml @@ -561,98 +561,16 @@ components: nullable: true description: Optional issuer/verifier branding logo for this locale. + # Shared asset shapes live in ./asset-components.yml and are re-referenced here + # so existing `#/components/schemas/...` refs keep resolving. BlobInfo: - type: object - description: | - A reference to a binary stored in the platform blob store. Present on assets and source - snapshots that have been persisted locally. The pair `(storeId, path)` locates the bytes. - properties: - storeId: - type: string - nullable: true - description: Identifier of the blob store holding the bytes. - path: - type: string - nullable: true - description: Path of the blob within the store. - tenantId: - type: string - nullable: true - description: Tenant the blob belongs to. - contentType: - type: string - nullable: true - description: MIME type of the stored bytes. - example: image/png - metadata: - type: object - additionalProperties: - type: string - description: Free-form key/value metadata recorded with the blob. + $ref: './asset-components.yml#/components/schemas/BlobInfo' AssetReference: - type: object - description: A pointer to a branding asset, either external (by URI) or stored locally (by blob). - required: [uri] - properties: - uri: - type: string - description: Resolvable URI of the asset. For locally stored assets this is the asset download URL. - example: https://cdn.example.com/logos/identity.png - integrity: - type: string - nullable: true - description: Optional subresource-integrity digest (for example `sha256-...`). - altText: - type: string - nullable: true - description: Accessible alt text for the asset. - contentType: - type: string - nullable: true - description: MIME type of the asset. - example: image/png - localBlob: - type: object - allOf: - - $ref: '#/components/schemas/BlobInfo' - nullable: true - description: Set when the asset is stored in the platform blob store. - example: - uri: https://cdn.example.com/logos/identity.png - contentType: image/png - altText: Identity issuer logo + $ref: './asset-components.yml#/components/schemas/AssetReference' AssetInfo: - type: object - description: >- - A descriptor for a content-addressed, tenant-scoped design asset blob, returned by the - design-agnostic asset listing surface. `hash` is the lowercase-hex SHA-256 of the bytes and - `uri` is the stable relative public path (the per-tenant absolute host is applied at serve time). - required: [uri, contentType, hash] - properties: - uri: - type: string - description: Stable relative public path of the asset, for example `/public/assets/design/{sha256}.png`. - example: /public/assets/design/0f4636c78f65d3639ece5a064b5ae753e3408614a14fb18ab4d7540d2c248543.png - contentType: - type: string - description: MIME type the asset was stored as. - example: image/png - hash: - type: string - description: Lowercase-hex SHA-256 digest (64 chars) of the asset bytes. - example: 0f4636c78f65d3639ece5a064b5ae753e3408614a14fb18ab4d7540d2c248543 - sizeBytes: - type: integer - format: int64 - nullable: true - description: Size of the asset in bytes, when the blob store reports it. - createdAt: - type: string - format: date-time - nullable: true - description: Creation timestamp of the asset blob, when the blob store reports it. + $ref: './asset-components.yml#/components/schemas/AssetInfo' SvgTemplate: type: object diff --git a/docs-groups.json b/docs-groups.json index d4ffa7b..8153f50 100644 --- a/docs-groups.json +++ b/docs-groups.json @@ -5,7 +5,7 @@ { "key": "verifiable-credentials", "label": "Digital Credentials", "apis": ["oid4vci-issuer", "oid4vci-issuer-session", "oid4vp-universal", "oid4vp-verifier", "credential-design", "dcql", "dcql-edk", "dcql-vdx", "statuslist-hosting", "statuslist-management"] }, { "key": "semantics", "label": "Semantics & Catalog", "apis": ["semantic-model-authoring", "semantic-binding", "semantic-vocabulary"] }, { "key": "parties", "label": "Parties & Accounts", "apis": ["party-manager", "user-manager", "identity-auth"] }, - { "key": "services", "label": "Services", "apis": ["software-manager", "connector", "resource-manager", "email"] }, + { "key": "services", "label": "Services", "apis": ["software-manager", "connector", "resource-manager", "email", "asset"] }, { "key": "platform", "label": "Tenancy & Platform", "apis": ["platform-admin", "platform-setup", "platform-bootstrap", "platform-config", "invitation", "forms"] } ], "labels": { @@ -39,6 +39,7 @@ "platform-config": "Platform Config", "invitation": "Invitations & Redemption", "email": "Email", - "forms": "Forms" + "forms": "Forms", + "asset": "Tenant Assets" } } diff --git a/manifest-catalog.json b/manifest-catalog.json index 6534f50..21a1181 100644 --- a/manifest-catalog.json +++ b/manifest-catalog.json @@ -20,11 +20,12 @@ { "division": "edk", "domain": "audit", "specPath": "audit-openapi.yml", "ownerModule": "vdx-lib-audit-server", "targets": ["edk","vdx"], "additionalOwnerModules": ["vdx-lib-audit-persistence"], "note": "Dedicated audit query surface under /api/audit/v1. It exposes read-only audit records independently from platform-admin so deployments can authorize audit access with dedicated roles." }, { "division": "edk", "domain": "trust-domain", "specPath": "trust-domain-openapi.yaml", "ownerModule": "lib-trust-domain-rest", "targets": ["edk","vdx"], "additionalOwnerModules": ["lib-trust-domain-public","lib-trust-domain-service","lib-trust-domain-persistence-postgresql","lib-trust-domain-persistence-mysql","lib-trust-domain-persistence-sqlite"], "note": "Tenant-scoped trust-domain, trust-anchor, binding, and anchor-resolution API under /api/platform/admin/v1/trust. Used by EDK and VDX trust-establishment flows for X.509, ETSI, DID, OpenID Federation, issuer validation, verifier validation, and credential-specific trust domains." }, { "division": "edk", "domain": "wallet-unit", "specPath": "wallet-unit-openapi.yml", "ownerModule": "vdx-service-wallet-unit-rest", "targets": ["edk","vdx"], "additionalOwnerModules": ["lib-wallet-unit","lib-wallet-public","lib-statuslist-public","lib-statuslist-management-rest","lib-eidas-signature-rest-api"], "note": "Optional Wallet Unit backend under /api/wallet-unit/v1 for lifecycle, activation evidence, TS03 WIA/KA attestation, Wallet Provider/Solution trust evidence, status-list subjects, and policy-gated wallet-key signing. It does not enforce OID4VCI PAR/token/credential requests and does not implement reset, notification, or conformance reporting workflows." }, - { "division": "vdx", "domain": "theme", "specPath": "theme-openapi.yml", "ownerModule": "vdx-conf-theme-rest", "targets": ["edk","vdx"], "additionalOwnerModules": ["vdx-conf-theme-public","vdx-conf-theme-impl","edk-theme-compose"], "note": "Tenant branding and resolved theme API under /api/theme/v1 for simple-brand administration, CSS/token resolution, media-backed branding, and wallet/admin-console runtime theme clients." }, + { "division": "vdx", "domain": "theme", "specPath": "theme-openapi.yml", "ownerModule": "vdx-conf-theme-rest", "targets": ["edk","vdx"], "additionalOwnerModules": ["vdx-conf-theme-public","vdx-conf-theme-impl","edk-theme-compose"], "note": "Tenant branding and theming API under /api/theme/v1: public theme/CSS/feature resolution, tenant and per-application brand administration, application registry, features and design element bindings, definitions, tokens, stylesheets, and palette/seed/cache operations." }, { "division": "vdx", "domain": "wallet-entitlement", "specPath": "wallet-entitlement-openapi.yml", "ownerModule": "vdx-service-wallet-entitlement-rest", "targets": ["edk","vdx"], "additionalOwnerModules": ["vdx-service-wallet-entitlement-public","vdx-service-wallet-entitlement-impl"], "note": "Wallet feature entitlement admin and signed manifest API under /api/wallet-entitlement/v1 for tenant/org-unit/group/person feature resolution, license-ceiling intersection, and wallet-side manifest fetch." }, { "division": "edk", "domain": "oid4vp-verifier", "specPath": "oid4vp-verifier-openapi.yaml", "ownerModule": "services-oid4vp-verifier-rest", "targets": ["edk","vdx"] }, { "division": "edk", "domain": "oid4vci-issuer", "specPath": "oid4vci-issuer-openapi.yaml", "ownerModule": "services-oid4vci-issuer-rest", "targets": ["edk","vdx"] }, { "division": "edk", "domain": "credential-design", "specPath": "credential-design-openapi.yml", "ownerModule": "lib-data-store-credential-design-rest", "targets": ["edk","vdx"] }, + { "division": "edk", "domain": "asset", "specPath": "asset-openapi.yml", "ownerModule": "lib-data-store-asset-rest", "targets": ["edk","vdx"], "note": "Tenant asset library under /api/assets/v1 (namespace-scoped upload/list/get/delete with SHA-256 content addressing and per-tenant dedup) plus the public unversioned hosting mount /public/assets/{tenantId}/{namespace}/{asset}." }, { "division": "vdx", "domain": "party-manager", "specPath": "party-manager-openapi.yml", "ownerModule": "data-store-party-api", "targets": ["edk","vdx"] }, { "division": "vdx", "domain": "license-portal", "specPath": "license-portal-openapi.yaml", "ownerModule": "vdx-service-license-portal", "targets": ["vdx"], "note": "Authenticated license issuer portal API under /api/license-portal/v1 for partners, customers, deployments, imported customer license requests, issuance, protected setup bundles, and license revocation." }, @@ -68,10 +69,10 @@ "wallet-entitlement-components.yml", "oid4vci-issuer-components.yml", "credential-design-components.yml", + "asset-components.yml", "party-manager-components.yml", "identity-manager-components.yml", "connector-components.yml", - "branding-components.yml", "software-manager-components.yml", "resource-manager-components.yml", "user-manager-components.yml", diff --git a/redocly.yaml b/redocly.yaml index e9b5796..db91167 100644 --- a/redocly.yaml +++ b/redocly.yaml @@ -60,6 +60,8 @@ apis: root: dcql-edk-openapi.yml edk-credential-design: root: credential-design-openapi.yml + edk-assets: + root: asset-openapi.yml edk-oid4vci-issuance-template: root: oid4vci-issuance-template-openapi.yml edk-oid4vp-verification-template: diff --git a/resource-manager-components.yml b/resource-manager-components.yml index b4aca3d..34a22c9 100644 --- a/resource-manager-components.yml +++ b/resource-manager-components.yml @@ -515,8 +515,6 @@ components: $ref: './party-manager-components.yml#/components/schemas/PartyEntity' resource: $ref: '#/components/schemas/Resource' - # brandingProfile: - # $ref: './branding-components.yml#/components/schemas/BrandingProfile' usagePolicy: $ref: '#/components/schemas/UsagePolicy' resourceUsagePolicy: diff --git a/theme-components.yml b/theme-components.yml index 2a25430..ec28bf0 100644 --- a/theme-components.yml +++ b/theme-components.yml @@ -2,7 +2,10 @@ openapi: 3.0.4 info: title: Theme Components version: 0.1.0 - description: Shared schemas for the VDX theme branding and resolution API. + description: | + Shared schemas for the tenant branding and theming API: scopes, variants, design tokens, + theme definitions, applications, features, design element bindings, brand shapes, and + resolution outputs. paths: {} components: parameters: @@ -10,30 +13,72 @@ components: name: tenant in: path required: true - description: Tenant identifier used by the existing theme REST adapter. + description: Tenant identifier. Validated against the tenant registry; an unknown tenant is a 404. schema: type: string - AppIdQuery: - name: appId - in: query - required: false - description: Optional application identifier for app-specific branding. + ApplicationIdPath: + name: applicationId + in: path + required: true + description: Identifier of a registered application (a deployed, brandable instance the tenant runs). + schema: + type: string + ProductTypePath: + name: productType + in: path + required: true + description: Product type the feature belongs to. + schema: + $ref: '#/components/schemas/ProductType' + FeatureIdPath: + name: featureId + in: path + required: true + description: Identifier of a brandable feature declared by the product type. + schema: + type: string + ElementIdPath: + name: elementId + in: path + required: true + description: Identifier of a design element declared by the feature. schema: type: string - PrincipalIdQuery: - name: principalId + ThemeIdPath: + name: themeId + in: path + required: true + description: Identifier of a theme definition. + schema: + type: string + ApplicationIdQuery: + name: applicationId in: query required: false - description: Optional principal identifier for principal-scoped theme resolution. + description: Optional identifier of a registered application to scope the operation to. schema: type: string VariantQuery: name: variant in: query required: false - description: Visual variant to resolve. + description: Visual variant to resolve or select. schema: $ref: '#/components/schemas/ThemeVariant' + ScopeQuery: + name: scope + in: query + required: false + description: Restrict to definitions at this scope. + schema: + $ref: '#/components/schemas/ThemeScope' + ProductTypeQuery: + name: productType + in: query + required: false + description: Restrict to definitions keyed by this product type. + schema: + $ref: '#/components/schemas/ProductType' ResolutionModeQuery: name: mode in: query @@ -45,13 +90,14 @@ components: name: If-None-Match in: header required: false - description: ETag from a previous resolved theme or CSS response. + description: ETag from a previous response. When it still matches, the server returns 304 with no body. schema: type: string schemas: ThemeVariant: type: string + description: Visual variant. HIGH_CONTRAST is reserved; the platform currently implements LIGHT and DARK. enum: [LIGHT, DARK, HIGH_CONTRAST] ThemeResolutionMode: @@ -60,7 +106,23 @@ components: ThemeScope: type: string - enum: [SYSTEM, APP, TENANT, PRINCIPAL] + description: | + Hierarchical scope of a theme definition. Precedence during resolution is + `SYSTEM < PRODUCT < TENANT < APPLICATION < PRINCIPAL`, later scopes win. + `PRODUCT` definitions require `productType`; `APPLICATION` definitions require + `applicationId`; the other scopes carry neither. + enum: [SYSTEM, PRODUCT, TENANT, APPLICATION, PRINCIPAL] + + ProductType: + type: string + description: The product a deployed application is an instance of. + enum: + - AUTHORIZATION_SERVER + - WEB_WALLET + - MOBILE_WALLET + - PORTAL + - ADMIN_CONSOLE + - CUSTOM ThemeTokenType: type: string @@ -90,6 +152,590 @@ components: type: $ref: '#/components/schemas/ThemeTokenType' + ThemeDefinition: + type: object + description: A set of design tokens at a given scope, layered during resolution. + required: [id, name, scope, tokens, version] + properties: + id: + type: string + name: + type: string + variant: + type: string + allOf: + - $ref: '#/components/schemas/ThemeVariant' + nullable: true + description: Variant this definition applies to. Null means the common baseline for its scope. + parentId: + type: string + nullable: true + description: Optional parent definition to inherit from. + scope: + $ref: '#/components/schemas/ThemeScope' + productType: + type: string + allOf: + - $ref: '#/components/schemas/ProductType' + nullable: true + description: Required when `scope` is PRODUCT; absent otherwise. + applicationId: + type: string + nullable: true + description: Required when `scope` is APPLICATION; absent otherwise. + tokens: + type: array + items: + $ref: '#/components/schemas/ThemeToken' + version: + type: integer + format: int64 + createdAt: + type: string + format: date-time + nullable: true + updatedAt: + type: string + format: date-time + nullable: true + + ThemeDefinitionInput: + type: object + description: Input shape for creating, updating, or validating a theme definition. + required: [name, scope, tokens] + properties: + id: + type: string + nullable: true + description: Optional client-chosen definition id. Generated when omitted on create; ignored on update. + name: + type: string + variant: + type: string + allOf: + - $ref: '#/components/schemas/ThemeVariant' + nullable: true + parentId: + type: string + nullable: true + scope: + $ref: '#/components/schemas/ThemeScope' + productType: + type: string + allOf: + - $ref: '#/components/schemas/ProductType' + nullable: true + description: Required when `scope` is PRODUCT; rejected otherwise. + applicationId: + type: string + nullable: true + description: Required when `scope` is APPLICATION; rejected otherwise. + tokens: + type: array + items: + $ref: '#/components/schemas/ThemeToken' + + ThemeValidationError: + type: object + required: [message] + properties: + tokenKey: + type: string + nullable: true + description: Token key the error applies to, when the error is token specific. + message: + type: string + + ThemeValidationResult: + type: object + required: [valid, errors] + properties: + valid: + type: boolean + errors: + type: array + items: + $ref: '#/components/schemas/ThemeValidationError' + + ThemeHistoryEntry: + type: object + required: [version, savedAt, tokenCount, name] + properties: + version: + type: integer + format: int64 + savedAt: + type: string + format: date-time + tokenCount: + type: integer + format: int32 + name: + type: string + + UndoThemeInput: + type: object + properties: + revertToVersion: + type: integer + format: int64 + nullable: true + description: Version to revert to. When omitted, the last update is undone. + + UndoThemeOutput: + type: object + required: [restoredDefinition, previousVersion, newVersion] + properties: + restoredDefinition: + $ref: '#/components/schemas/ThemeDefinition' + previousVersion: + type: integer + format: int64 + newVersion: + type: integer + format: int64 + + RestoreThemeOutput: + type: object + required: [restoredDefinition] + properties: + restoredDefinition: + $ref: '#/components/schemas/ThemeDefinition' + + Application: + type: object + description: >- + One deployed, brandable instance the tenant runs: a specific authorization server, web + wallet, portal, mobile wallet, or the admin console. Platform-managed instances enter the + list from the platform instance registries; external applications are registered here. + required: [applicationId, tenantId, productType, name, managed] + properties: + applicationId: + type: string + tenantId: + type: string + productType: + $ref: '#/components/schemas/ProductType' + name: + type: string + description: + type: string + nullable: true + managed: + type: boolean + description: True for platform-provisioned instances, which are read-only in this registry. + instanceRef: + type: string + nullable: true + description: Reference to the platform instance record backing a managed application. + createdAt: + type: string + format: date-time + nullable: true + updatedAt: + type: string + format: date-time + nullable: true + + ApplicationInput: + type: object + required: [productType, name] + properties: + productType: + $ref: '#/components/schemas/ProductType' + name: + type: string + description: + type: string + nullable: true + + BrandInput: + type: object + description: The tenant simple brand. Writing it regenerates the palette tokens in the canonical tenant definitions while preserving power overrides. + required: [appName, primaryColor] + properties: + appName: + type: string + example: Acme Wallet + primaryColor: + type: string + pattern: '^#[0-9A-Fa-f]{6}$' + example: '#3157D5' + secondaryColor: + type: string + nullable: true + pattern: '^#[0-9A-Fa-f]{6}$' + tagline: + type: string + nullable: true + logo: + type: object + allOf: + - $ref: './asset-components.yml#/components/schemas/AssetReference' + nullable: true + logoDark: + type: object + allOf: + - $ref: './asset-components.yml#/components/schemas/AssetReference' + nullable: true + favicon: + type: object + allOf: + - $ref: './asset-components.yml#/components/schemas/AssetReference' + nullable: true + + ApplicationBrandInput: + type: object + description: Sparse per-application override of the tenant brand. Every property is optional; set properties override the tenant default for this application. + properties: + appName: + type: string + nullable: true + primaryColor: + type: string + nullable: true + pattern: '^#[0-9A-Fa-f]{6}$' + secondaryColor: + type: string + nullable: true + pattern: '^#[0-9A-Fa-f]{6}$' + tagline: + type: string + nullable: true + logo: + type: object + allOf: + - $ref: './asset-components.yml#/components/schemas/AssetReference' + nullable: true + logoDark: + type: object + allOf: + - $ref: './asset-components.yml#/components/schemas/AssetReference' + nullable: true + favicon: + type: object + allOf: + - $ref: './asset-components.yml#/components/schemas/AssetReference' + nullable: true + + BrandOutput: + type: object + required: + - appName + - primaryColor + - generatedTokenCount + - preservedPowerTokenCount + - hasPowerOverrides + properties: + appName: + type: string + primaryColor: + type: string + pattern: '^#[0-9A-Fa-f]{6}$' + secondaryColor: + type: string + nullable: true + pattern: '^#[0-9A-Fa-f]{6}$' + tagline: + type: string + nullable: true + logo: + type: object + allOf: + - $ref: './asset-components.yml#/components/schemas/AssetReference' + nullable: true + logoDark: + type: object + allOf: + - $ref: './asset-components.yml#/components/schemas/AssetReference' + nullable: true + favicon: + type: object + allOf: + - $ref: './asset-components.yml#/components/schemas/AssetReference' + nullable: true + applicationId: + type: string + nullable: true + description: Set when this is a per-application brand. + generatedTokenCount: + type: integer + format: int32 + preservedPowerTokenCount: + type: integer + format: int32 + hasPowerOverrides: + type: boolean + lastUpdated: + type: string + format: date-time + nullable: true + + TokenPatchRequest: + type: object + description: Upserts and removals applied to the canonical definition for the addressed `(scope, variant, applicationId)` combination. + properties: + variant: + type: string + allOf: + - $ref: '#/components/schemas/ThemeVariant' + nullable: true + applicationId: + type: string + nullable: true + set: + type: object + additionalProperties: + type: string + description: Token key to value upserts. + unset: + type: array + items: + type: string + description: Token keys to remove. + + TokenSetOutput: + type: object + description: The editable token set at a given `(scope, variant, applicationId)` combination. + required: [definitionId, scope, tokens] + properties: + definitionId: + type: string + description: The canonical definition the tokens live in. + scope: + $ref: '#/components/schemas/ThemeScope' + variant: + type: string + allOf: + - $ref: '#/components/schemas/ThemeVariant' + nullable: true + applicationId: + type: string + nullable: true + tokens: + type: object + additionalProperties: + type: string + description: Flat map of token key to effective value. + + FeatureDefinition: + type: object + description: A brandable capability a product type declares, with the named design elements it renders. + required: [featureId, productType, name, builtIn, elements, version] + properties: + featureId: + type: string + example: login + productType: + $ref: '#/components/schemas/ProductType' + name: + type: string + description: + type: string + nullable: true + builtIn: + type: boolean + description: True for features contributed in code by the product. Built-ins are read-only here. + elements: + type: array + items: + $ref: '#/components/schemas/DesignElement' + version: + type: integer + format: int64 + createdAt: + type: string + format: date-time + nullable: true + updatedAt: + type: string + format: date-time + nullable: true + + FeatureInput: + type: object + required: [name, elements] + properties: + name: + type: string + description: + type: string + nullable: true + elements: + type: array + items: + $ref: '#/components/schemas/DesignElement' + + ElementKind: + type: string + description: Kind of value a design element takes. ASSET elements bind an asset reference; TEXT elements bind a string. + enum: [ASSET, TEXT] + + DesignElement: + type: object + description: A named, overridable design element a feature declares, such as a sign-in logo, background, or tagline. + required: [elementId, kind, required] + properties: + elementId: + type: string + example: background + kind: + $ref: '#/components/schemas/ElementKind' + required: + type: boolean + description: + type: string + nullable: true + acceptedContentTypes: + type: array + nullable: true + items: + type: string + description: Accepted MIME types for ASSET elements. + maxSizeBytes: + type: integer + format: int64 + nullable: true + description: Maximum asset size for ASSET elements. + maxLength: + type: integer + format: int32 + nullable: true + description: Maximum text length for TEXT elements. + fallbackTokenKey: + type: string + nullable: true + description: Token key resolution falls back to when no binding or default exists, for example `branding.logoUrl`. + defaultAsset: + type: object + allOf: + - $ref: './asset-components.yml#/components/schemas/AssetReference' + nullable: true + defaultText: + type: string + nullable: true + + ElementBindingInput: + type: object + description: >- + Value to bind to a design element. Exactly one of `asset` or `text` is set, matching the + element kind. `variant` and `applicationId` select the binding slot; they can also be + supplied as query parameters. + properties: + variant: + type: string + allOf: + - $ref: '#/components/schemas/ThemeVariant' + nullable: true + applicationId: + type: string + nullable: true + asset: + type: object + allOf: + - $ref: './asset-components.yml#/components/schemas/AssetReference' + nullable: true + text: + type: string + nullable: true + + ElementBinding: + type: object + description: >- + A stored design element value at tenant scope (`applicationId` null, the default for every + application of the product) or application scope (`applicationId` set), optionally per + variant. Exactly one of `asset` or `text` is set, matching the element kind. + required: [productType, featureId, elementId] + properties: + productType: + $ref: '#/components/schemas/ProductType' + featureId: + type: string + elementId: + type: string + variant: + type: string + allOf: + - $ref: '#/components/schemas/ThemeVariant' + nullable: true + applicationId: + type: string + nullable: true + asset: + type: object + allOf: + - $ref: './asset-components.yml#/components/schemas/AssetReference' + nullable: true + text: + type: string + nullable: true + updatedAt: + type: string + format: date-time + nullable: true + + ElementOrigin: + type: string + description: The resolution layer a resolved element value came from. + enum: [APPLICATION, TENANT, PRODUCT_DEFAULT, ELEMENT_DEFAULT, TOKEN_FALLBACK] + + ResolvedElement: + type: object + required: [origin] + properties: + asset: + type: object + allOf: + - $ref: './asset-components.yml#/components/schemas/AssetReference' + nullable: true + text: + type: string + nullable: true + origin: + $ref: '#/components/schemas/ElementOrigin' + + ResolvedFeature: + type: object + description: The effective design element values of one feature for a tenant, optionally scoped to an application and variant. + required: [productType, featureId, tenantId, elements] + properties: + productType: + $ref: '#/components/schemas/ProductType' + featureId: + type: string + tenantId: + type: string + applicationId: + type: string + nullable: true + variant: + type: string + allOf: + - $ref: '#/components/schemas/ThemeVariant' + nullable: true + etag: + type: string + nullable: true + elements: + type: object + additionalProperties: + $ref: '#/components/schemas/ResolvedElement' + description: Map of element id to resolved value. + missingRequired: + type: array + nullable: true + items: + type: string + description: Element ids of required elements that resolved to nothing. + + StylesheetInput: + type: object + required: [css] + properties: + css: + type: string + description: The custom CSS. Existing CSS policy limits apply. + BrandingMetadata: type: object properties: @@ -167,7 +813,7 @@ components: tenantId: type: string nullable: true - appId: + applicationId: type: string nullable: true branding: @@ -186,73 +832,111 @@ components: allOf: - $ref: '#/components/schemas/WebBrandingMetadata' - SimpleBrandInput: + GeneratePaletteInput: type: object - required: [primaryColor, appName] + required: [seedColor] properties: - primaryColor: + seedColor: type: string pattern: '^#[0-9A-Fa-f]{6}$' - example: '#3157D5' - appName: + example: '#6750A4' + + TonalPaletteResult: + type: object + description: A set of tonal values at standard Material Design 3 tone stops. Each value is a hex color string. + required: + - tone0 + - tone10 + - tone20 + - tone30 + - tone40 + - tone50 + - tone60 + - tone70 + - tone80 + - tone90 + - tone95 + - tone99 + - tone100 + properties: + tone0: type: string - example: Acme Wallet - secondaryColor: + tone10: type: string - nullable: true - pattern: '^#[0-9A-Fa-f]{6}$' - logoAssetId: + tone20: type: string - nullable: true - logoDarkAssetId: + tone30: type: string - nullable: true - faviconAssetId: + tone40: type: string - nullable: true - - SimpleBrandOutput: - type: object - required: - - primaryColor - - appName - - generatedTokenCount - - preservedPowerTokenCount - - hasPowerOverrides - properties: - primaryColor: + tone50: type: string - pattern: '^#[0-9A-Fa-f]{6}$' - secondaryColor: + tone60: type: string - nullable: true - pattern: '^#[0-9A-Fa-f]{6}$' - appName: + tone70: type: string - logoUrl: + tone80: type: string - nullable: true - format: uri - logoDarkUrl: + tone90: type: string - nullable: true - format: uri - faviconUrl: + tone95: type: string - nullable: true - format: uri - generatedTokenCount: - type: integer - format: int32 - preservedPowerTokenCount: + tone99: + type: string + tone100: + type: string + + ThemePalette: + type: object + description: A generated tonal palette based on Material Design 3, with the five key color role palettes. + required: [seedColor, primary, secondary, tertiary, neutral, error] + properties: + seedColor: + type: string + example: '#6750A4' + primary: + $ref: '#/components/schemas/TonalPaletteResult' + secondary: + $ref: '#/components/schemas/TonalPaletteResult' + tertiary: + $ref: '#/components/schemas/TonalPaletteResult' + neutral: + $ref: '#/components/schemas/TonalPaletteResult' + error: + $ref: '#/components/schemas/TonalPaletteResult' + + GeneratePaletteOutput: + type: object + required: [palette] + properties: + palette: + $ref: '#/components/schemas/ThemePalette' + + SeedThemeOutput: + type: object + required: [seededCount] + properties: + seededCount: type: integer format: int32 - lastUpdated: + alreadyExisted: + type: boolean + default: false + + PurgeCacheInput: + type: object + properties: + tenant: type: string - format: date-time nullable: true - hasPowerOverrides: + description: Tenant to purge. When omitted, the whole theme resolution cache is purged. + + PurgeCacheOutput: + type: object + properties: + purged: type: boolean + default: true ResolveBrandingContextOutput: type: object diff --git a/theme-openapi.yml b/theme-openapi.yml index ad153bc..48b306e 100644 --- a/theme-openapi.yml +++ b/theme-openapi.yml @@ -4,9 +4,20 @@ info: version: 0.1.0 x-products: [vdx] description: | - VDX theme branding API for tenant simple-brand administration and - runtime theme resolution. This mirrors the existing `vdx-conf-theme-rest` - branding adapter mounted at `/api/theme/v1`. + Tenant branding and theming API. Tenants brand every product surface from one system: + a simple brand (app name, colors, logos, favicon, tagline) set once at tenant level, + full design tokens for pixel control, and per-application overrides for every deployed + instance the tenant runs. Applications have features, and features declare named design + elements (a sign-in logo, a background, a tagline) that are bindable at tenant scope or + per application, optionally per variant. + + Resolution endpoints are public (`security: []`) so pre-auth surfaces such as a login + page can fetch their own theme. The tenant path segment is validated against the tenant + registry; an unknown tenant is a 404. There is never a default tenant fallback, and + headers are never authoritative for tenancy. A known tenant with no definitions resolves + to system defaults with `fallback=true` and `X-Theme-Fallback: true`. + + Resolution and stylesheet GETs return a strong `ETag` and honor `If-None-Match` with 304. servers: - url: https://api.example.com/api/theme/v1 description: Production server. @@ -15,26 +26,859 @@ servers: security: - bearer: [] tags: - - name: ThemeBranding - description: Tenant simple-brand configuration and resolved theme output. + - name: ThemeResolution + description: Public theme, CSS, and feature resolution, plus the cross-domain branding context. + - name: ThemeBrand + description: The tenant simple brand and sparse per-application brand overrides. + - name: ThemeApplications + description: Registry of the tenant's deployed, brandable application instances. + - name: ThemeFeatures + description: Brandable features a product type declares, built-in and custom. + - name: ThemeElements + description: Design element bindings at tenant scope or per application, optionally per variant. + - name: ThemeDefinitions + description: Theme definition CRUD with validation, undo, restore, and history. + - name: ThemeTokens + description: Direct token editing against the canonical definitions. + - name: ThemeStylesheets + description: Tenant and per-application custom CSS stylesheets. + - name: ThemeAdministration + description: Palette generation, tenant theme seeding, and cache purge operations. paths: - /{tenant}/simple-brand: + + # ---- Public resolution ---------------------------------------------------- + + /{tenant}/resolved: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + get: + tags: [ThemeResolution] + summary: Resolve theme + operationId: resolveTheme + x-command-id: theme.rest-resolution.resolve + security: [] + description: | + Resolves the effective theme for a tenant, optionally scoped to a registered + application and variant. Later scopes win: SYSTEM < PRODUCT < TENANT < APPLICATION + < PRINCIPAL; the PRODUCT and APPLICATION layers apply only when `applicationId` is + supplied. Returns 404 for an unknown tenant; a known tenant with no definitions + resolves to system defaults with `fallback=true` and `X-Theme-Fallback: true`. + parameters: + - $ref: './theme-components.yml#/components/parameters/VariantQuery' + - $ref: './theme-components.yml#/components/parameters/ApplicationIdQuery' + - $ref: './theme-components.yml#/components/parameters/ResolutionModeQuery' + - $ref: './theme-components.yml#/components/parameters/IfNoneMatchHeader' + responses: + '200': + description: Resolved theme. + headers: + ETag: + description: Strong ETag over the resolved tokens and applied layers. + schema: + type: string + X-Theme-Fallback: + description: True when the tenant has no definitions and system defaults were served. + schema: + type: boolean + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/ResolvedTheme' + '304': + description: Cached theme is still current. + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + /{tenant}/resolved/css: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + get: + tags: [ThemeResolution] + summary: Resolve theme CSS + operationId: resolveThemeCss + x-command-id: theme.rest-resolution.css + security: [] + description: | + Resolves the effective theme and returns it as CSS custom properties. Same + parameters and tenant semantics as `GET /{tenant}/resolved`. + parameters: + - $ref: './theme-components.yml#/components/parameters/VariantQuery' + - $ref: './theme-components.yml#/components/parameters/ApplicationIdQuery' + - $ref: './theme-components.yml#/components/parameters/ResolutionModeQuery' + - $ref: './theme-components.yml#/components/parameters/IfNoneMatchHeader' + responses: + '200': + description: Resolved theme as CSS custom properties. + headers: + ETag: + description: Strong ETag over the resolved tokens and applied layers. + schema: + type: string + X-Theme-Fallback: + description: True when the tenant has no definitions and system defaults were served. + schema: + type: boolean + content: + text/css: + schema: + type: string + '304': + description: Cached CSS is still current. + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + /{tenant}/applications/{applicationId}/features/{featureId}/resolved: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + - $ref: './theme-components.yml#/components/parameters/ApplicationIdPath' + - $ref: './theme-components.yml#/components/parameters/FeatureIdPath' + get: + tags: [ThemeResolution] + summary: Resolve a feature for an application + operationId: resolveApplicationFeature + x-command-id: theme.rest-feature.resolve + security: [] + description: | + Resolves the design elements of one feature for a registered application: what a + running application fetches for itself. Per element, the first match wins: + application binding (variant, then common), tenant binding (variant, then common), + product default, element default, then the element's fallback token key; a required + element that resolves to nothing is listed in `missingRequired`. + parameters: + - $ref: './theme-components.yml#/components/parameters/VariantQuery' + - $ref: './theme-components.yml#/components/parameters/IfNoneMatchHeader' + responses: + '200': + description: Resolved feature elements. + headers: + ETag: + description: Strong ETag over the resolved element values and origins. + schema: + type: string + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/ResolvedFeature' + '304': + description: Cached feature resolution is still current. + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + /{tenant}/products/{productType}/features/{featureId}/resolved: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + - $ref: './theme-components.yml#/components/parameters/ProductTypePath' + - $ref: './theme-components.yml#/components/parameters/FeatureIdPath' + get: + tags: [ThemeResolution] + summary: Resolve a feature at product level + operationId: resolveProductFeature + x-command-id: theme.rest-feature.resolve-product + security: [] + description: | + Resolves the design elements of one feature at tenant level for a product type, + without an application override layer: the defaults every application of this + product inherits. + parameters: + - $ref: './theme-components.yml#/components/parameters/VariantQuery' + - $ref: './theme-components.yml#/components/parameters/IfNoneMatchHeader' + responses: + '200': + description: Resolved feature elements. + headers: + ETag: + description: Strong ETag over the resolved element values and origins. + schema: + type: string + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/ResolvedFeature' + '304': + description: Cached feature resolution is still current. + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + # ---- Stylesheets ------------------------------------------------------------ + + /{tenant}/stylesheet: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + get: + tags: [ThemeStylesheets] + summary: Get the tenant stylesheet + operationId: getTenantStylesheet + x-command-id: theme.rest-stylesheet.serve + security: [] + description: Serves the tenant's custom CSS stylesheet. Returns 404 for an unknown tenant or when no stylesheet is set. + parameters: + - $ref: './theme-components.yml#/components/parameters/IfNoneMatchHeader' + responses: + '200': + description: The tenant stylesheet. + headers: + ETag: + schema: + type: string + content: + text/css: + schema: + type: string + '304': + description: Cached stylesheet is still current. + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + put: + tags: [ThemeStylesheets] + summary: Set the tenant stylesheet + operationId: setTenantStylesheet + x-command-id: theme.rest-stylesheet.set + requestBody: + required: true + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/StylesheetInput' + responses: + '204': + description: The stylesheet was stored. + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + delete: + tags: [ThemeStylesheets] + summary: Delete the tenant stylesheet + operationId: deleteTenantStylesheet + x-command-id: theme.rest-stylesheet.delete + responses: + '204': + description: The stylesheet was deleted. + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + /{tenant}/applications/{applicationId}/stylesheet: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + - $ref: './theme-components.yml#/components/parameters/ApplicationIdPath' + get: + tags: [ThemeStylesheets] + summary: Get an application stylesheet + operationId: getApplicationStylesheet + x-command-id: theme.rest-stylesheet.serve-application + security: [] + description: Serves the custom CSS stylesheet of one registered application. Returns 404 for an unknown tenant or application, or when no stylesheet is set. + parameters: + - $ref: './theme-components.yml#/components/parameters/IfNoneMatchHeader' + responses: + '200': + description: The application stylesheet. + headers: + ETag: + schema: + type: string + content: + text/css: + schema: + type: string + '304': + description: Cached stylesheet is still current. + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + put: + tags: [ThemeStylesheets] + summary: Set an application stylesheet + operationId: setApplicationStylesheet + x-command-id: theme.rest-stylesheet.set-application + requestBody: + required: true + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/StylesheetInput' + responses: + '204': + description: The stylesheet was stored. + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + delete: + tags: [ThemeStylesheets] + summary: Delete an application stylesheet + operationId: deleteApplicationStylesheet + x-command-id: theme.rest-stylesheet.delete-application + responses: + '204': + description: The stylesheet was deleted. + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + # ---- Brand ------------------------------------------------------------------ + + /{tenant}/brand: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + get: + tags: [ThemeBrand] + summary: Get the tenant brand + operationId: getBrand + x-command-id: theme.rest-brand.get + responses: + '200': + description: The tenant brand. + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/BrandOutput' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + put: + tags: [ThemeBrand] + summary: Set the tenant brand + operationId: setBrand + x-command-id: theme.rest-brand.set + description: >- + Applies the tenant brand and regenerates the palette tokens in the canonical tenant + definitions, preserving power overrides. Simple and advanced modes compose because + they target the same definitions. + requestBody: + required: true + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/BrandInput' + responses: + '200': + description: The updated tenant brand. + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/BrandOutput' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + /{tenant}/applications/{applicationId}/brand: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + - $ref: './theme-components.yml#/components/parameters/ApplicationIdPath' + get: + tags: [ThemeBrand] + summary: Get an application brand + operationId: getApplicationBrand + x-command-id: theme.rest-brand.get-application + responses: + '200': + description: The application brand override. + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/BrandOutput' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + put: + tags: [ThemeBrand] + summary: Set an application brand + operationId: setApplicationBrand + x-command-id: theme.rest-brand.set-application + description: >- + Applies a sparse brand override for one registered application. Set properties + override the tenant brand for this application; omitted properties keep cascading + from the tenant default. + requestBody: + required: true + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/ApplicationBrandInput' + responses: + '200': + description: The updated application brand. + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/BrandOutput' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + delete: + tags: [ThemeBrand] + summary: Delete an application brand + operationId: deleteApplicationBrand + x-command-id: theme.rest-brand.delete-application + description: Removes the application's brand override so it cascades from the tenant brand again. + responses: + '204': + description: The application brand override was deleted. + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + # ---- Applications registry --------------------------------------------------- + + /{tenant}/applications: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + get: + tags: [ThemeApplications] + summary: List applications + operationId: listApplications + x-command-id: theme.rest-application.list + description: >- + Returns every brandable application the tenant runs, as a plain array: + platform-managed instances merged from the platform instance registries plus + applications registered through this API. + responses: + '200': + description: The tenant's applications. + content: + application/json: + schema: + type: array + items: + $ref: './theme-components.yml#/components/schemas/Application' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + post: + tags: [ThemeApplications] + summary: Register an application + operationId: registerApplication + x-command-id: theme.rest-application.register + description: Registers an external application (a self-hosted portal, a mobile app) as a brandable instance. + requestBody: + required: true + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/ApplicationInput' + responses: + '201': + description: The registered application. + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/Application' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + /{tenant}/applications/{applicationId}: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + - $ref: './theme-components.yml#/components/parameters/ApplicationIdPath' + get: + tags: [ThemeApplications] + summary: Get an application + operationId: getApplication + x-command-id: theme.rest-application.get + responses: + '200': + description: The application. + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/Application' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + put: + tags: [ThemeApplications] + summary: Update an application + operationId: updateApplication + x-command-id: theme.rest-application.update + description: Updates a registered application. Platform-managed instances are read-only here and return 409. + requestBody: + required: true + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/ApplicationInput' + responses: + '200': + description: The updated application. + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/Application' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '409': + $ref: './common-components.yml#/components/responses/Conflict' + '500': + $ref: './common-components.yml#/components/responses/Error' + delete: + tags: [ThemeApplications] + summary: Delete an application + operationId: deleteApplication + x-command-id: theme.rest-application.delete + description: Deletes a registered application. Platform-managed instances are read-only here and return 409. + responses: + '204': + description: The application was deleted. + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '409': + $ref: './common-components.yml#/components/responses/Conflict' + '500': + $ref: './common-components.yml#/components/responses/Error' + + # ---- Features ----------------------------------------------------------------- + + /{tenant}/products/{productType}/features: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + - $ref: './theme-components.yml#/components/parameters/ProductTypePath' + get: + tags: [ThemeFeatures] + summary: List features + operationId: listFeatures + x-command-id: theme.rest-feature.list + description: Returns the brandable features of a product type as a plain array, built-in and custom. + responses: + '200': + description: The product's features. + content: + application/json: + schema: + type: array + items: + $ref: './theme-components.yml#/components/schemas/FeatureDefinition' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + post: + tags: [ThemeFeatures] + summary: Create a custom feature + operationId: createFeature + x-command-id: theme.rest-feature.create + description: Registers a custom feature, as published by user-built workflows, forms, and portal pages. + requestBody: + required: true + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/FeatureInput' + responses: + '201': + description: The created feature. + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/FeatureDefinition' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + /{tenant}/products/{productType}/features/{featureId}: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + - $ref: './theme-components.yml#/components/parameters/ProductTypePath' + - $ref: './theme-components.yml#/components/parameters/FeatureIdPath' + get: + tags: [ThemeFeatures] + summary: Get a feature + operationId: getFeature + x-command-id: theme.rest-feature.get + responses: + '200': + description: The feature. + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/FeatureDefinition' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + put: + tags: [ThemeFeatures] + summary: Update a custom feature + operationId: updateFeature + x-command-id: theme.rest-feature.update + description: Updates a custom feature. Built-in features are read-only and return 409. + requestBody: + required: true + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/FeatureInput' + responses: + '200': + description: The updated feature. + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/FeatureDefinition' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '409': + $ref: './common-components.yml#/components/responses/Conflict' + '500': + $ref: './common-components.yml#/components/responses/Error' + delete: + tags: [ThemeFeatures] + summary: Delete a custom feature + operationId: deleteFeature + x-command-id: theme.rest-feature.delete + description: Deletes a custom feature. Built-in features are read-only and return 409. + responses: + '204': + description: The feature was deleted. + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '409': + $ref: './common-components.yml#/components/responses/Conflict' + '500': + $ref: './common-components.yml#/components/responses/Error' + + # ---- Design element bindings ---------------------------------------------------- + + /{tenant}/products/{productType}/features/{featureId}/elements: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + - $ref: './theme-components.yml#/components/parameters/ProductTypePath' + - $ref: './theme-components.yml#/components/parameters/FeatureIdPath' + get: + tags: [ThemeElements] + summary: List element bindings + operationId: listElementBindings + x-command-id: theme.rest-element.list + description: >- + Returns the stored design element bindings of a feature as a plain array. Without + filters, all bindings are returned; `applicationId` and `variant` narrow to one slot. + parameters: + - $ref: './theme-components.yml#/components/parameters/ApplicationIdQuery' + - $ref: './theme-components.yml#/components/parameters/VariantQuery' + responses: + '200': + description: The stored element bindings. + content: + application/json: + schema: + type: array + items: + $ref: './theme-components.yml#/components/schemas/ElementBinding' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + /{tenant}/products/{productType}/features/{featureId}/elements/{elementId}: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + - $ref: './theme-components.yml#/components/parameters/ProductTypePath' + - $ref: './theme-components.yml#/components/parameters/FeatureIdPath' + - $ref: './theme-components.yml#/components/parameters/ElementIdPath' + put: + tags: [ThemeElements] + summary: Set an element binding + operationId: setElementBinding + x-command-id: theme.rest-element.set + description: >- + Binds a value to a design element at tenant scope (`applicationId` absent: the + default for every application of the product) or application scope, optionally per + variant. The `applicationId` and `variant` query parameters select the exact + binding slot. Exactly one of `asset` or `text` is set, matching the element kind. + parameters: + - $ref: './theme-components.yml#/components/parameters/ApplicationIdQuery' + - $ref: './theme-components.yml#/components/parameters/VariantQuery' + requestBody: + required: true + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/ElementBindingInput' + responses: + '200': + description: The stored element binding. + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/ElementBinding' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + delete: + tags: [ThemeElements] + summary: Delete an element binding + operationId: deleteElementBinding + x-command-id: theme.rest-element.delete + description: >- + Removes the binding at the exact slot selected by the `applicationId` and `variant` + query parameters, so resolution falls through to the next layer. + parameters: + - $ref: './theme-components.yml#/components/parameters/ApplicationIdQuery' + - $ref: './theme-components.yml#/components/parameters/VariantQuery' + responses: + '204': + description: The element binding was deleted. + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + # ---- Theme definitions ----------------------------------------------------------- + + /{tenant}/definitions: parameters: - $ref: './theme-components.yml#/components/parameters/TenantPath' get: - tags: [ThemeBranding] - summary: Get simple branding - operationId: getSimpleBrand - x-command-id: theme.rest-simple-brand.get + tags: [ThemeDefinitions] + summary: List theme definitions + operationId: listThemeDefinitions + x-command-id: theme.rest-definition.list + description: Returns the tenant's theme definitions matching the optional filters, as a plain array. parameters: - - $ref: './theme-components.yml#/components/parameters/AppIdQuery' + - $ref: './theme-components.yml#/components/parameters/ScopeQuery' + - $ref: './theme-components.yml#/components/parameters/ProductTypeQuery' + - $ref: './theme-components.yml#/components/parameters/ApplicationIdQuery' + - $ref: './theme-components.yml#/components/parameters/VariantQuery' responses: '200': - description: Simple branding configuration. + description: The matching theme definitions. content: application/json: schema: - $ref: './theme-components.yml#/components/schemas/SimpleBrandOutput' + type: array + items: + $ref: './theme-components.yml#/components/schemas/ThemeDefinition' '401': $ref: './common-components.yml#/components/responses/Unauthorized' '403': @@ -43,66 +887,162 @@ paths: $ref: './common-components.yml#/components/responses/NotFound' '500': $ref: './common-components.yml#/components/responses/Error' - put: - tags: [ThemeBranding] - summary: Set simple branding - operationId: setSimpleBrand - x-command-id: theme.rest-simple-brand.set - description: Applies tenant branding and generates the underlying theme token palette. - parameters: - - $ref: './theme-components.yml#/components/parameters/AppIdQuery' + post: + tags: [ThemeDefinitions] + summary: Create a theme definition + operationId: createThemeDefinition + x-command-id: theme.rest-definition.create + requestBody: + required: true + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/ThemeDefinitionInput' + responses: + '201': + description: The created theme definition. + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/ThemeDefinition' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + /{tenant}/definitions/validate: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + post: + tags: [ThemeDefinitions] + summary: Validate a theme definition + operationId: validateThemeDefinition + x-command-id: theme.rest-definition.validate + description: Validates a theme definition without saving it, including the scope key rules (PRODUCT requires `productType`, APPLICATION requires `applicationId`, other scopes carry neither). requestBody: required: true content: application/json: schema: - $ref: './theme-components.yml#/components/schemas/SimpleBrandInput' + $ref: './theme-components.yml#/components/schemas/ThemeDefinitionInput' responses: '200': - description: Updated simple branding configuration. + description: The validation result. content: application/json: schema: - $ref: './theme-components.yml#/components/schemas/SimpleBrandOutput' + $ref: './theme-components.yml#/components/schemas/ThemeValidationResult' '400': $ref: './common-components.yml#/components/responses/ValidationError' '401': $ref: './common-components.yml#/components/responses/Unauthorized' '403': $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' '500': $ref: './common-components.yml#/components/responses/Error' - /{tenant}/resolved: + /{tenant}/definitions/{themeId}: parameters: - $ref: './theme-components.yml#/components/parameters/TenantPath' + - $ref: './theme-components.yml#/components/parameters/ThemeIdPath' get: - tags: [ThemeBranding] - summary: Resolve theme - operationId: resolveTheme - x-command-id: theme.rest-resolution.resolve - parameters: - - $ref: './theme-components.yml#/components/parameters/VariantQuery' - - $ref: './theme-components.yml#/components/parameters/PrincipalIdQuery' - - $ref: './theme-components.yml#/components/parameters/ResolutionModeQuery' - - $ref: './theme-components.yml#/components/parameters/AppIdQuery' - - $ref: './theme-components.yml#/components/parameters/IfNoneMatchHeader' + tags: [ThemeDefinitions] + summary: Get a theme definition + operationId: getThemeDefinition + x-command-id: theme.rest-definition.get responses: '200': - description: Resolved theme. - headers: - ETag: + description: The theme definition. + content: + application/json: schema: - type: string - X-Theme-Fallback: + $ref: './theme-components.yml#/components/schemas/ThemeDefinition' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + put: + tags: [ThemeDefinitions] + summary: Update a theme definition + operationId: updateThemeDefinition + x-command-id: theme.rest-definition.update + requestBody: + required: true + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/ThemeDefinitionInput' + responses: + '200': + description: The updated theme definition. + content: + application/json: schema: - type: boolean + $ref: './theme-components.yml#/components/schemas/ThemeDefinition' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + delete: + tags: [ThemeDefinitions] + summary: Delete a theme definition + operationId: deleteThemeDefinition + x-command-id: theme.rest-definition.delete + responses: + '204': + description: The theme definition was deleted. + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + /{tenant}/definitions/{themeId}/undo: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + - $ref: './theme-components.yml#/components/parameters/ThemeIdPath' + post: + tags: [ThemeDefinitions] + summary: Undo a theme definition update + operationId: undoThemeDefinition + x-command-id: theme.rest-definition.undo + description: Undoes the last update to a theme definition, or reverts to the version given in the body. + requestBody: + required: false + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/UndoThemeInput' + responses: + '200': + description: The restored theme definition with the version transition. content: application/json: schema: - $ref: './theme-components.yml#/components/schemas/ResolvedTheme' - '304': - description: Cached theme is still current. + $ref: './theme-components.yml#/components/schemas/UndoThemeOutput' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' '401': $ref: './common-components.yml#/components/responses/Unauthorized' '403': @@ -112,36 +1052,175 @@ paths: '500': $ref: './common-components.yml#/components/responses/Error' - /{tenant}/resolved/css: + /{tenant}/definitions/{themeId}/restore: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + - $ref: './theme-components.yml#/components/parameters/ThemeIdPath' + post: + tags: [ThemeDefinitions] + summary: Restore a deleted theme definition + operationId: restoreThemeDefinition + x-command-id: theme.rest-definition.restore + description: Restores a soft-deleted theme definition. + responses: + '200': + description: The restored theme definition. + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/RestoreThemeOutput' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + /{tenant}/definitions/{themeId}/history: parameters: - $ref: './theme-components.yml#/components/parameters/TenantPath' + - $ref: './theme-components.yml#/components/parameters/ThemeIdPath' get: - tags: [ThemeBranding] - summary: Resolve theme CSS - operationId: resolveThemeCss - x-command-id: theme.rest-resolution.css + tags: [ThemeDefinitions] + summary: Get theme definition history + operationId: getThemeDefinitionHistory + x-command-id: theme.rest-definition.history + description: Returns the version history of a theme definition as a plain array, newest first. + responses: + '200': + description: The definition's history entries. + content: + application/json: + schema: + type: array + items: + $ref: './theme-components.yml#/components/schemas/ThemeHistoryEntry' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + # ---- Tokens ---------------------------------------------------------------------- + + /{tenant}/tokens: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + get: + tags: [ThemeTokens] + summary: Get the editable token set + operationId: getTokens + x-command-id: theme.rest-token.get + description: >- + Returns the editable token set with effective values for the addressed + `(scope, variant, applicationId)` combination: tenant scope by default, + application scope when `applicationId` is given. parameters: - $ref: './theme-components.yml#/components/parameters/VariantQuery' - - $ref: './theme-components.yml#/components/parameters/PrincipalIdQuery' - - $ref: './theme-components.yml#/components/parameters/ResolutionModeQuery' - - $ref: './theme-components.yml#/components/parameters/AppIdQuery' - - $ref: './theme-components.yml#/components/parameters/IfNoneMatchHeader' + - $ref: './theme-components.yml#/components/parameters/ApplicationIdQuery' responses: '200': - description: Resolved theme as CSS custom properties. - headers: - ETag: + description: The editable token set. + content: + application/json: schema: - type: string - X-Theme-Fallback: + $ref: './theme-components.yml#/components/schemas/TokenSetOutput' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + patch: + tags: [ThemeTokens] + summary: Patch tokens + operationId: patchTokens + x-command-id: theme.rest-token.patch + description: >- + Upserts and removes tokens in the canonical definition for the addressed + `(scope, variant, applicationId)` combination. Composes with the brand endpoints, + which write the same canonical definitions. + parameters: + - $ref: './theme-components.yml#/components/parameters/VariantQuery' + - $ref: './theme-components.yml#/components/parameters/ApplicationIdQuery' + requestBody: + required: true + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/TokenPatchRequest' + responses: + '200': + description: The token set after the patch. + content: + application/json: schema: - type: boolean + $ref: './theme-components.yml#/components/schemas/TokenSetOutput' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '404': + $ref: './common-components.yml#/components/responses/NotFound' + '500': + $ref: './common-components.yml#/components/responses/Error' + + # ---- Operations --------------------------------------------------------------------- + + /palette/generate: + post: + tags: [ThemeAdministration] + summary: Generate a palette + operationId: generatePalette + x-command-id: theme.rest-palette.generate + description: Generates a Material Design 3 tonal palette from a seed color. + requestBody: + required: true + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/GeneratePaletteInput' + responses: + '200': + description: The generated palette. content: - text/css: + application/json: schema: - type: string - '304': - description: Cached CSS is still current. + $ref: './theme-components.yml#/components/schemas/GeneratePaletteOutput' + '400': + $ref: './common-components.yml#/components/responses/ValidationError' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '500': + $ref: './common-components.yml#/components/responses/Error' + + /{tenant}/seed: + parameters: + - $ref: './theme-components.yml#/components/parameters/TenantPath' + post: + tags: [ThemeAdministration] + summary: Seed default themes + operationId: seedTheme + x-command-id: theme.rest-seed.create + description: Seeds the default theme definitions for a tenant. + responses: + '200': + description: The seeding result. + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/SeedThemeOutput' '401': $ref: './common-components.yml#/components/responses/Unauthorized' '403': @@ -155,15 +1234,17 @@ paths: parameters: - $ref: './theme-components.yml#/components/parameters/TenantPath' get: - tags: [ThemeBranding] + tags: [ThemeResolution] summary: Resolve branding context operationId: resolveBrandingContext x-command-id: theme.rest-branding.resolve + description: Resolves the tenant's branding as a flat, template-friendly key/value context, for cross-domain use such as email templates. parameters: - - $ref: './theme-components.yml#/components/parameters/AppIdQuery' + - $ref: './theme-components.yml#/components/parameters/VariantQuery' + - $ref: './theme-components.yml#/components/parameters/ApplicationIdQuery' responses: '200': - description: Email/template-friendly branding context. + description: Template-friendly branding context. content: application/json: schema: @@ -176,6 +1257,34 @@ paths: $ref: './common-components.yml#/components/responses/NotFound' '500': $ref: './common-components.yml#/components/responses/Error' + + /cache/purge: + post: + tags: [ThemeAdministration] + summary: Purge the theme cache + operationId: purgeThemeCache + x-command-id: theme.rest-cache.purge + description: Purges the theme resolution cache, for one tenant or globally. Platform admin operation. + requestBody: + required: false + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/PurgeCacheInput' + responses: + '200': + description: The purge result. + content: + application/json: + schema: + $ref: './theme-components.yml#/components/schemas/PurgeCacheOutput' + '401': + $ref: './common-components.yml#/components/responses/Unauthorized' + '403': + $ref: './common-components.yml#/components/responses/Forbidden' + '500': + $ref: './common-components.yml#/components/responses/Error' + components: securitySchemes: bearer: From df15f286144468b46060956e93785ceead77618e Mon Sep 17 00:00:00 2001 From: Niels Klomp Date: Tue, 7 Jul 2026 05:03:20 +0200 Subject: [PATCH 8/8] chore: fixes --- command-types.json | 614 ++++++++++++++++++++++++++++++++++++++++++ docs-groups.json | 6 +- manifest-catalog.json | 1 + theme-openapi.yml | 2 +- 4 files changed, 620 insertions(+), 3 deletions(-) create mode 100644 command-types.json diff --git a/command-types.json b/command-types.json new file mode 100644 index 0000000..39e3b5e --- /dev/null +++ b/command-types.json @@ -0,0 +1,614 @@ +{ + "CreateCredentialDesignArgs": { + "kind": "data class", + "name": "CreateCredentialDesignArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class CreateCredentialDesignArgs(\n val tenantId: String,\n val input: CreateCredentialDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class CreateCredentialDesignInput\n @JvmOverloads\n constructor(\n val bindings: List,\n val alias: String? = null,\n val hostingMode: DesignHostingMode = DesignHostingMode.LOCAL,\n val credentialTemplateId: Uuid? = null,\n val issuerDesignId: Uuid? = null,\n val displays: List,\n val claims: List = emptyList(),\n val renderVariantIds: List = emptyList(),\n val credentialType: CredentialTypeDescriptor? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n @SerialName(\"type\")\n val type: String? = null,\n @SerialName(\"@context\")\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\ndata class LocalizedCredentialDisplay\n @JvmOverloads\n constructor(\n val locale: String,\n val name: String,\n val description: String? = null,\n val issuerNameOverride: String? = null,\n val preferredRenderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class ClaimPresentation\n @JvmOverloads\n constructor(\n val path: DesignClaimPath,\n val labels: List,\n val mandatory: Boolean = false,\n val sdPolicy: SdPolicy = SdPolicy.ALLOWED,\n val order: Int = 0,\n val group: String? = null,\n val svgId: String? = null,\n val valueKind: ClaimValueKind? = null,\n val widgetHint: ClaimWidgetHint? = null,\n val markdownAllowed: Boolean = false,\n val entryCodes: List? = null,\n val unit: String? = null,\n val defaultValue: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n @SerialName(\"type\")\n val type: String? = null,\n @SerialName(\"@context\")\n val context: String? = null,\n )" + }, + "CredentialDesignRecord": { + "kind": "data class", + "name": "CredentialDesignRecord", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class CredentialDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val credentialTemplateId: Uuid? = null,\n val issuerDesignId: Uuid? = null,\n val displays: List,\n val claims: List = emptyList(),\n val renderVariantIds: List = emptyList(),\n val derivedRenderHintsId: Uuid? = null,\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n /** Optional OCA semantic attribute set this design draws from. When present, the OCA-backed\n * credential-design resolution derives selective-disclosure and mandatory flags from it. */\n val semanticAttributeSetRef: SemanticAttributeSetRef? = null,\n /** Optional attribute-profile this design draws from. When present, credential-design\n * resolution derives selective-disclosure and mandatory flags from the profile's resolved\n * effective projection in preference to [semanticAttributeSetRef]. The id and pinned\n * version are held as primitives so this IDK contract stays free of the EDK profile types. */\n val attributeProfileId: Uuid? = null,\n val attributeProfileVersion: Long? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n val credentialType: CredentialTypeDescriptor? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n @SerialName(\"type\")\n val type: String? = null,\n @SerialName(\"@context\")\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class LocalizedCredentialDisplay\n @JvmOverloads\n constructor(\n val locale: String,\n val name: String,\n val description: String? = null,\n val issuerNameOverride: String? = null,\n val preferredRenderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class ClaimPresentation\n @JvmOverloads\n constructor(\n val path: DesignClaimPath,\n val labels: List,\n val mandatory: Boolean = false,\n val sdPolicy: SdPolicy = SdPolicy.ALLOWED,\n val order: Int = 0,\n val group: String? = null,\n val svgId: String? = null,\n val valueKind: ClaimValueKind? = null,\n val widgetHint: ClaimWidgetHint? = null,\n val markdownAllowed: Boolean = false,\n val entryCodes: List? = null,\n val unit: String? = null,\n val defaultValue: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class SemanticAttributeSetRef(\n val bundleId: String,\n val version: String? = null,\n)\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n @SerialName(\"type\")\n val type: String? = null,\n @SerialName(\"@context\")\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n data object NONE : QrMode()\n\ntypealias DesignClaimPath = List\n\n@JsExportCompat\n@Serializable\ndata class ClaimLabel\n @JvmOverloads\n constructor(\n val locale: String,\n val label: String,\n val description: String? = null,\n @JsExportIgnoreCompat\n val entryValues: Map? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class SdPolicy {\n ALWAYS,\n ALLOWED,\n NEVER,\n}\n\n@JsExportCompat\n@Serializable\nenum class ClaimValueKind {\n STRING,\n BOOLEAN,\n NUMBER,\n INTEGER,\n ARRAY,\n OBJECT,\n DATE,\n DATE_TIME,\n URI,\n IMAGE,\n BINARY,\n MARKDOWN,\n REFERENCE,\n UNKNOWN,\n}\n\n@JsExportCompat\n@Serializable\nenum class ClaimWidgetHint {\n TEXT,\n MULTILINE_TEXT,\n CHECKBOX,\n BADGE,\n LIST,\n TABLE,\n GROUP,\n DATE,\n DATE_TIME,\n URI,\n IMAGE,\n MARKDOWN,\n HIDDEN,\n PICKLIST,\n FILE,\n}" + }, + "ListDesignsArgs": { + "kind": "data class", + "name": "ListDesignsArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class ListDesignsArgs\n @JvmOverloads\n constructor(\n val tenantId: String,\n val filter: DesignFilter = DesignFilter(),\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignFilter\n @JvmOverloads\n constructor(\n val entityType: DesignEntityType? = null,\n val hostingMode: DesignHostingMode? = null,\n val binding: DesignBinding? = null,\n val bindingKey: DesignBindingKey? = null,\n val bindingValue: String? = null,\n val aliasContains: String? = null,\n val sourceType: DesignSourceType? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignEntityType {\n CREDENTIAL,\n ISSUER,\n VERIFIER,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n @SerialName(\"type\")\n val type: String? = null,\n @SerialName(\"@context\")\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}" + }, + "FindByBindingKeyArgs": { + "kind": "data class", + "name": "FindByBindingKeyArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class FindByBindingKeyArgs(\n val tenantId: String,\n val bindingKey: DesignBindingKey,\n val bindingValue: String,\n)\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}" + }, + "ImportExternalDesignArgs": { + "kind": "data class", + "name": "ImportExternalDesignArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class ImportExternalDesignArgs(\n val tenantId: String,\n val input: ImportExternalDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class ImportExternalDesignInput\n @JvmOverloads\n constructor(\n val entityType: DesignEntityType,\n val bindings: List,\n val alias: String? = null,\n val sourceUrl: String,\n val sourceType: DesignSourceType,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignEntityType {\n CREDENTIAL,\n ISSUER,\n VERIFIER,\n}\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n @SerialName(\"type\")\n val type: String? = null,\n @SerialName(\"@context\")\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}" + }, + "ResolveCredentialDesignArgs": { + "kind": "data class", + "name": "ResolveCredentialDesignArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class ResolveCredentialDesignArgs(\n val tenantId: String,\n val input: ResolveCredentialDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class ResolveCredentialDesignInput\n @JvmOverloads\n constructor(\n val designId: Uuid? = null,\n val binding: DesignBinding? = null,\n val bindingKey: DesignBindingKey? = null,\n val bindingValue: String? = null,\n val preferredLocales: List = emptyList(),\n val renderTarget: RenderVariantKind? = null,\n val externalMetadata: ExternalDesignMetadata? = null,\n val designVersion: Int? = null,\n val activeAt: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n @SerialName(\"type\")\n val type: String? = null,\n @SerialName(\"@context\")\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}\n\n@JsExportCompat\n@Serializable\nenum class RenderVariantKind {\n SIMPLE_CARD,\n SVG_TEMPLATE,\n W3C_RENDER_METHOD,\n PDF_TEMPLATE,\n EXTERNAL_REFERENCE,\n}\n\n@JsExportCompat\n@Serializable\ndata class ExternalDesignMetadata\n @JvmOverloads\n constructor(\n val sdJwtVctMetadata: JsonObject? = null,\n val oid4vciCredentialConfiguration: JsonObject? = null,\n val oid4vciIssuerMetadata: JsonObject? = null,\n val sdJwtIssuerMetadata: JsonObject? = null,\n val jsonSchema: JsonObject? = null,\n val jsonLdContext: JsonObject? = null,\n val oidcDiscovery: JsonObject? = null,\n val openIdFederationEntity: JsonObject? = null,\n val oauthClientRegistration: JsonObject? = null,\n val eidasRegistryData: JsonObject? = null,\n val eidasCatalogueData: JsonObject? = null,\n val w3cRenderMethod: JsonObject? = null,\n val ocaBundle: JsonObject? = null,\n val ocaCaptureBase: JsonObject? = null,\n val ocaOverlays: List = emptyList(),\n val ocaFile: String? = null,\n val overlayFiles: List = emptyList(),\n )" + }, + "ResolvedCredentialDesign": { + "kind": "data class", + "name": "ResolvedCredentialDesign", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class ResolvedCredentialDesign\n @JvmOverloads\n constructor(\n val design: CredentialDesignRecord,\n val issuerDesign: IssuerDesignRecord? = null,\n val verifierDesign: VerifierDesignRecord? = null,\n val renderVariants: List,\n val derivedRenderHints: DerivedRenderHintsRecord? = null,\n val appliedLayers: List,\n @JsExportIgnoreCompat\n val lockedFields: Map,\n val resolvedAt: Instant,\n val etag: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class CredentialDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val credentialTemplateId: Uuid? = null,\n val issuerDesignId: Uuid? = null,\n val displays: List,\n val claims: List = emptyList(),\n val renderVariantIds: List = emptyList(),\n val derivedRenderHintsId: Uuid? = null,\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n /** Optional OCA semantic attribute set this design draws from. When present, the OCA-backed\n * credential-design resolution derives selective-disclosure and mandatory flags from it. */\n val semanticAttributeSetRef: SemanticAttributeSetRef? = null,\n /** Optional attribute-profile this design draws from. When present, credential-design\n * resolution derives selective-disclosure and mandatory flags from the profile's resolved\n * effective projection in preference to [semanticAttributeSetRef]. The id and pinned\n * version are held as primitives so this IDK contract stays free of the EDK profile types. */\n val attributeProfileId: Uuid? = null,\n val attributeProfileVersion: Long? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n val credentialType: CredentialTypeDescriptor? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class IssuerDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val partyId: Uuid? = null,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n )\n\n@JsExportCompat\n@Serializable\ndata class VerifierDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val partyId: Uuid? = null,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n )\n\n@JsExportCompat\n@Serializable\ndata class RenderVariantRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val kind: RenderVariantKind,\n val alias: String? = null,\n val localeApplicability: List = emptyList(),\n val sourceSnapshotId: Uuid? = null,\n val logo: AssetReference? = null,\n val backgroundImage: AssetReference? = null,\n val backgroundColor: String? = null,\n val textColor: String? = null,\n val accentColor: String? = null,\n val svgTemplate: SvgTemplate? = null,\n val w3cRenderMethod: W3cRenderMethodReference? = null,\n val pdfTemplate: AssetReference? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DerivedRenderHintsRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val sourceSnapshotIds: List = emptyList(),\n val fieldHints: List,\n @JsExportIgnoreCompat\n val groupHints: Map> = emptyMap(),\n val defaultOrdering: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class AppliedDesignLayer\n @JvmOverloads\n constructor(\n val sourceType: DesignSourceType,\n val sourceUrl: String? = null,\n val priority: Int,\n val authoritative: Boolean = false,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n @SerialName(\"type\")\n val type: String? = null,\n @SerialName(\"@context\")\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class LocalizedCredentialDisplay\n @JvmOverloads\n constructor(\n val locale: String,\n val name: String,\n val description: String? = null,\n val issuerNameOverride: String? = null,\n val preferredRenderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class ClaimPresentation\n @JvmOverloads\n constructor(\n val path: DesignClaimPath,\n val labels: List,\n val mandatory: Boolean = false,\n val sdPolicy: SdPolicy = SdPolicy.ALLOWED,\n val order: Int = 0,\n val group: String? = null,\n val svgId: String? = null,\n val valueKind: ClaimValueKind? = null,\n val widgetHint: ClaimWidgetHint? = null,\n val markdownAllowed: Boolean = false,\n val entryCodes: List? = null,\n val unit: String? = null,\n val defaultValue: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class SemanticAttributeSetRef(\n val bundleId: String,\n val version: String? = null,\n)\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n @SerialName(\"type\")\n val type: String? = null,\n @SerialName(\"@context\")\n val context: String? = null,\n )" + }, + "GetCredentialDesignArgs": { + "kind": "data class", + "name": "GetCredentialDesignArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class GetCredentialDesignArgs(\n val tenantId: String,\n val id: Uuid,\n)" + }, + "UpdateCredentialDesignArgs": { + "kind": "data class", + "name": "UpdateCredentialDesignArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class UpdateCredentialDesignArgs(\n val tenantId: String,\n val id: Uuid,\n val input: UpdateCredentialDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class UpdateCredentialDesignInput\n @JvmOverloads\n constructor(\n val alias: String? = null,\n val bindings: List? = null,\n val credentialTemplateId: Uuid? = null,\n val issuerDesignId: Uuid? = null,\n val displays: List? = null,\n val claims: List? = null,\n val renderVariantIds: List? = null,\n val hostingMode: DesignHostingMode? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n @SerialName(\"type\")\n val type: String? = null,\n @SerialName(\"@context\")\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class LocalizedCredentialDisplay\n @JvmOverloads\n constructor(\n val locale: String,\n val name: String,\n val description: String? = null,\n val issuerNameOverride: String? = null,\n val preferredRenderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class ClaimPresentation\n @JvmOverloads\n constructor(\n val path: DesignClaimPath,\n val labels: List,\n val mandatory: Boolean = false,\n val sdPolicy: SdPolicy = SdPolicy.ALLOWED,\n val order: Int = 0,\n val group: String? = null,\n val svgId: String? = null,\n val valueKind: ClaimValueKind? = null,\n val widgetHint: ClaimWidgetHint? = null,\n val markdownAllowed: Boolean = false,\n val entryCodes: List? = null,\n val unit: String? = null,\n val defaultValue: String? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n @SerialName(\"type\")\n val type: String? = null,\n @SerialName(\"@context\")\n val context: String? = null,\n )" + }, + "DeleteDesignArgs": { + "kind": "data class", + "name": "DeleteDesignArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class DeleteDesignArgs(\n val tenantId: String,\n val id: Uuid,\n)" + }, + "RefreshDesignArgs": { + "kind": "data class", + "name": "RefreshDesignArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class RefreshDesignArgs(\n val tenantId: String,\n val designId: Uuid,\n)" + }, + "CreateIssuerDesignArgs": { + "kind": "data class", + "name": "CreateIssuerDesignArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class CreateIssuerDesignArgs(\n val tenantId: String,\n val input: CreateIssuerDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class CreateIssuerDesignInput\n @JvmOverloads\n constructor(\n val bindings: List,\n val partyId: Uuid? = null,\n val alias: String? = null,\n val hostingMode: DesignHostingMode = DesignHostingMode.LOCAL,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n @SerialName(\"type\")\n val type: String? = null,\n @SerialName(\"@context\")\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\ndata class EntityLocaleDesign\n @JvmOverloads\n constructor(\n val locale: String,\n val displayName: String? = null,\n val description: String? = null,\n val logo: AssetReference? = null,\n )" + }, + "IssuerDesignRecord": { + "kind": "data class", + "name": "IssuerDesignRecord", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class IssuerDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val partyId: Uuid? = null,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n @SerialName(\"type\")\n val type: String? = null,\n @SerialName(\"@context\")\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class EntityLocaleDesign\n @JvmOverloads\n constructor(\n val locale: String,\n val displayName: String? = null,\n val description: String? = null,\n val logo: AssetReference? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class VctHostingMode {\n HOSTED,\n EXTERNAL,\n REGISTERED,\n NONE,\n}\n\n data object NONE : QrMode()\n\n@JsExportCompat\n@Serializable\ndata class CredentialTypeDescriptor\n @JvmOverloads\n constructor(\n val format: CredentialTypeFormat,\n val vct: String? = null,\n val docType: String? = null,\n @SerialName(\"type\")\n val type: String? = null,\n @SerialName(\"@context\")\n val context: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class AssetReference\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val altText: String? = null,\n val contentType: String? = null,\n val localBlob: BlobInfo? = null,\n )" + }, + "ResolveIssuerDesignArgs": { + "kind": "data class", + "name": "ResolveIssuerDesignArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class ResolveIssuerDesignArgs(\n val tenantId: String,\n val input: ResolveEntityDesignInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class ResolveEntityDesignInput\n @JvmOverloads\n constructor(\n val designId: Uuid? = null,\n val binding: DesignBinding? = null,\n val bindingKey: DesignBindingKey? = null,\n val bindingValue: String? = null,\n val preferredLocales: List = emptyList(),\n val externalMetadata: ExternalDesignMetadata? = null,\n val designVersion: Int? = null,\n val activeAt: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n @SerialName(\"type\")\n val type: String? = null,\n @SerialName(\"@context\")\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}\n\n@JsExportCompat\n@Serializable\ndata class ExternalDesignMetadata\n @JvmOverloads\n constructor(\n val sdJwtVctMetadata: JsonObject? = null,\n val oid4vciCredentialConfiguration: JsonObject? = null,\n val oid4vciIssuerMetadata: JsonObject? = null,\n val sdJwtIssuerMetadata: JsonObject? = null,\n val jsonSchema: JsonObject? = null,\n val jsonLdContext: JsonObject? = null,\n val oidcDiscovery: JsonObject? = null,\n val openIdFederationEntity: JsonObject? = null,\n val oauthClientRegistration: JsonObject? = null,\n val eidasRegistryData: JsonObject? = null,\n val eidasCatalogueData: JsonObject? = null,\n val w3cRenderMethod: JsonObject? = null,\n val ocaBundle: JsonObject? = null,\n val ocaCaptureBase: JsonObject? = null,\n val ocaOverlays: List = emptyList(),\n val ocaFile: String? = null,\n val overlayFiles: List = emptyList(),\n )" + }, + "ResolvedIssuerDesign": { + "kind": "data class", + "name": "ResolvedIssuerDesign", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class ResolvedIssuerDesign\n @JvmOverloads\n constructor(\n val design: IssuerDesignRecord,\n val renderVariants: List,\n val appliedLayers: List,\n @JsExportIgnoreCompat\n val lockedFields: Map,\n val resolvedAt: Instant,\n val etag: String? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class IssuerDesignRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val alias: String? = null,\n val hostingMode: DesignHostingMode,\n val bindings: List,\n val partyId: Uuid? = null,\n val displays: List,\n val renderVariantIds: List = emptyList(),\n val sourceSnapshotIds: List = emptyList(),\n val contentHash: String? = null,\n val createdAt: Instant,\n val updatedAt: Instant,\n )\n\n@JsExportCompat\n@Serializable\ndata class RenderVariantRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val kind: RenderVariantKind,\n val alias: String? = null,\n val localeApplicability: List = emptyList(),\n val sourceSnapshotId: Uuid? = null,\n val logo: AssetReference? = null,\n val backgroundImage: AssetReference? = null,\n val backgroundColor: String? = null,\n val textColor: String? = null,\n val accentColor: String? = null,\n val svgTemplate: SvgTemplate? = null,\n val w3cRenderMethod: W3cRenderMethodReference? = null,\n val pdfTemplate: AssetReference? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class AppliedDesignLayer\n @JvmOverloads\n constructor(\n val sourceType: DesignSourceType,\n val sourceUrl: String? = null,\n val priority: Int,\n val authoritative: Boolean = false,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n @SerialName(\"type\")\n val type: String? = null,\n @SerialName(\"@context\")\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class EntityLocaleDesign\n @JvmOverloads\n constructor(\n val locale: String,\n val displayName: String? = null,\n val description: String? = null,\n val logo: AssetReference? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class RenderVariantKind {\n SIMPLE_CARD,\n SVG_TEMPLATE,\n W3C_RENDER_METHOD,\n PDF_TEMPLATE,\n EXTERNAL_REFERENCE,\n}\n\n@JsExportCompat\n@Serializable\ndata class AssetReference\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val altText: String? = null,\n val contentType: String? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class SvgTemplate\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val orientation: SvgOrientation? = null,\n val colorScheme: SvgColorScheme? = null,\n val contrast: SvgContrast? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class W3cRenderMethodReference\n @JvmOverloads\n constructor(\n val type: String,\n val renderSuite: String? = null,\n val uri: String,\n val mediaType: String? = null,\n val name: String? = null,\n val description: String? = null,\n val digestMultibase: String? = null,\n val renderProperties: List? = null,\n )" + }, + "CreateRenderVariantArgs": { + "kind": "data class", + "name": "CreateRenderVariantArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class CreateRenderVariantArgs(\n val tenantId: String,\n val input: CreateRenderVariantInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class CreateRenderVariantInput\n @JvmOverloads\n constructor(\n val kind: RenderVariantKind,\n val alias: String? = null,\n val localeApplicability: List = emptyList(),\n val logo: AssetReference? = null,\n val backgroundImage: AssetReference? = null,\n val backgroundColor: String? = null,\n val textColor: String? = null,\n val accentColor: String? = null,\n val svgTemplate: SvgTemplate? = null,\n val w3cRenderMethod: W3cRenderMethodReference? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class RenderVariantKind {\n SIMPLE_CARD,\n SVG_TEMPLATE,\n W3C_RENDER_METHOD,\n PDF_TEMPLATE,\n EXTERNAL_REFERENCE,\n}\n\n@JsExportCompat\n@Serializable\ndata class AssetReference\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val altText: String? = null,\n val contentType: String? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class SvgTemplate\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val orientation: SvgOrientation? = null,\n val colorScheme: SvgColorScheme? = null,\n val contrast: SvgContrast? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class W3cRenderMethodReference\n @JvmOverloads\n constructor(\n val type: String,\n val renderSuite: String? = null,\n val uri: String,\n val mediaType: String? = null,\n val name: String? = null,\n val description: String? = null,\n val digestMultibase: String? = null,\n val renderProperties: List? = null,\n )" + }, + "RenderVariantRecord": { + "kind": "data class", + "name": "RenderVariantRecord", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class RenderVariantRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val kind: RenderVariantKind,\n val alias: String? = null,\n val localeApplicability: List = emptyList(),\n val sourceSnapshotId: Uuid? = null,\n val logo: AssetReference? = null,\n val backgroundImage: AssetReference? = null,\n val backgroundColor: String? = null,\n val textColor: String? = null,\n val accentColor: String? = null,\n val svgTemplate: SvgTemplate? = null,\n val w3cRenderMethod: W3cRenderMethodReference? = null,\n val pdfTemplate: AssetReference? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class RenderVariantKind {\n SIMPLE_CARD,\n SVG_TEMPLATE,\n W3C_RENDER_METHOD,\n PDF_TEMPLATE,\n EXTERNAL_REFERENCE,\n}\n\n@JsExportCompat\n@Serializable\ndata class AssetReference\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val altText: String? = null,\n val contentType: String? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class SvgTemplate\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val orientation: SvgOrientation? = null,\n val colorScheme: SvgColorScheme? = null,\n val contrast: SvgContrast? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class W3cRenderMethodReference\n @JvmOverloads\n constructor(\n val type: String,\n val renderSuite: String? = null,\n val uri: String,\n val mediaType: String? = null,\n val name: String? = null,\n val description: String? = null,\n val digestMultibase: String? = null,\n val renderProperties: List? = null,\n )\n\n@Serializable\n@SerialName(\"blob-info\")\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"BlobInfo\", exact = true)\ndata class BlobInfo(\n override val storeId: String? = null,\n override val path: String? = null,\n override val tenantId: String? = null,\n override val contentType: String? = null,\n override val metadata: Map = emptyMap(),\n @Transient\n val opts: Map = emptyMap(),\n) : BlobInfoType {\n override fun toBlobInfo(): BlobInfo = this\n\n /**\n * Returns a [BlobMetadata] from this info's content type and custom metadata.\n */\n fun toBlobMetadata(): BlobMetadata =\n BlobMetadata(\n contentType = contentType,\n custom = metadata,\n )\n\n /**\n * Lightweight identity for use as map keys and cache lookups.\n * Like [KeyIdentity] — deterministic equality without transient fields.\n */\n fun toIdentity(): BlobIdentity =\n BlobIdentity(\n storeId = storeId,\n path = path,\n tenantId = tenantId,\n )\n\n /** Creates a copy targeting a different path. */\n fun withPath(newPath: String): BlobInfo = copy(path = newPath)\n\n /** Creates a copy targeting a different store. */\n fun withStore(newStoreId: String): BlobInfo = copy(storeId = newStoreId)\n\n companion object {\n fun of(\n storeId: String,\n path: String,\n ) = BlobInfo(storeId = storeId, path = path)\n\n fun fromDescriptor(\n descriptor: BlobDescriptor,\n tenantId: String? = null,\n ) = BlobInfo(\n storeId = descriptor.storeId,\n path = descriptor.path,\n tenantId = tenantId,\n contentType = descriptor.contentType,\n metadata = descriptor.metadata.custom,\n )\n\n /**\n * Validates a blob path for security:\n * - Rejects path traversal segments (`..`)\n * - Rejects null bytes\n * - Rejects absolute paths\n * - Rejects backslash separators\n */\n fun validatePath(path: String) {\n require(!path.contains('\\u0000')) { \"Blob path must not contain null bytes\" }\n require(!path.startsWith('/')) { \"Blob path must not be absolute\" }\n require(!path.contains('\\\\')) { \"Blob path must use '/' separators, not '\\\\'\" }\n val segments = path.split('/')\n require(segments.none { it == \"..\" }) { \"Blob path must not contain '..' traversal segments: $path\" }\n require(segments.none { it == \".\" }) { \"Blob path must not contain '.' self-reference segments: $path\" }\n }\n\n /**\n * Sanitizes and normalizes a user-provided path. Returns a safe path string.\n * Throws [IllegalArgumentException] if the path is malicious.\n */\n fun sanitizePath(path: String): String {\n val normalized =\n path\n .replace('\\\\', '/')\n .replace(Regex(\"/+\"), \"/\")\n .trimStart('/')\n .trimEnd('/')\n require(normalized.isNotBlank()) { \"Sanitized path must not be blank\" }\n validatePath(normalized)\n return normalized\n }\n }\n}\n\n@JsExportCompat\n@Serializable\nenum class SvgOrientation { PORTRAIT, LANDSCAPE }\n\n@JsExportCompat\n@Serializable\nenum class SvgColorScheme { LIGHT, DARK }\n\n@JsExportCompat\n@Serializable\nenum class SvgContrast { NORMAL, HIGH }" + }, + "ListRenderVariantsArgs": { + "kind": "data class", + "name": "ListRenderVariantsArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class ListRenderVariantsArgs\n @JvmOverloads\n constructor(\n val tenantId: String,\n val filter: DesignFilter = DesignFilter(),\n )\n\n@JsExportCompat\n@Serializable\ndata class DesignFilter\n @JvmOverloads\n constructor(\n val entityType: DesignEntityType? = null,\n val hostingMode: DesignHostingMode? = null,\n val binding: DesignBinding? = null,\n val bindingKey: DesignBindingKey? = null,\n val bindingValue: String? = null,\n val aliasContains: String? = null,\n val sourceType: DesignSourceType? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignEntityType {\n CREDENTIAL,\n ISSUER,\n VERIFIER,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignHostingMode {\n LOCAL,\n CACHED_EXTERNAL,\n INFERRED,\n}\n\n@JsExportCompat\n@Serializable\ndata class DesignBinding\n @JvmOverloads\n constructor(\n val vct: String? = null,\n val vctHostingMode: VctHostingMode = VctHostingMode.NONE,\n val credentialConfigurationId: String? = null,\n val schemaId: String? = null,\n val docType: String? = null,\n @SerialName(\"type\")\n val type: String? = null,\n @SerialName(\"@context\")\n val context: String? = null,\n val issuerId: String? = null,\n val issuerDid: String? = null,\n val issuerUri: String? = null,\n val verifierClientId: String? = null,\n val ocaSaid: String? = null,\n val credentialType: CredentialTypeDescriptor? = null,\n val credentialDesignId: Uuid? = null,\n val credentialDesignVersion: Int? = null,\n val activeFrom: Instant? = null,\n val activeUntil: Instant? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignBindingKey {\n VCT,\n VCT_HOSTING_MODE,\n CREDENTIAL_CONFIGURATION_ID,\n SCHEMA_ID,\n DOC_TYPE,\n TYPE,\n CONTEXT,\n ISSUER_ID,\n ISSUER_DID,\n ISSUER_URI,\n VERIFIER_CLIENT_ID,\n OCA_SAID,\n CREDENTIAL_TYPE_FORMAT,\n CREDENTIAL_DESIGN_ID,\n CREDENTIAL_DESIGN_VERSION,\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}" + }, + "GetSourceSnapshotArgs": { + "kind": "data class", + "name": "GetSourceSnapshotArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class GetSourceSnapshotArgs(\n val tenantId: String,\n val snapshotId: Uuid,\n)" + }, + "SourceSnapshotRecord": { + "kind": "data class", + "name": "SourceSnapshotRecord", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class SourceSnapshotRecord\n @JvmOverloads\n constructor(\n val id: Uuid,\n val tenantId: String,\n val sourceType: DesignSourceType,\n val sourceUrl: String? = null,\n val etag: String? = null,\n val integrity: String? = null,\n val said: String? = null,\n val fetchedAt: Instant,\n val contentBlob: BlobInfo,\n val normalizedFromVersion: String? = null,\n )\n\n@JsExportCompat\n@Serializable\nenum class DesignSourceType {\n LOCAL_OVERRIDE,\n LOCAL_SHARED,\n SCHEMA_INFERENCE,\n JSON_LD_CONTEXT,\n CREDENTIAL_TEMPLATE,\n PARTY_STORE,\n SD_JWT_VCT_METADATA,\n SD_JWT_ISSUER_METADATA,\n OID4VCI_CREDENTIAL_CONFIGURATION,\n OID4VCI_ISSUER_METADATA,\n OIDC_DISCOVERY,\n OPENID_FEDERATION,\n OAUTH_CLIENT_REGISTRATION,\n EIDAS_REGISTRY,\n EIDAS_CREDENTIAL_CATALOGUE,\n W3C_VC_RENDER_METHOD,\n OCA_BUNDLE,\n MANUAL_IMPORT,\n}\n\n@Serializable\n@SerialName(\"blob-info\")\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"BlobInfo\", exact = true)\ndata class BlobInfo(\n override val storeId: String? = null,\n override val path: String? = null,\n override val tenantId: String? = null,\n override val contentType: String? = null,\n override val metadata: Map = emptyMap(),\n @Transient\n val opts: Map = emptyMap(),\n) : BlobInfoType {\n override fun toBlobInfo(): BlobInfo = this\n\n /**\n * Returns a [BlobMetadata] from this info's content type and custom metadata.\n */\n fun toBlobMetadata(): BlobMetadata =\n BlobMetadata(\n contentType = contentType,\n custom = metadata,\n )\n\n /**\n * Lightweight identity for use as map keys and cache lookups.\n * Like [KeyIdentity] — deterministic equality without transient fields.\n */\n fun toIdentity(): BlobIdentity =\n BlobIdentity(\n storeId = storeId,\n path = path,\n tenantId = tenantId,\n )\n\n /** Creates a copy targeting a different path. */\n fun withPath(newPath: String): BlobInfo = copy(path = newPath)\n\n /** Creates a copy targeting a different store. */\n fun withStore(newStoreId: String): BlobInfo = copy(storeId = newStoreId)\n\n companion object {\n fun of(\n storeId: String,\n path: String,\n ) = BlobInfo(storeId = storeId, path = path)\n\n fun fromDescriptor(\n descriptor: BlobDescriptor,\n tenantId: String? = null,\n ) = BlobInfo(\n storeId = descriptor.storeId,\n path = descriptor.path,\n tenantId = tenantId,\n contentType = descriptor.contentType,\n metadata = descriptor.metadata.custom,\n )\n\n /**\n * Validates a blob path for security:\n * - Rejects path traversal segments (`..`)\n * - Rejects null bytes\n * - Rejects absolute paths\n * - Rejects backslash separators\n */\n fun validatePath(path: String) {\n require(!path.contains('\\u0000')) { \"Blob path must not contain null bytes\" }\n require(!path.startsWith('/')) { \"Blob path must not be absolute\" }\n require(!path.contains('\\\\')) { \"Blob path must use '/' separators, not '\\\\'\" }\n val segments = path.split('/')\n require(segments.none { it == \"..\" }) { \"Blob path must not contain '..' traversal segments: $path\" }\n require(segments.none { it == \".\" }) { \"Blob path must not contain '.' self-reference segments: $path\" }\n }\n\n /**\n * Sanitizes and normalizes a user-provided path. Returns a safe path string.\n * Throws [IllegalArgumentException] if the path is malicious.\n */\n fun sanitizePath(path: String): String {\n val normalized =\n path\n .replace('\\\\', '/')\n .replace(Regex(\"/+\"), \"/\")\n .trimStart('/')\n .trimEnd('/')\n require(normalized.isNotBlank()) { \"Sanitized path must not be blank\" }\n validatePath(normalized)\n return normalized\n }\n }\n}\n\n@Serializable\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"BlobInfoType\", exact = true)\n@JsExportCompat\nsealed interface BlobInfoType {\n val storeId: String?\n val path: String?\n val tenantId: String?\n val contentType: String?\n\n @JsExportIgnoreCompat\n val metadata: Map\n\n /** Extract the unresolved [BlobInfo] from any variant. */\n fun toBlobInfo(): BlobInfo\n}\n\n@Serializable\n@JsExportCompat\ndata class BlobMetadata(\n val contentType: String? = null,\n val contentEncoding: String? = null,\n val contentDisposition: String? = null,\n @JsExportIgnoreCompat\n val custom: Map = emptyMap(),\n val contentHash: String? = null,\n val retentionHint: RetentionHint? = null,\n /** Consumer-supplied sensitivity classification hint (e.g., \"CONFIDENTIAL\"). */\n val classification: String? = null,\n /** Consumer-supplied legal basis hint (e.g., \"gdpr.art6.1a.consent\"). */\n val legalBasis: String? = null,\n /** Consumer-supplied retention-days hint; authoritative value lives on the consumer row. */\n val retentionDays: Int? = null,\n /** Consumer-supplied processing-purpose hint (GDPR Art. 5(1)(b)). */\n val processingPurpose: String? = null,\n /** Consumer-supplied jurisdiction hint (e.g., \"EU-NL\"). */\n val jurisdiction: String? = null,\n) {\n companion object {\n val EMPTY = BlobMetadata()\n\n fun ofContentType(contentType: String) = BlobMetadata(contentType = contentType)\n }\n}\n\n@Serializable\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"BlobIdentity\", exact = true)\n@JsExportCompat\ndata class BlobIdentity(\n val storeId: String? = null,\n val path: String? = null,\n val tenantId: String? = null,\n) {\n fun hasIdentity(): Boolean = path != null\n}\n\n@Serializable\n@JsExportCompat\ndata class BlobDescriptor(\n val path: String,\n /**\n * The CONFIGURED registry id of the store this blob lives in (e.g. `\"default\"` from\n * `blob.stores.default.*`), NOT the backend scheme id ([BlobStore.schemeId], e.g. `\"memory\"`\n * or `\"filesystem\"`).\n *\n * Backend [BlobStore] implementations stamp their own scheme id here, but [BlobService]\n * normalises it to the configured id on every caller-facing descriptor before it leaves the\n * service. Callers may therefore round-trip this value straight back into [BlobInfo.storeId]\n * for a subsequent operation. Descriptors observed directly from a [BlobStore] (below the\n * service boundary) still carry the scheme id.\n */\n val storeId: String,\n val sizeBytes: Long,\n val contentType: String? = null,\n val filename: String? = null,\n val etag: String? = null,\n val createdAt: Instant? = null,\n val lastModified: Instant? = null,\n val metadata: BlobMetadata = BlobMetadata.EMPTY,\n val contentHash: String? = null,\n /** Consumer-supplied sensitivity classification hint mirrored from [BlobMetadata.classification]. */\n val classification: String? = null,\n /** Consumer-supplied legal basis hint mirrored from [BlobMetadata.legalBasis]. */\n val legalBasis: String? = null,\n /** Consumer-supplied retention-days hint mirrored from [BlobMetadata.retentionDays]. */\n val retentionDays: Int? = null,\n /** Consumer-supplied processing-purpose hint mirrored from [BlobMetadata.processingPurpose]. */\n val processingPurpose: String? = null,\n /** Consumer-supplied jurisdiction hint mirrored from [BlobMetadata.jurisdiction]. */\n val jurisdiction: String? = null,\n)" + }, + "RefreshSourceSnapshotArgs": { + "kind": "data class", + "name": "RefreshSourceSnapshotArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class RefreshSourceSnapshotArgs(\n val tenantId: String,\n val snapshotId: Uuid,\n)" + }, + "UploadDesignAssetArgs": { + "kind": "data class", + "name": "UploadDesignAssetArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class UploadDesignAssetArgs(\n val tenantId: String,\n val input: UploadDesignAssetInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class UploadDesignAssetInput(\n val designId: Uuid,\n val locale: String,\n val assetType: DesignAssetType,\n val data: ByteArray,\n val contentType: String,\n) {\n override fun equals(other: Any?): Boolean {\n if (this === other) {\n return true\n }\n if (other !is UploadDesignAssetInput) {\n return false\n }\n return designId == other.designId && locale == other.locale && assetType == other.assetType &&\n data.contentEquals(other.data) && contentType == other.contentType\n }\n\n override fun hashCode(): Int {\n var result = designId.hashCode()\n result = 31 * result + locale.hashCode()\n result = 31 * result + assetType.hashCode()\n result = 31 * result + data.contentHashCode()\n result = 31 * result + contentType.hashCode()\n return result\n }\n}\n\n@JsExportCompat\n@Serializable\nenum class DesignAssetType {\n LOGO,\n BACKGROUND_IMAGE,\n SVG_TEMPLATE,\n PDF_TEMPLATE,\n}" + }, + "AssetReference": { + "kind": "data class", + "name": "AssetReference", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class AssetReference\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val altText: String? = null,\n val contentType: String? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@Serializable\n@SerialName(\"blob-info\")\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"BlobInfo\", exact = true)\ndata class BlobInfo(\n override val storeId: String? = null,\n override val path: String? = null,\n override val tenantId: String? = null,\n override val contentType: String? = null,\n override val metadata: Map = emptyMap(),\n @Transient\n val opts: Map = emptyMap(),\n) : BlobInfoType {\n override fun toBlobInfo(): BlobInfo = this\n\n /**\n * Returns a [BlobMetadata] from this info's content type and custom metadata.\n */\n fun toBlobMetadata(): BlobMetadata =\n BlobMetadata(\n contentType = contentType,\n custom = metadata,\n )\n\n /**\n * Lightweight identity for use as map keys and cache lookups.\n * Like [KeyIdentity] — deterministic equality without transient fields.\n */\n fun toIdentity(): BlobIdentity =\n BlobIdentity(\n storeId = storeId,\n path = path,\n tenantId = tenantId,\n )\n\n /** Creates a copy targeting a different path. */\n fun withPath(newPath: String): BlobInfo = copy(path = newPath)\n\n /** Creates a copy targeting a different store. */\n fun withStore(newStoreId: String): BlobInfo = copy(storeId = newStoreId)\n\n companion object {\n fun of(\n storeId: String,\n path: String,\n ) = BlobInfo(storeId = storeId, path = path)\n\n fun fromDescriptor(\n descriptor: BlobDescriptor,\n tenantId: String? = null,\n ) = BlobInfo(\n storeId = descriptor.storeId,\n path = descriptor.path,\n tenantId = tenantId,\n contentType = descriptor.contentType,\n metadata = descriptor.metadata.custom,\n )\n\n /**\n * Validates a blob path for security:\n * - Rejects path traversal segments (`..`)\n * - Rejects null bytes\n * - Rejects absolute paths\n * - Rejects backslash separators\n */\n fun validatePath(path: String) {\n require(!path.contains('\\u0000')) { \"Blob path must not contain null bytes\" }\n require(!path.startsWith('/')) { \"Blob path must not be absolute\" }\n require(!path.contains('\\\\')) { \"Blob path must use '/' separators, not '\\\\'\" }\n val segments = path.split('/')\n require(segments.none { it == \"..\" }) { \"Blob path must not contain '..' traversal segments: $path\" }\n require(segments.none { it == \".\" }) { \"Blob path must not contain '.' self-reference segments: $path\" }\n }\n\n /**\n * Sanitizes and normalizes a user-provided path. Returns a safe path string.\n * Throws [IllegalArgumentException] if the path is malicious.\n */\n fun sanitizePath(path: String): String {\n val normalized =\n path\n .replace('\\\\', '/')\n .replace(Regex(\"/+\"), \"/\")\n .trimStart('/')\n .trimEnd('/')\n require(normalized.isNotBlank()) { \"Sanitized path must not be blank\" }\n validatePath(normalized)\n return normalized\n }\n }\n}\n\n@Serializable\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"BlobInfoType\", exact = true)\n@JsExportCompat\nsealed interface BlobInfoType {\n val storeId: String?\n val path: String?\n val tenantId: String?\n val contentType: String?\n\n @JsExportIgnoreCompat\n val metadata: Map\n\n /** Extract the unresolved [BlobInfo] from any variant. */\n fun toBlobInfo(): BlobInfo\n}\n\n@Serializable\n@JsExportCompat\ndata class BlobMetadata(\n val contentType: String? = null,\n val contentEncoding: String? = null,\n val contentDisposition: String? = null,\n @JsExportIgnoreCompat\n val custom: Map = emptyMap(),\n val contentHash: String? = null,\n val retentionHint: RetentionHint? = null,\n /** Consumer-supplied sensitivity classification hint (e.g., \"CONFIDENTIAL\"). */\n val classification: String? = null,\n /** Consumer-supplied legal basis hint (e.g., \"gdpr.art6.1a.consent\"). */\n val legalBasis: String? = null,\n /** Consumer-supplied retention-days hint; authoritative value lives on the consumer row. */\n val retentionDays: Int? = null,\n /** Consumer-supplied processing-purpose hint (GDPR Art. 5(1)(b)). */\n val processingPurpose: String? = null,\n /** Consumer-supplied jurisdiction hint (e.g., \"EU-NL\"). */\n val jurisdiction: String? = null,\n) {\n companion object {\n val EMPTY = BlobMetadata()\n\n fun ofContentType(contentType: String) = BlobMetadata(contentType = contentType)\n }\n}\n\n@Serializable\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"BlobIdentity\", exact = true)\n@JsExportCompat\ndata class BlobIdentity(\n val storeId: String? = null,\n val path: String? = null,\n val tenantId: String? = null,\n) {\n fun hasIdentity(): Boolean = path != null\n}\n\n@Serializable\n@JsExportCompat\ndata class BlobDescriptor(\n val path: String,\n /**\n * The CONFIGURED registry id of the store this blob lives in (e.g. `\"default\"` from\n * `blob.stores.default.*`), NOT the backend scheme id ([BlobStore.schemeId], e.g. `\"memory\"`\n * or `\"filesystem\"`).\n *\n * Backend [BlobStore] implementations stamp their own scheme id here, but [BlobService]\n * normalises it to the configured id on every caller-facing descriptor before it leaves the\n * service. Callers may therefore round-trip this value straight back into [BlobInfo.storeId]\n * for a subsequent operation. Descriptors observed directly from a [BlobStore] (below the\n * service boundary) still carry the scheme id.\n */\n val storeId: String,\n val sizeBytes: Long,\n val contentType: String? = null,\n val filename: String? = null,\n val etag: String? = null,\n val createdAt: Instant? = null,\n val lastModified: Instant? = null,\n val metadata: BlobMetadata = BlobMetadata.EMPTY,\n val contentHash: String? = null,\n /** Consumer-supplied sensitivity classification hint mirrored from [BlobMetadata.classification]. */\n val classification: String? = null,\n /** Consumer-supplied legal basis hint mirrored from [BlobMetadata.legalBasis]. */\n val legalBasis: String? = null,\n /** Consumer-supplied retention-days hint mirrored from [BlobMetadata.retentionDays]. */\n val retentionDays: Int? = null,\n /** Consumer-supplied processing-purpose hint mirrored from [BlobMetadata.processingPurpose]. */\n val processingPurpose: String? = null,\n /** Consumer-supplied jurisdiction hint mirrored from [BlobMetadata.jurisdiction]. */\n val jurisdiction: String? = null,\n)" + }, + "GetDesignAssetArgs": { + "kind": "data class", + "name": "GetDesignAssetArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class GetDesignAssetArgs(\n val tenantId: String,\n val input: GetDesignAssetInput,\n)\n\n@JsExportCompat\n@Serializable\ndata class GetDesignAssetInput(\n val designId: Uuid,\n val locale: String,\n val assetType: DesignAssetType,\n)\n\n@JsExportCompat\n@Serializable\nenum class DesignAssetType {\n LOGO,\n BACKGROUND_IMAGE,\n SVG_TEMPLATE,\n PDF_TEMPLATE,\n}" + }, + "ResolvedDesignAsset": { + "kind": "data class", + "name": "ResolvedDesignAsset", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class ResolvedDesignAsset(\n val data: ByteArray,\n val contentType: String,\n val reference: AssetReference,\n) {\n override fun equals(other: Any?): Boolean {\n if (this === other) {\n return true\n }\n if (other !is ResolvedDesignAsset) {\n return false\n }\n return data.contentEquals(other.data) && contentType == other.contentType && reference == other.reference\n }\n\n override fun hashCode(): Int {\n var result = data.contentHashCode()\n result = 31 * result + contentType.hashCode()\n result = 31 * result + reference.hashCode()\n return result\n }\n}\n\n@JsExportCompat\n@Serializable\ndata class AssetReference\n @JvmOverloads\n constructor(\n val uri: String,\n val integrity: String? = null,\n val altText: String? = null,\n val contentType: String? = null,\n val localBlob: BlobInfo? = null,\n )\n\n@Serializable\n@SerialName(\"blob-info\")\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"BlobInfo\", exact = true)\ndata class BlobInfo(\n override val storeId: String? = null,\n override val path: String? = null,\n override val tenantId: String? = null,\n override val contentType: String? = null,\n override val metadata: Map = emptyMap(),\n @Transient\n val opts: Map = emptyMap(),\n) : BlobInfoType {\n override fun toBlobInfo(): BlobInfo = this\n\n /**\n * Returns a [BlobMetadata] from this info's content type and custom metadata.\n */\n fun toBlobMetadata(): BlobMetadata =\n BlobMetadata(\n contentType = contentType,\n custom = metadata,\n )\n\n /**\n * Lightweight identity for use as map keys and cache lookups.\n * Like [KeyIdentity] — deterministic equality without transient fields.\n */\n fun toIdentity(): BlobIdentity =\n BlobIdentity(\n storeId = storeId,\n path = path,\n tenantId = tenantId,\n )\n\n /** Creates a copy targeting a different path. */\n fun withPath(newPath: String): BlobInfo = copy(path = newPath)\n\n /** Creates a copy targeting a different store. */\n fun withStore(newStoreId: String): BlobInfo = copy(storeId = newStoreId)\n\n companion object {\n fun of(\n storeId: String,\n path: String,\n ) = BlobInfo(storeId = storeId, path = path)\n\n fun fromDescriptor(\n descriptor: BlobDescriptor,\n tenantId: String? = null,\n ) = BlobInfo(\n storeId = descriptor.storeId,\n path = descriptor.path,\n tenantId = tenantId,\n contentType = descriptor.contentType,\n metadata = descriptor.metadata.custom,\n )\n\n /**\n * Validates a blob path for security:\n * - Rejects path traversal segments (`..`)\n * - Rejects null bytes\n * - Rejects absolute paths\n * - Rejects backslash separators\n */\n fun validatePath(path: String) {\n require(!path.contains('\\u0000')) { \"Blob path must not contain null bytes\" }\n require(!path.startsWith('/')) { \"Blob path must not be absolute\" }\n require(!path.contains('\\\\')) { \"Blob path must use '/' separators, not '\\\\'\" }\n val segments = path.split('/')\n require(segments.none { it == \"..\" }) { \"Blob path must not contain '..' traversal segments: $path\" }\n require(segments.none { it == \".\" }) { \"Blob path must not contain '.' self-reference segments: $path\" }\n }\n\n /**\n * Sanitizes and normalizes a user-provided path. Returns a safe path string.\n * Throws [IllegalArgumentException] if the path is malicious.\n */\n fun sanitizePath(path: String): String {\n val normalized =\n path\n .replace('\\\\', '/')\n .replace(Regex(\"/+\"), \"/\")\n .trimStart('/')\n .trimEnd('/')\n require(normalized.isNotBlank()) { \"Sanitized path must not be blank\" }\n validatePath(normalized)\n return normalized\n }\n }\n}" + }, + "InitPipelineSessionArgs": { + "kind": "data class", + "name": "InitPipelineSessionArgs", + "module": "public", + "source": "@Serializable\ndata class InitPipelineSessionArgs(\n /** The pipeline this session runs. */\n val pipelineConfiguration: PipelineConfiguration,\n /** External correlation handle; the command generates one when absent. */\n val correlationId: String? = null,\n /** Attributes known at session init (invitation context, static-offer config, ...). */\n val initialAttributes: List = emptyList(),\n /** Connector fields known at session init. These can satisfy invocation lookup inputs directly. */\n val initialConnectorFields: Map = emptyMap(),\n /** How the session payload is protected at rest. */\n val encryptionMode: SessionEncryptionMode = PlatformEncryptedMode,\n /** Session lifetime; the command applies a configured default when absent. */\n val ttlSeconds: Long? = null,\n)\n\n@JsExportCompat\n@Serializable\ndata class PipelineConfiguration(\n /** Stable identifier — referenced by [IssuancePipelineSession.pipelineId]. */\n val pipelineId: String,\n /** Connector invocations bound into this pipeline, each with its stage and binding config. */\n @JsExportIgnoreCompat\n val invocationBindings: List = emptyList(),\n /** The credentials this pipeline can assemble claims for. */\n @JsExportIgnoreCompat\n val claimsBindings: List = emptyList(),\n /**\n * Connector fields the caller is expected to provide at session init (from invitation context,\n * static-offer config, or the init call). A connector invocation may consume one of these\n * without any earlier invocation producing it.\n */\n @JsExportIgnoreCompat\n val expectedInitialConnectorFields: Set = emptySet(),\n)\n\n@JsExportCompat\n@Serializable\ndata class AttributeRecord(\n /** Where this attribute lives in the bag. */\n val path: AttributePath,\n /** The typed value. */\n val value: AttributeValue,\n /** Which producer contributed this record (opaque producer id — an IDV node, a pipeline source, ...). */\n val producerId: AttributeProvenanceRef,\n /** Producer-specific detail (e.g. IDV node id, OIDC issuer, HR-API endpoint). */\n val producerDetail: String? = null,\n /** The phase during which this record was contributed. */\n val phase: PipelinePhase,\n /** When this record was contributed. */\n val timestamp: Instant,\n /** Assurance level (from IDV evidence, OIDC `acr`, ...). */\n val assurance: EidasAssuranceLevel? = null,\n /** Conflict-resolution priority — higher wins; ties broken by [timestamp]. */\n val priority: Int = 0,\n /** Retention policy for this specific attribute. */\n val retention: AttributeRetentionPolicy = SessionRetention(),\n /** Whether this attribute has been verified by an IDV process. */\n val verified: Boolean = false,\n) {\n /**\n * The value as a [JsonElement] when it is plain data, else `null`. Blob / key / evidence\n * values are references and have no direct JSON form here — a downstream assembler handles\n * those explicitly.\n */\n val jsonValue: JsonElement?\n get() = (value as? AttributeData)?.value\n}\n\n@JsExportCompat\n@Serializable\nsealed interface SessionEncryptionMode\n\n/** No encryption — the payload is stored as plaintext. For local development / non-PII flows only. */\n@Serializable\n@SerialName(\"plaintext\")\n\n@Serializable\n@SerialName(\"platform-encrypted\")\ndata object PlatformEncryptedMode : SessionEncryptionMode\n\n/**\n * Tier 2: the effective encryption key is additionally bound to the session's `correlationId`\n * via HKDF, so decryption requires re-presenting the `correlationId`. The platform alone cannot\n * read the payload.\n *\n * @property fallbackToPlatform when true, a session whose `correlationId` cannot be re-presented\n * degrades to [PlatformEncryptedMode] semantics rather than being unreadable.\n */\n@Serializable\n@SerialName(\"client-bound\")\n\n @Serializable\r\n @SerialName(\"session\")\r\n data class Session(\r\n /** `null` -> use the domain default ([SessionRetention.encryptionRequired] = `true`). */\r\n val encryptionRequired: Boolean? = null,\r\n ) : RetentionDto() {\r\n override val kind: String = \"session\"\r\n }\n\n@JsExportCompat\n@Serializable\ndata class IssuancePipelineSession(\n /** Stable primary identifier. */\n val sessionId: String,\n /** The pipeline this session runs — carried on the session so a phase can be run without a separate registry lookup. */\n val pipelineConfiguration: PipelineConfiguration,\n /** The tenant this session belongs to. */\n val tenantId: String,\n /**\n * Which VDX issuer instance this session belongs to. Reserved for the multi-issuer-per-tenant\n * work; null for single-issuer deployments.\n */\n val issuerPartyId: String? = null,\n /** Lifecycle status. */\n val status: IssuancePipelineStatus,\n /** External correlation handle — the join key to the issuer-core session and all ingress paths. */\n val correlationId: String,\n /** Attributes accumulated across every phase run so far. Encrypted at rest per [encryptionMode]. */\n val bag: AttributeBag = AttributeBag.empty(),\n /** Connector fields accumulated so far. Encrypted at rest per [encryptionMode]. */\n @JsExportIgnoreCompat\n val connectorFields: Map = emptyMap(),\n /** Phases that have completed for this session. */\n @JsExportIgnoreCompat\n val completedPhases: Set = emptySet(),\n /** The phase currently executing, if any. */\n val currentPhase: PipelinePhase? = null,\n /** Protocol-specific context the front-end adapter carries through phases (e.g. `issuer_state`). */\n @JsExportIgnoreCompat\n val protocolContext: Map = emptyMap(),\n /** Per-binding deferral state, keyed by `bindingId`. Operational metadata; stored plaintext. */\n @JsExportIgnoreCompat\n val deferralEntries: Map = emptyMap(),\n /** Approval-gate state, present when a bound credential requires approval. Encrypted at rest. */\n val approval: ApprovalState? = null,\n /** How [bag] / [connectorFields] / [approval] are protected at rest. */\n val encryptionMode: SessionEncryptionMode = PlatformEncryptedMode,\n val createdAt: Instant,\n val updatedAt: Instant,\n val expiresAt: Instant,\n) {\n /** The id of the [pipelineConfiguration] this session runs. */\n val pipelineId: String get() = pipelineConfiguration.pipelineId\n}\n\n@JsExportCompat\n@Serializable\ndata class ConnectorInvocationBinding(\n @SerialName(\"invocationBindingId\")\n val invocationBindingId: ConnectorInvocationBindingId,\n @SerialName(\"ownerSurface\")\n val ownerSurface: ConnectorOwnerSurface,\n @SerialName(\"ownerReference\")\n val ownerReference: String,\n @SerialName(\"stage\")\n val stage: ConnectorInvocationStage,\n @SerialName(\"role\")\n val role: ConnectorInvocationRole,\n @SerialName(\"target\")\n val target: ConnectorInvocationTarget,\n @SerialName(\"exchangeMode\")\n val exchangeMode: ConnectorExchangeMode,\n @SerialName(\"dataDirection\")\n val dataDirection: ConnectorDataDirection = ConnectorExchangeModes.axesFor(exchangeMode).dataDirection,\n @SerialName(\"initiationSide\")\n val initiationSide: ConnectorInitiationSide = ConnectorExchangeModes.axesFor(exchangeMode).initiationSide,\n @SerialName(\"subsetMapping\")\n val subsetMapping: ConnectorSubsetMapping = ConnectorSubsetMapping(),\n @SerialName(\"logicalContext\")\n val logicalContext: ConnectorLogicalContext,\n @SerialName(\"logicalConnectionBindingId\")\n val logicalConnectionBindingId: LogicalConnectionBindingId? = null,\n @SerialName(\"physicalConnectorInstanceId\")\n val physicalConnectorInstanceId: ConnectorId? = null,\n @SerialName(\"executionPolicy\")\n val executionPolicy: ConnectorInvocationExecutionPolicy = ConnectorInvocationExecutionPolicy(),\n @SerialName(\"governance\")\n val governance: ConnectorGovernanceEnvelope? = null,\n @SerialName(\"partyAnchors\")\n val partyAnchors: ConnectorPartyAnchorSet = ConnectorPartyAnchorSet(),\n @SerialName(\"materializationPolicy\")\n val materializationPolicy: MaterializationPolicy = MaterializationPolicy(),\n @SerialName(\"metadata\")\n val metadata: Map = emptyMap(),\n)\n\n@JsExportCompat\n@Serializable\ndata class CredentialClaimsBinding(\n /** Matches the credential's `credential_configuration_id`. */\n val id: String,\n /**\n * The semantic attribute set (OCA bundle / vocabulary subset) this credential draws from.\n * The credential-design service resolves SD policy + mandatory claims from it.\n */\n val semanticAttributeSetRef: SemanticAttributeSetRef,\n /**\n * Optional mapping FROM semantic-model attribute names TO the credential's claim structure\n * (renaming / restructuring per vct / doctype). Null when names map 1:1. NOT where selective\n * disclosure is decided.\n */\n val claimMappingConfigId: String? = null,\n /** Inline alternative to [claimMappingConfigId]. */\n val inlineClaimMappingConfig: ClaimMappingConfiguration? = null,\n /** Which of the pipeline's sources this credential consumes, per phase. */\n @JsExportIgnoreCompat\n val requiredContributors: Map> = emptyMap(),\n /** Per-credential deferral policy. */\n val deferralPolicy: DeferralPolicy = DeferralPolicy.disabled(),\n)\n\n@JsExportCompat\n@Serializable(with = AttributePathSerializer::class)\ndata class AttributePath(\n val value: String,\n)\n\n@JsExportCompat\n@Serializable\nsealed interface AttributeValue\n\n/**\n * A plain data value (string, number, boolean, object, array). Becomes a credential \"claim\"\n * only once a downstream assembler maps it into a credential.\n */\n@Serializable\n@SerialName(\"data\")\n\n@JsExportCompat\n@Serializable(with = AttributeProvenanceRefSerializer::class)\ndata class AttributeProvenanceRef(\n val value: String,\n)\n\n@JsExportCompat\n@Serializable\ndata class PipelinePhase(\n val value: String,\n) {\n companion object {\n /** Session / offer creation — initial attributes injected by the caller. */\n val SESSION_INIT = PipelinePhase(\"session_init\")\n\n /**\n * Generic, channel-neutral attribute resolution — the phase a non-credential caller (a form,\n * portal page, PDF/API render, or a standalone semantic-enrichment lookup) uses to resolve\n * attributes from connector invocations without any issuance flow. Lets the pipeline drive every\n * channel, not only credential issuance.\n */\n val RESOLUTION = PipelinePhase(\"resolution\")\n\n /** Identity verification completed — IDV results are available. */\n val IDV_COMPLETED = PipelinePhase(\"idv_completed\")\n\n /** Credential assembly — final enrichment before credential construction. */\n val CREDENTIAL_ASSEMBLY = PipelinePhase(\"credential_assembly\")\n\n /** Post-issuance — audit, cleanup, retention enforcement. */\n val POST_ISSUANCE = PipelinePhase(\"post_issuance\")\n }\n}\n\ntypealias EidasAssuranceLevel = com.sphereon.core.api.service.EidasAssuranceLevel" + }, + "InitPipelineSessionResult": { + "kind": "data class", + "name": "InitPipelineSessionResult", + "module": "public", + "source": "@Serializable\ndata class InitPipelineSessionResult(\n val sessionId: String,\n /** The correlation handle — generated when the caller did not supply one. */\n val correlationId: String,\n)" + }, + "ContributeAttributesArgs": { + "kind": "data class", + "name": "ContributeAttributesArgs", + "module": "public", + "source": "@Serializable\ndata class ContributeAttributesArgs(\n /** The session to contribute to. */\n val correlationId: String,\n /** The phase to run. */\n val phase: PipelinePhase,\n /** Attributes pushed in as input for this phase (from a backend push, a callback, ...). */\n val attributes: List = emptyList(),\n /** Connector fields pushed in as input for this phase. */\n val connectorFields: Map = emptyMap(),\n)\n\n@JsExportCompat\n@Serializable\ndata class PipelinePhase(\n val value: String,\n) {\n companion object {\n /** Session / offer creation — initial attributes injected by the caller. */\n val SESSION_INIT = PipelinePhase(\"session_init\")\n\n /**\n * Generic, channel-neutral attribute resolution — the phase a non-credential caller (a form,\n * portal page, PDF/API render, or a standalone semantic-enrichment lookup) uses to resolve\n * attributes from connector invocations without any issuance flow. Lets the pipeline drive every\n * channel, not only credential issuance.\n */\n val RESOLUTION = PipelinePhase(\"resolution\")\n\n /** Identity verification completed — IDV results are available. */\n val IDV_COMPLETED = PipelinePhase(\"idv_completed\")\n\n /** Credential assembly — final enrichment before credential construction. */\n val CREDENTIAL_ASSEMBLY = PipelinePhase(\"credential_assembly\")\n\n /** Post-issuance — audit, cleanup, retention enforcement. */\n val POST_ISSUANCE = PipelinePhase(\"post_issuance\")\n }\n}\n\n@JsExportCompat\n@Serializable\ndata class AttributeRecord(\n /** Where this attribute lives in the bag. */\n val path: AttributePath,\n /** The typed value. */\n val value: AttributeValue,\n /** Which producer contributed this record (opaque producer id — an IDV node, a pipeline source, ...). */\n val producerId: AttributeProvenanceRef,\n /** Producer-specific detail (e.g. IDV node id, OIDC issuer, HR-API endpoint). */\n val producerDetail: String? = null,\n /** The phase during which this record was contributed. */\n val phase: PipelinePhase,\n /** When this record was contributed. */\n val timestamp: Instant,\n /** Assurance level (from IDV evidence, OIDC `acr`, ...). */\n val assurance: EidasAssuranceLevel? = null,\n /** Conflict-resolution priority — higher wins; ties broken by [timestamp]. */\n val priority: Int = 0,\n /** Retention policy for this specific attribute. */\n val retention: AttributeRetentionPolicy = SessionRetention(),\n /** Whether this attribute has been verified by an IDV process. */\n val verified: Boolean = false,\n) {\n /**\n * The value as a [JsonElement] when it is plain data, else `null`. Blob / key / evidence\n * values are references and have no direct JSON form here — a downstream assembler handles\n * those explicitly.\n */\n val jsonValue: JsonElement?\n get() = (value as? AttributeData)?.value\n}\n\n @Serializable\r\n @SerialName(\"session\")\r\n data class Session(\r\n /** `null` -> use the domain default ([SessionRetention.encryptionRequired] = `true`). */\r\n val encryptionRequired: Boolean? = null,\r\n ) : RetentionDto() {\r\n override val kind: String = \"session\"\r\n }\n\n data class Generic(\n val exception: Throwable? = null,\n override val message: String = \"Consent error\",\n ) : ConsentError\n\n@JsExportCompat\n@Serializable\ndata class Identity\n @JvmOverloads\n constructor(\n /** Party ID - serves as the primary key */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Tenant this identity belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The role of this identity in the credential ecosystem */\n @SerialName(\"identityRole\")\n val identityRole: IdentityRole,\n /** Whether this is the default identity for the owning party */\n @SerialName(\"isDefault\")\n val isDefault: Boolean = false,\n /**\n * The specialization this identity serves, when it is intrinsically role-scoped\n * (e.g. an `employee` login identity vs a `customer` login identity on the same person).\n * Null means the identity is party-global and login resolution fans out then filters by binding.\n */\n @SerialName(\"specializationSubtype\")\n val specializationSubtype: String? = null,\n /** Controls whether readable profile data may exist on bound Party records. */\n @SerialName(\"privacyMode\")\n val privacyMode: IdentityPrivacyMode = IdentityPrivacyMode.PARTY_PROFILED,\n /** Opaque per-identity salt handle (reference only; no crypto in this layer) */\n @SerialName(\"saltRef\")\n val saltRef: String? = null,\n /** When the identity was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the identity (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the identity was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the identity (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the identity was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the identity (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) {\n val identityId: Uuid get() = partyId\n }\n\n data class Post(\n val credentials: ClientCredentials,\n ) : ClientAuthenticationConfig\n\n@JsExportCompat\n@Serializable(with = AttributePathSerializer::class)\ndata class AttributePath(\n val value: String,\n)\n\n@JsExportCompat\n@Serializable\nsealed interface AttributeValue\n\n/**\n * A plain data value (string, number, boolean, object, array). Becomes a credential \"claim\"\n * only once a downstream assembler maps it into a credential.\n */\n@Serializable\n@SerialName(\"data\")\n\n@JsExportCompat\n@Serializable(with = AttributeProvenanceRefSerializer::class)\ndata class AttributeProvenanceRef(\n val value: String,\n)\n\ntypealias EidasAssuranceLevel = com.sphereon.core.api.service.EidasAssuranceLevel\n\n@JsExportCompat\n@Serializable\nsealed interface AttributeRetentionPolicy\n\n/** In-memory only. Never serialized to persistent storage. */\n@Serializable\n@SerialName(\"ephemeral\")\n\n@Serializable\n@SerialName(\"session\")\ndata class SessionRetention(\n val encryptionRequired: Boolean = true,\n) : AttributeRetentionPolicy\n\n-- discriminator-tagged sealed-interface JSON via kotlinx-serialization." + }, + "ContributeAttributesResult": { + "kind": "data class", + "name": "ContributeAttributesResult", + "module": "public", + "source": "@Serializable\ndata class ContributeAttributesResult(\n val sessionId: String,\n /** The session status after the phase ran. */\n val status: IssuancePipelineStatus,\n /** Phases completed for the session, including this one. */\n val completedPhases: Set,\n)\n\n@JsExportCompat\nenum class IssuancePipelineStatus {\n /** Session created; no phase has run yet. */\n CREATED,\n\n /** A phase's sources are currently executing. */\n PHASE_EXECUTING,\n\n /** A phase finished; the session is between phases. */\n PHASE_COMPLETED,\n\n /** `/credential` returned 202; waiting for deferred attribute ingress. */\n AWAITING_DEFERRED,\n\n /** Required attributes are complete but an approver has not yet decided. */\n AWAITING_APPROVAL,\n\n /** All bindings complete and approved (if required); claims can be assembled. */\n READY,\n\n /** Issuance finished for every bound credential. */\n COMPLETED,\n\n /** The session failed terminally. */\n FAILED,\n\n /** The session passed its `expiresAt` without completing. */\n EXPIRED,\n}\n\n@JsExportCompat\n@Serializable\ndata class PipelinePhase(\n val value: String,\n) {\n companion object {\n /** Session / offer creation — initial attributes injected by the caller. */\n val SESSION_INIT = PipelinePhase(\"session_init\")\n\n /**\n * Generic, channel-neutral attribute resolution — the phase a non-credential caller (a form,\n * portal page, PDF/API render, or a standalone semantic-enrichment lookup) uses to resolve\n * attributes from connector invocations without any issuance flow. Lets the pipeline drive every\n * channel, not only credential issuance.\n */\n val RESOLUTION = PipelinePhase(\"resolution\")\n\n /** Identity verification completed — IDV results are available. */\n val IDV_COMPLETED = PipelinePhase(\"idv_completed\")\n\n /** Credential assembly — final enrichment before credential construction. */\n val CREDENTIAL_ASSEMBLY = PipelinePhase(\"credential_assembly\")\n\n /** Post-issuance — audit, cleanup, retention enforcement. */\n val POST_ISSUANCE = PipelinePhase(\"post_issuance\")\n }\n}\n\n @Serializable\r\n @SerialName(\"session\")\r\n data class Session(\r\n /** `null` -> use the domain default ([SessionRetention.encryptionRequired] = `true`). */\r\n val encryptionRequired: Boolean? = null,\r\n ) : RetentionDto() {\r\n override val kind: String = \"session\"\r\n }\n\n @Serializable\n @SerialName(\"Required\")\n data class Required(\n val message: String? = null,\n ) : FieldValidationRule\n\n data class FAILED(\n val failure: WalletOperationReplayFailure\n ) : ReplayOutcome\n\n data class Generic(\n val exception: Throwable? = null,\n override val message: String = \"Consent error\",\n ) : ConsentError\n\n@JsExportCompat\n@Serializable\ndata class Identity\n @JvmOverloads\n constructor(\n /** Party ID - serves as the primary key */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Tenant this identity belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The role of this identity in the credential ecosystem */\n @SerialName(\"identityRole\")\n val identityRole: IdentityRole,\n /** Whether this is the default identity for the owning party */\n @SerialName(\"isDefault\")\n val isDefault: Boolean = false,\n /**\n * The specialization this identity serves, when it is intrinsically role-scoped\n * (e.g. an `employee` login identity vs a `customer` login identity on the same person).\n * Null means the identity is party-global and login resolution fans out then filters by binding.\n */\n @SerialName(\"specializationSubtype\")\n val specializationSubtype: String? = null,\n /** Controls whether readable profile data may exist on bound Party records. */\n @SerialName(\"privacyMode\")\n val privacyMode: IdentityPrivacyMode = IdentityPrivacyMode.PARTY_PROFILED,\n /** Opaque per-identity salt handle (reference only; no crypto in this layer) */\n @SerialName(\"saltRef\")\n val saltRef: String? = null,\n /** When the identity was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the identity (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the identity was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the identity (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the identity was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the identity (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) {\n val identityId: Uuid get() = partyId\n }\n\n data class Post(\n val credentials: ClientCredentials,\n ) : ClientAuthenticationConfig" + }, + "GetSessionAttributesArgs": { + "kind": "data class", + "name": "GetSessionAttributesArgs", + "module": "public", + "source": "@Serializable\ndata class GetSessionAttributesArgs(\n /** The session whose attributes are read. */\n val correlationId: String,\n)" + }, + "GetSessionAttributesResult": { + "kind": "data class", + "name": "GetSessionAttributesResult", + "module": "public", + "source": "@Serializable\ndata class GetSessionAttributesResult(\n /**\n * The effective attribute data records from the session bag, keyed by attribute path string.\n * Only records whose value is plain attribute data are included; blob / key / evidence\n * references have no direct JSON form and are omitted.\n */\n val attributes: Map,\n /**\n * The connector field names known to the session. Field values are omitted because they may\n * be sensitive and are never returned in the clear over REST.\n */\n val connectorFieldNames: List,\n)\n\n-- discriminator-tagged sealed-interface JSON via kotlinx-serialization." + }, + "RecordPipelineContributorFailureArgs": { + "kind": "data class", + "name": "RecordPipelineContributorFailureArgs", + "module": "public", + "source": "@Serializable\ndata class RecordPipelineContributorFailureArgs(\n /** The external correlation handle identifying the pipeline session. */\n val correlationId: String,\n /** The opaque contributor identifier (matches `AttributeProvenanceRef.value`). */\n val contributorId: String,\n /** Optional human-readable reason recorded with the failure marker. */\n val reason: String? = null,\n)\n\n@JsExportCompat\n@Serializable(with = AttributeProvenanceRefSerializer::class)\ndata class AttributeProvenanceRef(\n val value: String,\n)\n\nobject AttributeProvenanceRefSerializer : KSerializer {\n override val descriptor: SerialDescriptor =\n PrimitiveSerialDescriptor(\"com.sphereon.attribute.flow.AttributeProvenanceRef\", PrimitiveKind.STRING)\n\n override fun serialize(\n encoder: Encoder,\n value: AttributeProvenanceRef\n ) = encoder.encodeString(value.value)\n\n override fun deserialize(decoder: Decoder): AttributeProvenanceRef = AttributeProvenanceRef(decoder.decodeString())\n}" + }, + "RecordPipelineContributorFailureResult": { + "kind": "data class", + "name": "RecordPipelineContributorFailureResult", + "module": "public", + "source": "@Serializable\ndata class RecordPipelineContributorFailureResult(\n /** The session's correlation id, echoed back for convenience. */\n val correlationId: String,\n /** The contributor id whose contribution was marked as failed. */\n val contributorId: String,\n)" + }, + "CreateDcqlQueryArgs": { + "kind": "data class", + "name": "CreateDcqlQueryArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class CreateDcqlQueryArgs(\n val queryId: String,\n val name: String,\n val description: String? = null,\n val dcqlQuery: DcqlQuery,\n val enabled: Boolean = true,\n)\n\n@Serializable\n@JsExportCompat\ndata class DcqlQuery(\n val credentials: List? = null,\n val credential_sets: List? = null,\n) {\n init {\n require(credentials != null || credential_sets != null) {\n \"At least one of 'credentials' or 'credential_sets' must be present\"\n }\n }\n}\n\n@Serializable\n@JsExportCompat\ndata class DcqlCredentialQuery(\n val id: String,\n val format: String? = null,\n val meta: JsonObject? = null,\n val claims: List? = null,\n val claim_sets: List? = null,\n val require_cryptographic_holder_binding: Boolean = true,\n val multiple: Boolean = false,\n @SerialName(\"trusted_authorities\")\n val trusted_authorities: List? = null,\n) {\n /**\n * Normalized trusted authorities with duplicate types automatically combined.\n *\n * When multiple authority entries of the same type exist in trusted_authorities,\n * they are automatically combined into a single entry with all values merged.\n * This prevents logic/validation problems by external parties.\n *\n * This property is computed in the init block and always reflects the deduplicated state.\n *\n * Example:\n * ```kotlin\n * // Input during construction/deserialization:\n * listOf(\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed1.com\")),\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed2.com\"))\n * )\n * // Automatically normalized to:\n * listOf(\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed1.com\", \"https://fed2.com\"))\n * )\n * ```\n */\n @Transient\n val normalizedTrustedAuthorities: List? = trusted_authorities?.let { normalizeTrustedAuthorities(it) }\n\n companion object {\n /**\n * Combines multiple trusted authority entries of the same type into single entries.\n *\n * @param authorities Original list that may contain duplicate types\n * @return List with duplicate types merged, maintaining order of first occurrence\n */\n private fun normalizeTrustedAuthorities(authorities: List): List {\n if (authorities.isEmpty()) {\n return authorities\n }\n\n // Group by type and combine all values\n val grouped = authorities.groupBy { it.type }\n\n // Maintain order of first occurrence for each type\n return authorities\n .distinctBy { it.type }\n .map { firstOfType ->\n val allValues = grouped[firstOfType.type]!!.flatMap { it.values }.distinct()\n DcqlTrustedAuthority(\n type = firstOfType.type,\n values = allValues,\n )\n }\n }\n }\n}\n\n@Serializable\n@JsExportCompat\ndata class DcqlCredentialSetQuery(\n val required: Boolean = false,\n val options: List,\n)" + }, + "DcqlQueryConfiguration": { + "kind": "data class", + "name": "DcqlQueryConfiguration", + "module": "public", + "source": "@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"DcqlQueryConfiguration\", exact = true)\n@JsExportCompat\n@Serializable\ndata class DcqlQueryConfiguration(\n val queryId: String,\n val name: String,\n val description: String? = null,\n val dcqlQuery: DcqlQuery,\n val enabled: Boolean = true,\n val createdAt: Long,\n val updatedAt: Long,\n /**\n * The version number of the currently active DCQL body, when the configuration is backed\n * by a version-history store. Null for stores without versioning (the IDK KV/SQLite\n * backings); set by the EDK versioned store.\n */\n val currentVersion: Int? = null,\n)\n\n@Serializable\n@JsExportCompat\ndata class DcqlQuery(\n val credentials: List? = null,\n val credential_sets: List? = null,\n) {\n init {\n require(credentials != null || credential_sets != null) {\n \"At least one of 'credentials' or 'credential_sets' must be present\"\n }\n }\n}\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNull\")\n @Serializable(with = CDDLSerializer::class)\n object Null : CDDL(\"null\", MajorType.SPECIAL, 22, arrayOf(nil)) {\n fun newNull() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n@Serializable\n@JsExportCompat\ndata class DcqlCredentialQuery(\n val id: String,\n val format: String? = null,\n val meta: JsonObject? = null,\n val claims: List? = null,\n val claim_sets: List? = null,\n val require_cryptographic_holder_binding: Boolean = true,\n val multiple: Boolean = false,\n @SerialName(\"trusted_authorities\")\n val trusted_authorities: List? = null,\n) {\n /**\n * Normalized trusted authorities with duplicate types automatically combined.\n *\n * When multiple authority entries of the same type exist in trusted_authorities,\n * they are automatically combined into a single entry with all values merged.\n * This prevents logic/validation problems by external parties.\n *\n * This property is computed in the init block and always reflects the deduplicated state.\n *\n * Example:\n * ```kotlin\n * // Input during construction/deserialization:\n * listOf(\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed1.com\")),\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed2.com\"))\n * )\n * // Automatically normalized to:\n * listOf(\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed1.com\", \"https://fed2.com\"))\n * )\n * ```\n */\n @Transient\n val normalizedTrustedAuthorities: List? = trusted_authorities?.let { normalizeTrustedAuthorities(it) }\n\n companion object {\n /**\n * Combines multiple trusted authority entries of the same type into single entries.\n *\n * @param authorities Original list that may contain duplicate types\n * @return List with duplicate types merged, maintaining order of first occurrence\n */\n private fun normalizeTrustedAuthorities(authorities: List): List {\n if (authorities.isEmpty()) {\n return authorities\n }\n\n // Group by type and combine all values\n val grouped = authorities.groupBy { it.type }\n\n // Maintain order of first occurrence for each type\n return authorities\n .distinctBy { it.type }\n .map { firstOfType ->\n val allValues = grouped[firstOfType.type]!!.flatMap { it.values }.distinct()\n DcqlTrustedAuthority(\n type = firstOfType.type,\n values = allValues,\n )\n }\n }\n }\n}\n\n@Serializable\n@JsExportCompat\ndata class DcqlCredentialSetQuery(\n val required: Boolean = false,\n val options: List,\n)\n\ninternal object CDDLSerializer : KSerializer {\n override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(\"CDDL\", PrimitiveKind.STRING)\n\n override fun serialize(\n encoder: Encoder,\n value: CDDL,\n ) {\n encoder.encodeString(value.format)\n }\n\n override fun deserialize(decoder: Decoder): CDDL = CDDL.util.fromFormat(decoder.decodeString())\n}\n\n@Suppress(\"UNCHECKED_CAST\")\n@JsExportCompat\n@Serializable(with = CDDLSerializer::class)\nsealed class CDDL(\n override val format: String,\n override val majorType: MajorType? = null,\n override val info: Int? = null,\n override val aliasFor: Array = arrayOf(),\n) : CDDLType {\n override fun newCborItemFromJson(\n element: JsonElement?,\n cddl: CDDLType?,\n ): CborItem {\n val jsonPrimitive: JsonPrimitive? = (element as? JsonPrimitive)?.jsonPrimitive\n val jsonArray: JsonArray? = (element as? JsonArray)?.jsonArray\n val jsonObject: JsonObject? = (element as? JsonObject)?.jsonObject\n val isNull: Boolean = element == JsonNull || element === null\n val isString: Boolean = jsonPrimitive?.isString == true\n\n if (isNull) {\n return CborNull()\n } else if (isString && jsonPrimitive !== null) {\n return CborString(jsonPrimitive.content)\n } else if (jsonArray !== null) {\n return list.fromJson(jsonArray)\n } else if (jsonObject !== null) {\n if (CborItemJson.isCborItemValueJson(jsonObject)) {\n val key =\n if (CborItemJson.isCborItemJson(jsonObject)) {\n (jsonObject[\"key\"] as? JsonPrimitive)?.content\n } else {\n null\n }\n val cddlStr = (jsonObject[\"cddl\"] as? JsonPrimitive)?.content\n\n if (cddlStr === null) {\n // cddl key found, but wasn't a primitive, returning a null value\n return CborNull()\n }\n val cddlObject = util.fromFormat(cddlStr)\n val cborObject = newCborItemFromJson(jsonObject[jsonObject.keys.find { it != CDDL_LITERAL && it != KEY_LITERAL }], cddlObject)\n if (key === null) {\n return cborObject\n }\n return CborMap(mutableMapOf(Pair(CborString(key), cborObject)))\n }\n // number label keys?\n return CborMap(mutableMapOf(* jsonObject.map { Pair(CborString(it.key), newCborItemFromJson(it.value)) }.toTypedArray()))\n } else if (jsonPrimitive !== null) {\n if (cddl == null) {\n return newCborItem(jsonPrimitive)\n }\n return when (cddl) {\n // Needed because we cannot have inheritance with Kotlin to JS, unfortunately. The fromJson would cause clashes if we put it in the interface\n tstr -> tstr.fromJson(jsonPrimitive)\n\n Null -> CborNull()\n\n False -> CborSimple.FALSE\n\n True -> CborSimple.TRUE\n\n bool -> bool.fromJson(jsonPrimitive)\n\n bstr -> bstr.fromJson(jsonPrimitive)\n\n bytes -> bytes.fromJson(jsonPrimitive)\n\n float -> float.fromJson(jsonPrimitive)\n\n float16 -> float16.fromJson(jsonPrimitive)\n\n float32 -> float32.fromJson(jsonPrimitive)\n\n float64 -> float64.fromJson(jsonPrimitive)\n\n full_date -> full_date.fromJson(jsonPrimitive)\n\n int -> int.fromJson(jsonPrimitive)\n\n nil -> nil.newNil()\n\n nint -> nint.fromJson(jsonPrimitive)\n\n tdate -> tdate.fromJson(jsonPrimitive)\n\n text -> text.fromJson(jsonPrimitive)\n\n time -> time.fromJson(jsonPrimitive)\n\n uint -> uint.fromJson(jsonPrimitive)\n\n undefined -> undefined.newUndefined()\n\n else -> cddl.newCborItem(jsonPrimitive)\n }\n }\n return newCborItem(element)\n }\n\n override fun newCborItem(origValue: T?): CborItem {\n // We are not using inheritance for the methods as that would impact JS export.\n // Since this is a sealed class anyway that is not too bad\n var value = origValue\n val jsonElement: JsonElement? =\n when (value) {\n is JsonPrimitive -> value\n is JsonArray -> value\n is JsonObject -> value\n is JsonNull -> value\n else -> null\n }\n if (value == null) {\n return nil.newNil()\n } else if (value == Unit) {\n return undefined.newUndefined()\n }\n return when (this) {\n tstr -> {\n if (jsonElement === null) {\n tstr.newString(value.toString())\n } else {\n tstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n False -> {\n False.newFalse()\n }\n\n Null -> {\n Null.newNull()\n }\n\n True -> {\n True.newTrue()\n }\n\n any -> {\n return when (value) {\n is JsonPrimitive -> {\n val prim = value\n when {\n prim.isString -> tstr.fromJson(prim)\n prim.content == \"true\" || prim.content == \"false\" -> bool.fromJson(prim)\n prim.content.contains('.') || prim.content.contains('e') || prim.content.contains('E') -> float64.fromJson(prim)\n else -> int.fromJson(prim) // Assume integer if not string, boolean, or float\n }\n }\n\n is cddl_tstr -> {\n if (jsonElement === null) {\n tstr.newString(value)\n } else {\n tstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_bstr -> {\n if (jsonElement === null) {\n bstr.newByteString(value)\n } else {\n bstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_tdate -> {\n if (jsonElement === null) {\n tdate.newTDate(value)\n } else {\n tdate.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_full_date -> {\n if (jsonElement === null) {\n full_date.newFullDate(value)\n } else {\n full_date.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_bool -> {\n if (jsonElement === null) {\n bool.newBool(value)\n } else {\n bool.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n // Use consolidated Number handling for JS/WasmJs compatibility\n // (on JS, all numeric `is` checks match any Number, making individual checks unreliable)\n is Number -> {\n if (jsonElement === null) {\n value.toCborItem()\n } else {\n val d = value.toDouble()\n if (d != kotlin.math.floor(d) || d.isInfinite() || d.isNaN()) {\n float64.fromJson(jsonElement.jsonPrimitive)\n } else {\n int.fromJson(jsonElement.jsonPrimitive)\n }\n }\n }\n\n is cddl_list<*> -> {\n if (jsonElement === null) {\n list.newList(\n value\n .map {\n if (it is CborItem<*>) {\n it\n } else {\n any.newCborItem(\n it,\n )\n }\n }.toMutableList(),\n )\n } else {\n list.fromJson(jsonElement.jsonArray)\n }\n }\n\n is cddl_map<*, *> -> {\n if (jsonElement === null) {\n map.newMap(\n mutableMapOf(\n * value\n .map {\n Pair(\n if (it.key is CborItem<*>) {\n it.key as CborItem<*>\n } else {\n any.newCborItem(it.key)\n },\n if (it.value is CborItem<*>) {\n it.value as CborItem<*>\n } else {\n any.newCborItem(it.value)\n },\n )\n }.toTypedArray(),\n ),\n )\n } else {\n map.fromJson(jsonElement.jsonObject)\n }\n }\n\n else -> {\n throw IllegalArgumentException(\"newCborItem for $value Not implemented yet\")\n }\n }\n }\n\n bool -> {\n if (jsonElement === null) {\n bool.newBool(value == true)\n } else {\n bool.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n bstr -> {\n if (jsonElement === null) {\n bstr.newByteString(value as ByteArray)\n } else {\n bstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n bstr_indef_length -> {\n if (jsonElement === null) {\n bstr_indef_length.newByteString(value as List)\n } else {\n TODO(\"indef cddl from json not implemented yet\")\n }\n }\n\n bytes -> {\n if (jsonElement === null) {\n bytes.newBytes(value as ByteArray)\n } else {\n bytes.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float -> {\n if (jsonElement === null) {\n float.newFloat(value as Float)\n } else {\n float.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float16 -> {\n if (jsonElement === null) {\n float16.newFloat16(value as Float)\n } else {\n float16.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float32 -> {\n if (jsonElement === null) {\n float32.newFloat32(value as Float)\n } else {\n float32.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float64 -> {\n if (jsonElement === null) {\n float64.newFloat64(value as Double)\n } else {\n float64.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n full_date -> {\n if (jsonElement === null) {\n full_date.newFullDate(value as cddl_full_date)\n } else {\n full_date.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n int -> {\n if (jsonElement === null) {\n int.newInt(value as Int)\n } else {\n int.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n list -> {\n if (jsonElement === null) {\n if (value is CborArray<*>) {\n value\n } else {\n list.newList(\n (value as List<*>)\n .map {\n if (it is CborItem<*>) {\n it\n } else {\n any.newCborItem(\n it,\n )\n }\n }.toMutableList(),\n )\n }\n } else {\n list.fromJson(jsonElement.jsonArray)\n }\n }\n\n map -> {\n if (jsonElement === null) {\n if (value is CborMap<*, *>) {\n value\n } else {\n map.newMap(\n mutableMapOf(\n * (value as Map<*, *>)\n .map {\n Pair(\n if (it.key is CborItem<*>) {\n it.key as CborItem<*>\n } else {\n any.newCborItem(it.key)\n },\n if (it.value is CborItem<*>) {\n it.value as CborItem<*>\n } else {\n any.newCborItem(it.value)\n },\n )\n }.toTypedArray(),\n ),\n ) // fixme. Needs inspection of keys and values and map type\n }\n } else {\n return map.fromJson(jsonElement.jsonObject)\n }\n }\n\n nil -> {\n nil.newNil()\n }\n\n nint -> {\n if (jsonElement === null) {\n nint.newNInt(\n if (value is Number) {\n value.toLong()\n } else {\n value as Long\n }\n )\n } else {\n nint.fromJson(\n jsonElement.jsonPrimitive,\n )\n }\n }\n\n tdate -> {\n if (jsonElement === null) {\n tdate.newTDate(value as cddl_tdate)\n } else {\n tdate.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n text -> {\n if (jsonElement === null) {\n text.newText(value as cddl_text)\n } else {\n text.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n time -> {\n if (jsonElement === null) {\n time.newTime(value as cddl_time)\n } else {\n time.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n tstr_indef_length -> {\n if (jsonElement !== null) {\n tstr_indef_length.newStringIndefLength(value as List)\n } else {\n TODO(\"tstr indef length from json to cbor not implemented\")\n }\n }\n\n uint -> {\n if (jsonElement === null) {\n uint.newUint(\n if (value is Long) {\n value\n } else if (value is Number) {\n value.toLong()\n } else {\n value as Long\n },\n )\n } else {\n uint.fromJson(\n jsonElement.jsonPrimitive,\n )\n }\n }\n\n undefined -> {\n undefined.newUndefined()\n }\n }\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTstr\")\n object tstr : CDDL(\"tstr\", MajorType.UNICODE_STRING) {\n fun newString(value: cddl_tstr) = CborString(value)\n\n fun fromJson(value: JsonPrimitive) = CborString(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlUint\")\n object uint : CDDL(\"uint\", MajorType.UNSIGNED_INTEGER) {\n fun newUint(value: cddl_uint) = CborUInt(value)\n\n fun fromJson(value: JsonPrimitive) = CborUInt(value.content.toLong())\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNint\")\n object nint : CDDL(\"nint\", MajorType.NEGATIVE_INTEGER) {\n fun newNInt(value: cddl_nint) = CborNInt(value)\n\n fun fromJson(value: JsonPrimitive) = CborNInt(value.content.toLong())\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlInt\")\n object int :\n CDDL(\"int\", null, null, aliasFor = arrayOf(uint, nint)) {\n fun newInt(value: Int) =\n if (value < 0) {\n CborNInt(value.toLong())\n } else {\n CborUInt(value.toLong())\n }\n\n fun newLong(value: Long) =\n if (value < 0) {\n CborNInt(value)\n } else {\n CborUInt(value)\n }\n\n fun fromJson(value: JsonPrimitive) =\n if (value.long < 0) {\n CborNInt(value.long)\n } else {\n CborUInt(value.long)\n }\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBstr\")\n object bstr : CDDL(\"bstr\", MajorType.BYTE_STRING) {\n fun newByteString(value: cddl_bstr) = CborByteString(value)\n\n fun fromJson(\n value: JsonPrimitive,\n encoding: Encoding = Encoding.BASE64URL,\n ) = CborByteString(value.content.decodeFrom(encoding))\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBstrIndefLength\")\n object bstr_indef_length : CDDL(\"bstr\", MajorType.BYTE_STRING) {\n fun newByteString(value: List) = CborByteStringIndefLength(value)\n\n fun fromJson(\n value: JsonArray,\n encoding: Encoding = Encoding.BASE64URL,\n ): CborByteStringIndefLength = TODO(\"indef length from json to cbor not implemented yet\")\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBytes\")\n object bytes : CDDL(\"bytes\", MajorType.BYTE_STRING, aliasFor = arrayOf(bstr)) {\n fun newBytes(value: cddl_bstr) = CborByteString(value)\n\n fun fromJson(\n value: JsonPrimitive,\n encoding: Encoding = Encoding.BASE64URL,\n ) = CborByteString(value.content.decodeFrom(encoding))\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTstrIndefLength\")\n object tstr_indef_length : CDDL(\"tstr\", MajorType.UNICODE_STRING) {\n fun newStringIndefLength(value: List) = CborStringIndefLength(value)\n\n fun fromJson(\n value: JsonArray,\n encoding: Encoding = Encoding.BASE64URL,\n ): CborStringIndefLength = TODO(\"indef length from json to cbor not implemented yet\")\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlText\")\n object text : CDDL(\"text\", MajorType.UNICODE_STRING, aliasFor = arrayOf(tstr)) {\n fun newText(value: cddl_text) = CborString(value)\n\n fun fromJson(value: JsonPrimitive) = CborString(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTdate\")\n object tdate : CDDL(\n \"tdate\",\n MajorType.TAG,\n DATE_TIME_STRING,\n ) { // RFC 7049, section 2.4.1, a tdate data item shall contain a date-time string as specified in RFC 3339\n fun newTDate(value: cddl_tdate) = CborTDate(value)\n\n fun fromJson(value: JsonPrimitive) = CborTDate(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFullDate\")\n object full_date : CDDL(\n \"full-date\",\n MajorType.TAG,\n CborTagged.FULL_DATE_STRING,\n ) { // #6.1004(tstr) In accordance with RFC 8943, a full-date data item shall contain a full-datestring as specified in RFC 3339.\n fun newFullDate(value: cddl_full_date) = CborFullDate(value)\n\n fun fromJson(value: JsonPrimitive) = CborFullDate(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTime\")\n object time : CDDL(\n \"time\",\n MajorType.TAG,\n CborTagged.DATE_TIME_NUMBER,\n ) { // RFC 7049, section 2.4.1, a tdate data item shall contain a date-time number as specified in RFC 3339\n fun newTime(value: cddl_time) = CborTime(value)\n\n fun fromJson(value: JsonPrimitive) = CborTime(value.content.toLong())\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat16\")\n object float16 : CDDL(\"float16\", MajorType.SPECIAL, 25) {\n fun newFloat16(value: cddl_float16) = CborFloat16(value)\n\n fun fromJson(value: JsonPrimitive) = CborFloat16(value.float)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat32\")\n object float32 : CDDL(\"float32\", MajorType.SPECIAL, 26) {\n fun newFloat32(value: cddl_float32) = CborFloat32(value)\n\n fun fromJson(value: JsonPrimitive) = CborFloat32(value.float)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat64\")\n object float64 : CDDL(\"float64\", MajorType.SPECIAL, 27) {\n fun newFloat64(value: cddl_float64) = CborDouble(value)\n\n fun fromJson(value: JsonPrimitive) = CborDouble(value.double)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat\")\n object float : CDDL(\"float\", MajorType.SPECIAL, aliasFor = arrayOf(float16, float32, float64)) {\n fun newFloat(value: cddl_float) = CborFloat32(value)\n\n fun fromJson(value: JsonPrimitive) = CborFloat32(value.float)\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFalse\")\n @Serializable(with = CDDLSerializer::class)\n object False : CDDL(\"false\", MajorType.SPECIAL, 20) {\n fun newFalse() = CborSimple.FALSE\n\n fun fromJson(value: JsonPrimitive) = CborSimple.FALSE\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTrue\")\n @Serializable(with = CDDLSerializer::class)\n object True : CDDL(\"true\", MajorType.SPECIAL, 21) {\n fun newTrue() = CborSimple.TRUE\n\n fun fromJson(value: JsonPrimitive) = CborSimple.TRUE\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBool\")\n object bool :\n CDDL(\"bool\", MajorType.SPECIAL, aliasFor = arrayOf(False, True)) {\n fun newBool(value: cddl_bool) =\n if (value) {\n CborSimple.TRUE\n } else {\n CborSimple.FALSE\n }\n\n fun fromJson(value: JsonPrimitive) =\n if (value.boolean) {\n CborSimple.TRUE\n } else {\n CborSimple.FALSE\n }\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNil\")\n object nil : CDDL(\"nil\", MajorType.SPECIAL, 22) {\n fun newNil() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNull\")\n @Serializable(with = CDDLSerializer::class)\n object Null : CDDL(\"null\", MajorType.SPECIAL, 22, arrayOf(nil)) {\n fun newNull() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlUndefined\")\n object undefined :\n CDDL(\"undefined\", MajorType.SPECIAL, 23) {\n fun newUndefined() = CborSimple.UNDEFINED\n\n fun fromJson(value: JsonElement) = CborSimple.UNDEFINED\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlMap\")\n object map :\n CDDL(\n \"map\",\n MajorType.MAP,\n ) {\n fun newMap(value: MutableMap, CborItem<*>>): CborItem, CborItem<*>>> = CborMap(value)\n\n /**\n * Please note that this method is not able to map onto the exact Cbor items as the json values have no type information!\n */\n fun fromJson(value: JsonObject): CborMap> =\n CborMap(\n value.entries\n .map {\n Pair(\n CborString(it.key),\n when (it.value) {\n is JsonPrimitive -> any.fromJson(it.value)\n is JsonArray -> list.fromJson(it.value as JsonArray)\n is JsonObject -> fromJson(it.value as JsonObject)\n else -> throw IllegalArgumentException(\"Unknown type encountered\")\n },\n )\n }.toMap()\n .toMutableMap(),\n )\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlList\")\n object list :\n CDDL(\n \"list\",\n MajorType.ARRAY,\n ) {\n fun > newList(value: cddl_list) = CborArray(value)\n\n /**\n * Please note that this method is not able to map onto the exact Cbor items as the json values have no type information!\n */\n fun fromJson(value: JsonArray): CborArray> =\n CborArray(\n value\n .map { elt ->\n when (elt) {\n is JsonPrimitive -> {\n any.fromJson(elt)\n }\n\n is JsonArray -> {\n fromJson(elt)\n }\n\n is JsonObject -> {\n if (CborItemJson.isCborItemValueJson(elt)) {\n newCborItemFromJson(\n elt,\n elt[CDDL_LITERAL]?.jsonPrimitive?.content?.let { CDDL.util.fromFormat(it) },\n )\n } else {\n map.fromJson(elt)\n }\n }\n\n else -> {\n throw IllegalArgumentException(\"Unknown type encountered\")\n }\n }\n }.toMutableList(),\n )\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlAny\")\n object any :\n CDDL(\n \"any\",\n ) {\n fun newAny(value: cddl_any) = CborAny(value)\n\n fun fromJson(value: JsonElement): CborItem<*> {\n return newCborItemFromJson(value)\n// TODO(\"Json any to cbor not implemeted yet\")\n }\n }\n\n override fun toTag(additionalInfo: Int?): String {\n if (aliasFor.isNotEmpty()) {\n if (additionalInfo == null) {\n return aliasFor[0].toTag(additionalInfo)\n }\n\n // fixme: this is not correct. We first need to traverse the aliases, as an alias could go without major and additional info\n return util.entries\n .first { it.majorType == majorType && it.info == additionalInfo }\n .toTag(additionalInfo)\n }\n\n var tag = \"#\"\n if (majorType != null) {\n tag += majorType\n }\n if (additionalInfo != null) {\n tag += \".$additionalInfo\"\n }\n return tag\n }\n\n override fun toString(): String = \"CDDL(format='$format', majorType=$majorType, info=$info, aliasFor=${aliasFor.contentToString()})\"\n\n override fun equals(other: Any?): Boolean {\n if (this === other) {\n return true\n }\n if (other !is CDDL) {\n return false\n }\n\n if (format != other.format) {\n return false\n }\n if (majorType != other.majorType) {\n return false\n }\n if (info != other.info) {\n return false\n }\n if (!aliasFor.contentEquals(other.aliasFor)) {\n return false\n }\n\n return true\n }\n\n override fun hashCode(): Int {\n var result = format.hashCode()\n result = 31 * result + (majorType?.hashCode() ?: 0)\n result = 31 * result + (info ?: 0)\n result = 31 * result + aliasFor.contentHashCode()\n return result\n }\n\n object util {\n // Lazy for serialization as this class is used as object in the above CDDL class\n val entries by lazy {\n arrayOf(\n any,\n uint,\n int,\n nint,\n bstr,\n bstr_indef_length,\n bytes,\n tstr,\n tstr_indef_length,\n text,\n tdate,\n full_date,\n time,\n float,\n False,\n True,\n bool,\n nil,\n Null,\n undefined,\n float16,\n float32,\n float64,\n map,\n list,\n )\n }\n\n fun fromFormat(format: String) = entries.first { it.format == format }\n\n fun fromTag(tag: String): CDDL {\n require(tag.startsWith(\"#\")) { \"Invalid tag supplied $tag\" }\n val parts = tag.split(\"#\", \".\")\n if (parts.size == 1) {\n return any\n }\n val majorVal = parts[1].toIntOrNull()\n return fromMajorType(majorVal?.let { MajorType.fromInt(it) }, parts[2].toIntOrNull())\n }\n\n fun fromBytes(input: Int): CDDL {\n val majorType = input shr 5\n\n // todo additionalInto\n return fromMajorType(MajorType.fromInt(majorType))\n }\n\n fun fromMajorType(\n majorType: MajorType? = null,\n additionalInfo: Int? = null,\n ) = entries.first {\n it.majorType == majorType && it.info == additionalInfo\n }\n }\n}\n\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"MajorType\", exact = true)\n@Serializable\n@JsExportCompat\nenum class MajorType(\n val type: Int,\n) {\n /**\n * Major type 0.\n *\n * An unsigned integer in the range 0..2^64-1 inclusive. The value of the encoded item is the\n * argument itself. For example, the integer 10 is denoted as the one byte 0b000_01010 (major\n * type 0, additional information 10). The integer 500 would be 0b000_11001 (major type 0,\n * additional information 25) followed by the two bytes 0x01f4, which is 500 in decimal.\n */\n UNSIGNED_INTEGER(0),\n\n /**\n * Major type 1.\n *\n * A negative integer in the range -2^64..-1 inclusive. The value of the item is -1 minus\n * the argument. For example, the integer -500 would be 0b001_11001 (major type 1, additional\n * information 25) followed by the two bytes 0x01f3, which is 499 in decimal.\n */\n NEGATIVE_INTEGER(1),\n\n /**\n * Major type 2.\n *\n * A byte string. The number of bytes in the string is equal to the argument. For example,\n * a byte string whose length is 5 would have an initial byte of 0b010_00101 (major type 2,\n * additional information 5 for the length), followed by 5 bytes of binary content. A byte\n * string whose length is 500 would have 3 initial bytes of 0b010_11001 (major type 2,\n * additional information 25 to indicate a two-byte length) followed by the two bytes 0x01f4\n * for a length of 500, followed by 500 bytes of binary content.\n */\n BYTE_STRING(2),\n\n /**\n * Major type 3.\n *\n * A text string (Section 2) encoded as UTF-8 [RFC3629]. The number of bytes in the string\n * is equal to the argument. A string containing an invalid UTF-8 sequence is well-formed\n * but invalid (Section 1.2). This type is provided for systems that need to interpret or\n * display human-readable text, and allows the differentiation between unstructured bytes\n * and text that has a specified repertoire (that of Unicode) and encoding (UTF-8). In\n * contrast to formats such as JSON, the Unicode characters in this type are never escaped.\n * Thus, a newline character (U+000A) is always represented in a string as the byte 0x0a,\n * and never as the bytes 0x5c6e (the characters \"\\\" and \"n\") nor as 0x5c7530303061 (the\n * characters \"\\\", \"u\", \"0\", \"0\", \"0\", and \"a\").\n */\n UNICODE_STRING(3),\n\n /**\n * Major type 4.\n * An array of data items. In other formats, arrays are also called lists, sequences, or\n * tuples (a \"CBOR sequence\" is something slightly different, though [RFC8742]). The argument\n * is the number of data items in the array. Items in an array do not need to all be of the\n * same type. For example, an array that contains 10 items of any type would have an initial\n * byte of 0b100_01010 (major type 4, additional information 10 for the length) followed by\n * the 10 remaining items.\n */\n ARRAY(4),\n\n /**\n * Major type 5.\n *\n * A map of pairs of data items. Maps are also called tables, dictionaries, hashes, or\n * objects (in JSON). A map is comprised of pairs of data items, each pair consisting of a\n * key that is immediately followed by a value. The argument is the number of pairs of data\n * items in the map. For example, a map that contains 9 pairs would have an initial byte of\n * 0b101_01001 (major type 5, additional information 9 for the number of pairs) followed by\n * the 18 remaining items. The first item is the first key, the second item is the first\n * value, the third item is the second key, and so on. Because items in a map come in pairs,\n * their total number is always even: a map that contains an odd number of items (no value\n * data present after the last key data item) is not well-formed. A map that has duplicate\n * keys may be well-formed, but it is not valid, and thus it causes indeterminate decoding;\n * see also Section 5.6.\n */\n MAP(5),\n\n /**\n * Major type 6.\n *\n * A tagged data item (\"tag\") whose tag number, an integer in the range 0..2^64-1 inclusive,\n * is the argument and whose enclosed data item (tag content) is the single encoded data item\n * that follows the head. See Section 3.4.\n */\n TAG(6),\n\n /**\n * Major type 7.\n *\n * Floating-point numbers and simple values, as well as the \"break\" stop code. See Section 3.3.\n */\n SPECIAL(7),\n ;\n\n companion object {\n /**\n * Gets a [MajorType] instance from type.\n *\n * @param value an integer between 0 and 7, both inclusive\n * @return a [MajorType] for the given value.\n */\n @JsStatic\n @JvmStatic\n fun fromInt(value: Int): MajorType =\n entries.find { it.type == value }\n ?: throw IllegalArgumentException(\"Unknown major type with value $value\")\n }\n}\n\nabstract class CborSimple(\n value: Type,\n cddl: CDDL,\n) : CborItem(value, cddl) {\n init {\n val info =\n when (cddl) {\n is CDDL.bool -> {\n when (value) {\n true -> CDDL.True.info\n else -> CDDL.False.info\n }\n }\n\n else -> {\n cddl.info\n }\n }\n require(info != null)\n require(info is Int)\n check(info < 24 || (info in 32..255))\n }\n\n override fun encode(builder: ByteStringBuilder) {\n val majorTypeShifted = (majorType!!.type shl 5).toByte()\n builder.append(majorTypeShifted.or(info!!.toByte()))\n }\n\n override fun equals(other: Any?): Boolean = other is CborSimple<*> && value == other.value\n\n override fun hashCode(): Int = value.hashCode()\n\n override fun toString() =\n when (this) {\n FALSE -> \"Simple(FALSE)\"\n TRUE -> \"Simple(TRUE)\"\n NULL -> \"Simple(NULL)\"\n UNDEFINED -> \"Simple(UNDEFINED)\"\n else -> \"Simple($value)\"\n }\n\n companion object {\n /** The [Simple] value for FALSE */\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"CBOR_FALSE\")\n @JsStatic\n @JvmStatic\n val FALSE = CborFalse()\n\n /** The [Simple] value for TRUE */\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"CBOR_TRUE\")\n @JsStatic\n @JvmStatic\n val TRUE = CborTrue()\n\n /** The [Simple] value for NULL */\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"CBOR_NULL\")\n @JsStatic\n @JvmStatic\n val NULL = CborNull()\n\n /** The [Simple] value for UNDEFINED */\n @JsStatic\n @JvmStatic\n val UNDEFINED = CborUndefined()\n }\n}" + }, + "GetDcqlQueryArgs": { + "kind": "data class", + "name": "GetDcqlQueryArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class GetDcqlQueryArgs(\n val queryId: String,\n)" + }, + "ListDcqlQueriesArgs": { + "kind": "class", + "name": "ListDcqlQueriesArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\nclass ListDcqlQueriesArgs\n\n/**\n * Arguments for updating an existing DCQL query configuration.\n *\n * A null field leaves the corresponding value unchanged. This supports both full\n * replacement (PUT, all fields supplied) and partial update (PATCH, a subset supplied).\n */\n@JsExportCompat\n@Serializable" + }, + "UpdateDcqlQueryArgs": { + "kind": "data class", + "name": "UpdateDcqlQueryArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class UpdateDcqlQueryArgs(\n val queryId: String,\n val name: String? = null,\n val description: String? = null,\n val dcqlQuery: DcqlQuery? = null,\n val enabled: Boolean? = null,\n)\n\n@Serializable\n@JsExportCompat\ndata class DcqlQuery(\n val credentials: List? = null,\n val credential_sets: List? = null,\n) {\n init {\n require(credentials != null || credential_sets != null) {\n \"At least one of 'credentials' or 'credential_sets' must be present\"\n }\n }\n}\n\n@Serializable\n@JsExportCompat\ndata class DcqlCredentialQuery(\n val id: String,\n val format: String? = null,\n val meta: JsonObject? = null,\n val claims: List? = null,\n val claim_sets: List? = null,\n val require_cryptographic_holder_binding: Boolean = true,\n val multiple: Boolean = false,\n @SerialName(\"trusted_authorities\")\n val trusted_authorities: List? = null,\n) {\n /**\n * Normalized trusted authorities with duplicate types automatically combined.\n *\n * When multiple authority entries of the same type exist in trusted_authorities,\n * they are automatically combined into a single entry with all values merged.\n * This prevents logic/validation problems by external parties.\n *\n * This property is computed in the init block and always reflects the deduplicated state.\n *\n * Example:\n * ```kotlin\n * // Input during construction/deserialization:\n * listOf(\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed1.com\")),\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed2.com\"))\n * )\n * // Automatically normalized to:\n * listOf(\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed1.com\", \"https://fed2.com\"))\n * )\n * ```\n */\n @Transient\n val normalizedTrustedAuthorities: List? = trusted_authorities?.let { normalizeTrustedAuthorities(it) }\n\n companion object {\n /**\n * Combines multiple trusted authority entries of the same type into single entries.\n *\n * @param authorities Original list that may contain duplicate types\n * @return List with duplicate types merged, maintaining order of first occurrence\n */\n private fun normalizeTrustedAuthorities(authorities: List): List {\n if (authorities.isEmpty()) {\n return authorities\n }\n\n // Group by type and combine all values\n val grouped = authorities.groupBy { it.type }\n\n // Maintain order of first occurrence for each type\n return authorities\n .distinctBy { it.type }\n .map { firstOfType ->\n val allValues = grouped[firstOfType.type]!!.flatMap { it.values }.distinct()\n DcqlTrustedAuthority(\n type = firstOfType.type,\n values = allValues,\n )\n }\n }\n }\n}\n\n@Serializable\n@JsExportCompat\ndata class DcqlCredentialSetQuery(\n val required: Boolean = false,\n val options: List,\n)" + }, + "DeleteDcqlQueryArgs": { + "kind": "data class", + "name": "DeleteDcqlQueryArgs", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class DeleteDcqlQueryArgs(\n val queryId: String,\n)" + }, + "ListDcqlQueryVersionsArgs": { + "kind": "data class", + "name": "ListDcqlQueryVersionsArgs", + "module": "public", + "source": "@Serializable\r\ndata class ListDcqlQueryVersionsArgs(\r\n val queryId: String,\r\n)" + }, + "DcqlQueryVersionSummary": { + "kind": "data class", + "name": "DcqlQueryVersionSummary", + "module": "public", + "source": "@Serializable\r\ndata class DcqlQueryVersionSummary(\r\n val version: Int,\r\n val createdAt: Long,\r\n val createdBy: String? = null,\r\n)" + }, + "GetDcqlQueryVersionArgs": { + "kind": "data class", + "name": "GetDcqlQueryVersionArgs", + "module": "public", + "source": "@Serializable\r\ndata class GetDcqlQueryVersionArgs(\r\n val queryId: String,\r\n val version: Int,\r\n)" + }, + "DcqlQueryVersionRecord": { + "kind": "data class", + "name": "DcqlQueryVersionRecord", + "module": "public", + "source": "@Serializable\r\ndata class DcqlQueryVersionRecord(\r\n val identifier: String,\r\n val version: Int,\r\n val dcqlQuery: DcqlQuery,\r\n val createdAt: Long,\r\n val createdBy: String? = null,\r\n)\n\n@Serializable\n@JsExportCompat\ndata class DcqlQuery(\n val credentials: List? = null,\n val credential_sets: List? = null,\n) {\n init {\n require(credentials != null || credential_sets != null) {\n \"At least one of 'credentials' or 'credential_sets' must be present\"\n }\n }\n}\n\n@Serializable\n@JsExportCompat\ndata class DcqlCredentialQuery(\n val id: String,\n val format: String? = null,\n val meta: JsonObject? = null,\n val claims: List? = null,\n val claim_sets: List? = null,\n val require_cryptographic_holder_binding: Boolean = true,\n val multiple: Boolean = false,\n @SerialName(\"trusted_authorities\")\n val trusted_authorities: List? = null,\n) {\n /**\n * Normalized trusted authorities with duplicate types automatically combined.\n *\n * When multiple authority entries of the same type exist in trusted_authorities,\n * they are automatically combined into a single entry with all values merged.\n * This prevents logic/validation problems by external parties.\n *\n * This property is computed in the init block and always reflects the deduplicated state.\n *\n * Example:\n * ```kotlin\n * // Input during construction/deserialization:\n * listOf(\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed1.com\")),\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed2.com\"))\n * )\n * // Automatically normalized to:\n * listOf(\n * DcqlTrustedAuthority(\"openid_federation\", listOf(\"https://fed1.com\", \"https://fed2.com\"))\n * )\n * ```\n */\n @Transient\n val normalizedTrustedAuthorities: List? = trusted_authorities?.let { normalizeTrustedAuthorities(it) }\n\n companion object {\n /**\n * Combines multiple trusted authority entries of the same type into single entries.\n *\n * @param authorities Original list that may contain duplicate types\n * @return List with duplicate types merged, maintaining order of first occurrence\n */\n private fun normalizeTrustedAuthorities(authorities: List): List {\n if (authorities.isEmpty()) {\n return authorities\n }\n\n // Group by type and combine all values\n val grouped = authorities.groupBy { it.type }\n\n // Maintain order of first occurrence for each type\n return authorities\n .distinctBy { it.type }\n .map { firstOfType ->\n val allValues = grouped[firstOfType.type]!!.flatMap { it.values }.distinct()\n DcqlTrustedAuthority(\n type = firstOfType.type,\n values = allValues,\n )\n }\n }\n }\n}\n\n@Serializable\n@JsExportCompat\ndata class DcqlCredentialSetQuery(\n val required: Boolean = false,\n val options: List,\n)" + }, + "RestoreDcqlQueryVersionArgs": { + "kind": "data class", + "name": "RestoreDcqlQueryVersionArgs", + "module": "public", + "source": "@Serializable\r\ndata class RestoreDcqlQueryVersionArgs(\r\n val queryId: String,\r\n val version: Int,\r\n val note: String? = null,\r\n)" + }, + "BindVerifierDcqlArgs": { + "kind": "data class", + "name": "BindVerifierDcqlArgs", + "module": "public", + "source": "@Serializable\ndata class BindVerifierDcqlArgs(\n val verifierId: String,\n val queryId: String,\n /** Version to pin. Defaults to the DCQL query's current version when null. */\n val version: Int? = null,\n)\n\n object Defaults {\n /** Default slot interval in minutes for availability calculations */\n const val SLOT_INTERVAL_MINUTES = 30\n\n /** Default concurrency limit (how many concurrent bookings allowed) */\n const val CONCURRENCY_LIMIT = 1\n\n /** Default minimum booking duration in minutes */\n const val MIN_BOOKING_DURATION_MINUTES = 30\n\n /** Default buffer time after each booking in minutes */\n const val BUFFER_AFTER_MINUTES = 0\n\n /** Default for allowing same-day bookings */\n const val ALLOW_SAME_DAY_BOOKING = true\n }" + }, + "VerifierDcqlBinding": { + "kind": "data class", + "name": "VerifierDcqlBinding", + "module": "public", + "source": "@Serializable\r\ndata class VerifierDcqlBinding(\r\n val id: String,\r\n val tenantId: String,\r\n val verifierId: String,\r\n val queryId: String,\r\n val pinnedVersion: Int,\r\n val enabled: Boolean = true,\r\n val alias: String? = null,\r\n val createdAt: Instant,\r\n val updatedAt: Instant,\r\n)" + }, + "ListVerifierDcqlBindingsArgs": { + "kind": "data class", + "name": "ListVerifierDcqlBindingsArgs", + "module": "public", + "source": "@Serializable\ndata class ListVerifierDcqlBindingsArgs(\n val verifierId: String,\n)" + }, + "VerifierDcqlBindingKey": { + "kind": "data class", + "name": "VerifierDcqlBindingKey", + "module": "public", + "source": "@Serializable\ndata class VerifierDcqlBindingKey(\n val verifierId: String,\n val queryId: String,\n)" + }, + "UpdateVerifierDcqlBindingArgs": { + "kind": "data class", + "name": "UpdateVerifierDcqlBindingArgs", + "module": "public", + "source": "@Serializable\ndata class UpdateVerifierDcqlBindingArgs(\n val verifierId: String,\n val queryId: String,\n /** New pinned version. Null leaves the pinned version unchanged. */\n val pinnedVersion: Int? = null,\n /** Null leaves `enabled` unchanged. */\n val enabled: Boolean? = null,\n /** Null leaves `alias` unchanged. */\n val alias: String? = null,\n)\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNull\")\n @Serializable(with = CDDLSerializer::class)\n object Null : CDDL(\"null\", MajorType.SPECIAL, 22, arrayOf(nil)) {\n fun newNull() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\ninternal object CDDLSerializer : KSerializer {\n override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(\"CDDL\", PrimitiveKind.STRING)\n\n override fun serialize(\n encoder: Encoder,\n value: CDDL,\n ) {\n encoder.encodeString(value.format)\n }\n\n override fun deserialize(decoder: Decoder): CDDL = CDDL.util.fromFormat(decoder.decodeString())\n}\n\n@Suppress(\"UNCHECKED_CAST\")\n@JsExportCompat\n@Serializable(with = CDDLSerializer::class)\nsealed class CDDL(\n override val format: String,\n override val majorType: MajorType? = null,\n override val info: Int? = null,\n override val aliasFor: Array = arrayOf(),\n) : CDDLType {\n override fun newCborItemFromJson(\n element: JsonElement?,\n cddl: CDDLType?,\n ): CborItem {\n val jsonPrimitive: JsonPrimitive? = (element as? JsonPrimitive)?.jsonPrimitive\n val jsonArray: JsonArray? = (element as? JsonArray)?.jsonArray\n val jsonObject: JsonObject? = (element as? JsonObject)?.jsonObject\n val isNull: Boolean = element == JsonNull || element === null\n val isString: Boolean = jsonPrimitive?.isString == true\n\n if (isNull) {\n return CborNull()\n } else if (isString && jsonPrimitive !== null) {\n return CborString(jsonPrimitive.content)\n } else if (jsonArray !== null) {\n return list.fromJson(jsonArray)\n } else if (jsonObject !== null) {\n if (CborItemJson.isCborItemValueJson(jsonObject)) {\n val key =\n if (CborItemJson.isCborItemJson(jsonObject)) {\n (jsonObject[\"key\"] as? JsonPrimitive)?.content\n } else {\n null\n }\n val cddlStr = (jsonObject[\"cddl\"] as? JsonPrimitive)?.content\n\n if (cddlStr === null) {\n // cddl key found, but wasn't a primitive, returning a null value\n return CborNull()\n }\n val cddlObject = util.fromFormat(cddlStr)\n val cborObject = newCborItemFromJson(jsonObject[jsonObject.keys.find { it != CDDL_LITERAL && it != KEY_LITERAL }], cddlObject)\n if (key === null) {\n return cborObject\n }\n return CborMap(mutableMapOf(Pair(CborString(key), cborObject)))\n }\n // number label keys?\n return CborMap(mutableMapOf(* jsonObject.map { Pair(CborString(it.key), newCborItemFromJson(it.value)) }.toTypedArray()))\n } else if (jsonPrimitive !== null) {\n if (cddl == null) {\n return newCborItem(jsonPrimitive)\n }\n return when (cddl) {\n // Needed because we cannot have inheritance with Kotlin to JS, unfortunately. The fromJson would cause clashes if we put it in the interface\n tstr -> tstr.fromJson(jsonPrimitive)\n\n Null -> CborNull()\n\n False -> CborSimple.FALSE\n\n True -> CborSimple.TRUE\n\n bool -> bool.fromJson(jsonPrimitive)\n\n bstr -> bstr.fromJson(jsonPrimitive)\n\n bytes -> bytes.fromJson(jsonPrimitive)\n\n float -> float.fromJson(jsonPrimitive)\n\n float16 -> float16.fromJson(jsonPrimitive)\n\n float32 -> float32.fromJson(jsonPrimitive)\n\n float64 -> float64.fromJson(jsonPrimitive)\n\n full_date -> full_date.fromJson(jsonPrimitive)\n\n int -> int.fromJson(jsonPrimitive)\n\n nil -> nil.newNil()\n\n nint -> nint.fromJson(jsonPrimitive)\n\n tdate -> tdate.fromJson(jsonPrimitive)\n\n text -> text.fromJson(jsonPrimitive)\n\n time -> time.fromJson(jsonPrimitive)\n\n uint -> uint.fromJson(jsonPrimitive)\n\n undefined -> undefined.newUndefined()\n\n else -> cddl.newCborItem(jsonPrimitive)\n }\n }\n return newCborItem(element)\n }\n\n override fun newCborItem(origValue: T?): CborItem {\n // We are not using inheritance for the methods as that would impact JS export.\n // Since this is a sealed class anyway that is not too bad\n var value = origValue\n val jsonElement: JsonElement? =\n when (value) {\n is JsonPrimitive -> value\n is JsonArray -> value\n is JsonObject -> value\n is JsonNull -> value\n else -> null\n }\n if (value == null) {\n return nil.newNil()\n } else if (value == Unit) {\n return undefined.newUndefined()\n }\n return when (this) {\n tstr -> {\n if (jsonElement === null) {\n tstr.newString(value.toString())\n } else {\n tstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n False -> {\n False.newFalse()\n }\n\n Null -> {\n Null.newNull()\n }\n\n True -> {\n True.newTrue()\n }\n\n any -> {\n return when (value) {\n is JsonPrimitive -> {\n val prim = value\n when {\n prim.isString -> tstr.fromJson(prim)\n prim.content == \"true\" || prim.content == \"false\" -> bool.fromJson(prim)\n prim.content.contains('.') || prim.content.contains('e') || prim.content.contains('E') -> float64.fromJson(prim)\n else -> int.fromJson(prim) // Assume integer if not string, boolean, or float\n }\n }\n\n is cddl_tstr -> {\n if (jsonElement === null) {\n tstr.newString(value)\n } else {\n tstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_bstr -> {\n if (jsonElement === null) {\n bstr.newByteString(value)\n } else {\n bstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_tdate -> {\n if (jsonElement === null) {\n tdate.newTDate(value)\n } else {\n tdate.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_full_date -> {\n if (jsonElement === null) {\n full_date.newFullDate(value)\n } else {\n full_date.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n is cddl_bool -> {\n if (jsonElement === null) {\n bool.newBool(value)\n } else {\n bool.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n // Use consolidated Number handling for JS/WasmJs compatibility\n // (on JS, all numeric `is` checks match any Number, making individual checks unreliable)\n is Number -> {\n if (jsonElement === null) {\n value.toCborItem()\n } else {\n val d = value.toDouble()\n if (d != kotlin.math.floor(d) || d.isInfinite() || d.isNaN()) {\n float64.fromJson(jsonElement.jsonPrimitive)\n } else {\n int.fromJson(jsonElement.jsonPrimitive)\n }\n }\n }\n\n is cddl_list<*> -> {\n if (jsonElement === null) {\n list.newList(\n value\n .map {\n if (it is CborItem<*>) {\n it\n } else {\n any.newCborItem(\n it,\n )\n }\n }.toMutableList(),\n )\n } else {\n list.fromJson(jsonElement.jsonArray)\n }\n }\n\n is cddl_map<*, *> -> {\n if (jsonElement === null) {\n map.newMap(\n mutableMapOf(\n * value\n .map {\n Pair(\n if (it.key is CborItem<*>) {\n it.key as CborItem<*>\n } else {\n any.newCborItem(it.key)\n },\n if (it.value is CborItem<*>) {\n it.value as CborItem<*>\n } else {\n any.newCborItem(it.value)\n },\n )\n }.toTypedArray(),\n ),\n )\n } else {\n map.fromJson(jsonElement.jsonObject)\n }\n }\n\n else -> {\n throw IllegalArgumentException(\"newCborItem for $value Not implemented yet\")\n }\n }\n }\n\n bool -> {\n if (jsonElement === null) {\n bool.newBool(value == true)\n } else {\n bool.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n bstr -> {\n if (jsonElement === null) {\n bstr.newByteString(value as ByteArray)\n } else {\n bstr.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n bstr_indef_length -> {\n if (jsonElement === null) {\n bstr_indef_length.newByteString(value as List)\n } else {\n TODO(\"indef cddl from json not implemented yet\")\n }\n }\n\n bytes -> {\n if (jsonElement === null) {\n bytes.newBytes(value as ByteArray)\n } else {\n bytes.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float -> {\n if (jsonElement === null) {\n float.newFloat(value as Float)\n } else {\n float.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float16 -> {\n if (jsonElement === null) {\n float16.newFloat16(value as Float)\n } else {\n float16.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float32 -> {\n if (jsonElement === null) {\n float32.newFloat32(value as Float)\n } else {\n float32.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n float64 -> {\n if (jsonElement === null) {\n float64.newFloat64(value as Double)\n } else {\n float64.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n full_date -> {\n if (jsonElement === null) {\n full_date.newFullDate(value as cddl_full_date)\n } else {\n full_date.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n int -> {\n if (jsonElement === null) {\n int.newInt(value as Int)\n } else {\n int.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n list -> {\n if (jsonElement === null) {\n if (value is CborArray<*>) {\n value\n } else {\n list.newList(\n (value as List<*>)\n .map {\n if (it is CborItem<*>) {\n it\n } else {\n any.newCborItem(\n it,\n )\n }\n }.toMutableList(),\n )\n }\n } else {\n list.fromJson(jsonElement.jsonArray)\n }\n }\n\n map -> {\n if (jsonElement === null) {\n if (value is CborMap<*, *>) {\n value\n } else {\n map.newMap(\n mutableMapOf(\n * (value as Map<*, *>)\n .map {\n Pair(\n if (it.key is CborItem<*>) {\n it.key as CborItem<*>\n } else {\n any.newCborItem(it.key)\n },\n if (it.value is CborItem<*>) {\n it.value as CborItem<*>\n } else {\n any.newCborItem(it.value)\n },\n )\n }.toTypedArray(),\n ),\n ) // fixme. Needs inspection of keys and values and map type\n }\n } else {\n return map.fromJson(jsonElement.jsonObject)\n }\n }\n\n nil -> {\n nil.newNil()\n }\n\n nint -> {\n if (jsonElement === null) {\n nint.newNInt(\n if (value is Number) {\n value.toLong()\n } else {\n value as Long\n }\n )\n } else {\n nint.fromJson(\n jsonElement.jsonPrimitive,\n )\n }\n }\n\n tdate -> {\n if (jsonElement === null) {\n tdate.newTDate(value as cddl_tdate)\n } else {\n tdate.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n text -> {\n if (jsonElement === null) {\n text.newText(value as cddl_text)\n } else {\n text.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n time -> {\n if (jsonElement === null) {\n time.newTime(value as cddl_time)\n } else {\n time.fromJson(jsonElement.jsonPrimitive)\n }\n }\n\n tstr_indef_length -> {\n if (jsonElement !== null) {\n tstr_indef_length.newStringIndefLength(value as List)\n } else {\n TODO(\"tstr indef length from json to cbor not implemented\")\n }\n }\n\n uint -> {\n if (jsonElement === null) {\n uint.newUint(\n if (value is Long) {\n value\n } else if (value is Number) {\n value.toLong()\n } else {\n value as Long\n },\n )\n } else {\n uint.fromJson(\n jsonElement.jsonPrimitive,\n )\n }\n }\n\n undefined -> {\n undefined.newUndefined()\n }\n }\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTstr\")\n object tstr : CDDL(\"tstr\", MajorType.UNICODE_STRING) {\n fun newString(value: cddl_tstr) = CborString(value)\n\n fun fromJson(value: JsonPrimitive) = CborString(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlUint\")\n object uint : CDDL(\"uint\", MajorType.UNSIGNED_INTEGER) {\n fun newUint(value: cddl_uint) = CborUInt(value)\n\n fun fromJson(value: JsonPrimitive) = CborUInt(value.content.toLong())\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNint\")\n object nint : CDDL(\"nint\", MajorType.NEGATIVE_INTEGER) {\n fun newNInt(value: cddl_nint) = CborNInt(value)\n\n fun fromJson(value: JsonPrimitive) = CborNInt(value.content.toLong())\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlInt\")\n object int :\n CDDL(\"int\", null, null, aliasFor = arrayOf(uint, nint)) {\n fun newInt(value: Int) =\n if (value < 0) {\n CborNInt(value.toLong())\n } else {\n CborUInt(value.toLong())\n }\n\n fun newLong(value: Long) =\n if (value < 0) {\n CborNInt(value)\n } else {\n CborUInt(value)\n }\n\n fun fromJson(value: JsonPrimitive) =\n if (value.long < 0) {\n CborNInt(value.long)\n } else {\n CborUInt(value.long)\n }\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBstr\")\n object bstr : CDDL(\"bstr\", MajorType.BYTE_STRING) {\n fun newByteString(value: cddl_bstr) = CborByteString(value)\n\n fun fromJson(\n value: JsonPrimitive,\n encoding: Encoding = Encoding.BASE64URL,\n ) = CborByteString(value.content.decodeFrom(encoding))\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBstrIndefLength\")\n object bstr_indef_length : CDDL(\"bstr\", MajorType.BYTE_STRING) {\n fun newByteString(value: List) = CborByteStringIndefLength(value)\n\n fun fromJson(\n value: JsonArray,\n encoding: Encoding = Encoding.BASE64URL,\n ): CborByteStringIndefLength = TODO(\"indef length from json to cbor not implemented yet\")\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBytes\")\n object bytes : CDDL(\"bytes\", MajorType.BYTE_STRING, aliasFor = arrayOf(bstr)) {\n fun newBytes(value: cddl_bstr) = CborByteString(value)\n\n fun fromJson(\n value: JsonPrimitive,\n encoding: Encoding = Encoding.BASE64URL,\n ) = CborByteString(value.content.decodeFrom(encoding))\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTstrIndefLength\")\n object tstr_indef_length : CDDL(\"tstr\", MajorType.UNICODE_STRING) {\n fun newStringIndefLength(value: List) = CborStringIndefLength(value)\n\n fun fromJson(\n value: JsonArray,\n encoding: Encoding = Encoding.BASE64URL,\n ): CborStringIndefLength = TODO(\"indef length from json to cbor not implemented yet\")\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlText\")\n object text : CDDL(\"text\", MajorType.UNICODE_STRING, aliasFor = arrayOf(tstr)) {\n fun newText(value: cddl_text) = CborString(value)\n\n fun fromJson(value: JsonPrimitive) = CborString(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTdate\")\n object tdate : CDDL(\n \"tdate\",\n MajorType.TAG,\n DATE_TIME_STRING,\n ) { // RFC 7049, section 2.4.1, a tdate data item shall contain a date-time string as specified in RFC 3339\n fun newTDate(value: cddl_tdate) = CborTDate(value)\n\n fun fromJson(value: JsonPrimitive) = CborTDate(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFullDate\")\n object full_date : CDDL(\n \"full-date\",\n MajorType.TAG,\n CborTagged.FULL_DATE_STRING,\n ) { // #6.1004(tstr) In accordance with RFC 8943, a full-date data item shall contain a full-datestring as specified in RFC 3339.\n fun newFullDate(value: cddl_full_date) = CborFullDate(value)\n\n fun fromJson(value: JsonPrimitive) = CborFullDate(value.content)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTime\")\n object time : CDDL(\n \"time\",\n MajorType.TAG,\n CborTagged.DATE_TIME_NUMBER,\n ) { // RFC 7049, section 2.4.1, a tdate data item shall contain a date-time number as specified in RFC 3339\n fun newTime(value: cddl_time) = CborTime(value)\n\n fun fromJson(value: JsonPrimitive) = CborTime(value.content.toLong())\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat16\")\n object float16 : CDDL(\"float16\", MajorType.SPECIAL, 25) {\n fun newFloat16(value: cddl_float16) = CborFloat16(value)\n\n fun fromJson(value: JsonPrimitive) = CborFloat16(value.float)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat32\")\n object float32 : CDDL(\"float32\", MajorType.SPECIAL, 26) {\n fun newFloat32(value: cddl_float32) = CborFloat32(value)\n\n fun fromJson(value: JsonPrimitive) = CborFloat32(value.float)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat64\")\n object float64 : CDDL(\"float64\", MajorType.SPECIAL, 27) {\n fun newFloat64(value: cddl_float64) = CborDouble(value)\n\n fun fromJson(value: JsonPrimitive) = CborDouble(value.double)\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFloat\")\n object float : CDDL(\"float\", MajorType.SPECIAL, aliasFor = arrayOf(float16, float32, float64)) {\n fun newFloat(value: cddl_float) = CborFloat32(value)\n\n fun fromJson(value: JsonPrimitive) = CborFloat32(value.float)\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlFalse\")\n @Serializable(with = CDDLSerializer::class)\n object False : CDDL(\"false\", MajorType.SPECIAL, 20) {\n fun newFalse() = CborSimple.FALSE\n\n fun fromJson(value: JsonPrimitive) = CborSimple.FALSE\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlTrue\")\n @Serializable(with = CDDLSerializer::class)\n object True : CDDL(\"true\", MajorType.SPECIAL, 21) {\n fun newTrue() = CborSimple.TRUE\n\n fun fromJson(value: JsonPrimitive) = CborSimple.TRUE\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlBool\")\n object bool :\n CDDL(\"bool\", MajorType.SPECIAL, aliasFor = arrayOf(False, True)) {\n fun newBool(value: cddl_bool) =\n if (value) {\n CborSimple.TRUE\n } else {\n CborSimple.FALSE\n }\n\n fun fromJson(value: JsonPrimitive) =\n if (value.boolean) {\n CborSimple.TRUE\n } else {\n CborSimple.FALSE\n }\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNil\")\n object nil : CDDL(\"nil\", MajorType.SPECIAL, 22) {\n fun newNil() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNull\")\n @Serializable(with = CDDLSerializer::class)\n object Null : CDDL(\"null\", MajorType.SPECIAL, 22, arrayOf(nil)) {\n fun newNull() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlUndefined\")\n object undefined :\n CDDL(\"undefined\", MajorType.SPECIAL, 23) {\n fun newUndefined() = CborSimple.UNDEFINED\n\n fun fromJson(value: JsonElement) = CborSimple.UNDEFINED\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlMap\")\n object map :\n CDDL(\n \"map\",\n MajorType.MAP,\n ) {\n fun newMap(value: MutableMap, CborItem<*>>): CborItem, CborItem<*>>> = CborMap(value)\n\n /**\n * Please note that this method is not able to map onto the exact Cbor items as the json values have no type information!\n */\n fun fromJson(value: JsonObject): CborMap> =\n CborMap(\n value.entries\n .map {\n Pair(\n CborString(it.key),\n when (it.value) {\n is JsonPrimitive -> any.fromJson(it.value)\n is JsonArray -> list.fromJson(it.value as JsonArray)\n is JsonObject -> fromJson(it.value as JsonObject)\n else -> throw IllegalArgumentException(\"Unknown type encountered\")\n },\n )\n }.toMap()\n .toMutableMap(),\n )\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlList\")\n object list :\n CDDL(\n \"list\",\n MajorType.ARRAY,\n ) {\n fun > newList(value: cddl_list) = CborArray(value)\n\n /**\n * Please note that this method is not able to map onto the exact Cbor items as the json values have no type information!\n */\n fun fromJson(value: JsonArray): CborArray> =\n CborArray(\n value\n .map { elt ->\n when (elt) {\n is JsonPrimitive -> {\n any.fromJson(elt)\n }\n\n is JsonArray -> {\n fromJson(elt)\n }\n\n is JsonObject -> {\n if (CborItemJson.isCborItemValueJson(elt)) {\n newCborItemFromJson(\n elt,\n elt[CDDL_LITERAL]?.jsonPrimitive?.content?.let { CDDL.util.fromFormat(it) },\n )\n } else {\n map.fromJson(elt)\n }\n }\n\n else -> {\n throw IllegalArgumentException(\"Unknown type encountered\")\n }\n }\n }.toMutableList(),\n )\n }\n\n @Serializable(with = CDDLSerializer::class)\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlAny\")\n object any :\n CDDL(\n \"any\",\n ) {\n fun newAny(value: cddl_any) = CborAny(value)\n\n fun fromJson(value: JsonElement): CborItem<*> {\n return newCborItemFromJson(value)\n// TODO(\"Json any to cbor not implemeted yet\")\n }\n }\n\n override fun toTag(additionalInfo: Int?): String {\n if (aliasFor.isNotEmpty()) {\n if (additionalInfo == null) {\n return aliasFor[0].toTag(additionalInfo)\n }\n\n // fixme: this is not correct. We first need to traverse the aliases, as an alias could go without major and additional info\n return util.entries\n .first { it.majorType == majorType && it.info == additionalInfo }\n .toTag(additionalInfo)\n }\n\n var tag = \"#\"\n if (majorType != null) {\n tag += majorType\n }\n if (additionalInfo != null) {\n tag += \".$additionalInfo\"\n }\n return tag\n }\n\n override fun toString(): String = \"CDDL(format='$format', majorType=$majorType, info=$info, aliasFor=${aliasFor.contentToString()})\"\n\n override fun equals(other: Any?): Boolean {\n if (this === other) {\n return true\n }\n if (other !is CDDL) {\n return false\n }\n\n if (format != other.format) {\n return false\n }\n if (majorType != other.majorType) {\n return false\n }\n if (info != other.info) {\n return false\n }\n if (!aliasFor.contentEquals(other.aliasFor)) {\n return false\n }\n\n return true\n }\n\n override fun hashCode(): Int {\n var result = format.hashCode()\n result = 31 * result + (majorType?.hashCode() ?: 0)\n result = 31 * result + (info ?: 0)\n result = 31 * result + aliasFor.contentHashCode()\n return result\n }\n\n object util {\n // Lazy for serialization as this class is used as object in the above CDDL class\n val entries by lazy {\n arrayOf(\n any,\n uint,\n int,\n nint,\n bstr,\n bstr_indef_length,\n bytes,\n tstr,\n tstr_indef_length,\n text,\n tdate,\n full_date,\n time,\n float,\n False,\n True,\n bool,\n nil,\n Null,\n undefined,\n float16,\n float32,\n float64,\n map,\n list,\n )\n }\n\n fun fromFormat(format: String) = entries.first { it.format == format }\n\n fun fromTag(tag: String): CDDL {\n require(tag.startsWith(\"#\")) { \"Invalid tag supplied $tag\" }\n val parts = tag.split(\"#\", \".\")\n if (parts.size == 1) {\n return any\n }\n val majorVal = parts[1].toIntOrNull()\n return fromMajorType(majorVal?.let { MajorType.fromInt(it) }, parts[2].toIntOrNull())\n }\n\n fun fromBytes(input: Int): CDDL {\n val majorType = input shr 5\n\n // todo additionalInto\n return fromMajorType(MajorType.fromInt(majorType))\n }\n\n fun fromMajorType(\n majorType: MajorType? = null,\n additionalInfo: Int? = null,\n ) = entries.first {\n it.majorType == majorType && it.info == additionalInfo\n }\n }\n}\n\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"MajorType\", exact = true)\n@Serializable\n@JsExportCompat\nenum class MajorType(\n val type: Int,\n) {\n /**\n * Major type 0.\n *\n * An unsigned integer in the range 0..2^64-1 inclusive. The value of the encoded item is the\n * argument itself. For example, the integer 10 is denoted as the one byte 0b000_01010 (major\n * type 0, additional information 10). The integer 500 would be 0b000_11001 (major type 0,\n * additional information 25) followed by the two bytes 0x01f4, which is 500 in decimal.\n */\n UNSIGNED_INTEGER(0),\n\n /**\n * Major type 1.\n *\n * A negative integer in the range -2^64..-1 inclusive. The value of the item is -1 minus\n * the argument. For example, the integer -500 would be 0b001_11001 (major type 1, additional\n * information 25) followed by the two bytes 0x01f3, which is 499 in decimal.\n */\n NEGATIVE_INTEGER(1),\n\n /**\n * Major type 2.\n *\n * A byte string. The number of bytes in the string is equal to the argument. For example,\n * a byte string whose length is 5 would have an initial byte of 0b010_00101 (major type 2,\n * additional information 5 for the length), followed by 5 bytes of binary content. A byte\n * string whose length is 500 would have 3 initial bytes of 0b010_11001 (major type 2,\n * additional information 25 to indicate a two-byte length) followed by the two bytes 0x01f4\n * for a length of 500, followed by 500 bytes of binary content.\n */\n BYTE_STRING(2),\n\n /**\n * Major type 3.\n *\n * A text string (Section 2) encoded as UTF-8 [RFC3629]. The number of bytes in the string\n * is equal to the argument. A string containing an invalid UTF-8 sequence is well-formed\n * but invalid (Section 1.2). This type is provided for systems that need to interpret or\n * display human-readable text, and allows the differentiation between unstructured bytes\n * and text that has a specified repertoire (that of Unicode) and encoding (UTF-8). In\n * contrast to formats such as JSON, the Unicode characters in this type are never escaped.\n * Thus, a newline character (U+000A) is always represented in a string as the byte 0x0a,\n * and never as the bytes 0x5c6e (the characters \"\\\" and \"n\") nor as 0x5c7530303061 (the\n * characters \"\\\", \"u\", \"0\", \"0\", \"0\", and \"a\").\n */\n UNICODE_STRING(3),\n\n /**\n * Major type 4.\n * An array of data items. In other formats, arrays are also called lists, sequences, or\n * tuples (a \"CBOR sequence\" is something slightly different, though [RFC8742]). The argument\n * is the number of data items in the array. Items in an array do not need to all be of the\n * same type. For example, an array that contains 10 items of any type would have an initial\n * byte of 0b100_01010 (major type 4, additional information 10 for the length) followed by\n * the 10 remaining items.\n */\n ARRAY(4),\n\n /**\n * Major type 5.\n *\n * A map of pairs of data items. Maps are also called tables, dictionaries, hashes, or\n * objects (in JSON). A map is comprised of pairs of data items, each pair consisting of a\n * key that is immediately followed by a value. The argument is the number of pairs of data\n * items in the map. For example, a map that contains 9 pairs would have an initial byte of\n * 0b101_01001 (major type 5, additional information 9 for the number of pairs) followed by\n * the 18 remaining items. The first item is the first key, the second item is the first\n * value, the third item is the second key, and so on. Because items in a map come in pairs,\n * their total number is always even: a map that contains an odd number of items (no value\n * data present after the last key data item) is not well-formed. A map that has duplicate\n * keys may be well-formed, but it is not valid, and thus it causes indeterminate decoding;\n * see also Section 5.6.\n */\n MAP(5),\n\n /**\n * Major type 6.\n *\n * A tagged data item (\"tag\") whose tag number, an integer in the range 0..2^64-1 inclusive,\n * is the argument and whose enclosed data item (tag content) is the single encoded data item\n * that follows the head. See Section 3.4.\n */\n TAG(6),\n\n /**\n * Major type 7.\n *\n * Floating-point numbers and simple values, as well as the \"break\" stop code. See Section 3.3.\n */\n SPECIAL(7),\n ;\n\n companion object {\n /**\n * Gets a [MajorType] instance from type.\n *\n * @param value an integer between 0 and 7, both inclusive\n * @return a [MajorType] for the given value.\n */\n @JsStatic\n @JvmStatic\n fun fromInt(value: Int): MajorType =\n entries.find { it.type == value }\n ?: throw IllegalArgumentException(\"Unknown major type with value $value\")\n }\n}\n\nabstract class CborSimple(\n value: Type,\n cddl: CDDL,\n) : CborItem(value, cddl) {\n init {\n val info =\n when (cddl) {\n is CDDL.bool -> {\n when (value) {\n true -> CDDL.True.info\n else -> CDDL.False.info\n }\n }\n\n else -> {\n cddl.info\n }\n }\n require(info != null)\n require(info is Int)\n check(info < 24 || (info in 32..255))\n }\n\n override fun encode(builder: ByteStringBuilder) {\n val majorTypeShifted = (majorType!!.type shl 5).toByte()\n builder.append(majorTypeShifted.or(info!!.toByte()))\n }\n\n override fun equals(other: Any?): Boolean = other is CborSimple<*> && value == other.value\n\n override fun hashCode(): Int = value.hashCode()\n\n override fun toString() =\n when (this) {\n FALSE -> \"Simple(FALSE)\"\n TRUE -> \"Simple(TRUE)\"\n NULL -> \"Simple(NULL)\"\n UNDEFINED -> \"Simple(UNDEFINED)\"\n else -> \"Simple($value)\"\n }\n\n companion object {\n /** The [Simple] value for FALSE */\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"CBOR_FALSE\")\n @JsStatic\n @JvmStatic\n val FALSE = CborFalse()\n\n /** The [Simple] value for TRUE */\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"CBOR_TRUE\")\n @JsStatic\n @JvmStatic\n val TRUE = CborTrue()\n\n /** The [Simple] value for NULL */\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"CBOR_NULL\")\n @JsStatic\n @JvmStatic\n val NULL = CborNull()\n\n /** The [Simple] value for UNDEFINED */\n @JsStatic\n @JvmStatic\n val UNDEFINED = CborUndefined()\n }\n}" + }, + "ScheduleVerifierDcqlActivationArgs": { + "kind": "data class", + "name": "ScheduleVerifierDcqlActivationArgs", + "module": "public", + "source": "@Serializable\ndata class ScheduleVerifierDcqlActivationArgs(\n val verifierId: String,\n val queryId: String,\n /** Version to pin at activation time. Defaults to the DCQL query's current version when null. */\n val pinnedVersion: Int? = null,\n val effectiveAt: Instant,\n)\n\n object Defaults {\n /** Default slot interval in minutes for availability calculations */\n const val SLOT_INTERVAL_MINUTES = 30\n\n /** Default concurrency limit (how many concurrent bookings allowed) */\n const val CONCURRENCY_LIMIT = 1\n\n /** Default minimum booking duration in minutes */\n const val MIN_BOOKING_DURATION_MINUTES = 30\n\n /** Default buffer time after each booking in minutes */\n const val BUFFER_AFTER_MINUTES = 0\n\n /** Default for allowing same-day bookings */\n const val ALLOW_SAME_DAY_BOOKING = true\n }" + }, + "VerifierDcqlScheduledActivation": { + "kind": "data class", + "name": "VerifierDcqlScheduledActivation", + "module": "public", + "source": "@Serializable\r\ndata class VerifierDcqlScheduledActivation(\r\n val activationId: String,\r\n val verifierId: String,\r\n val queryId: String,\r\n /** The resolved concrete version pinned by this activation. */\r\n val pinnedVersion: Int,\r\n val effectiveAt: Instant,\r\n val status: ScheduledActivationStatus,\r\n)\n\n@Serializable\r\nenum class ScheduledActivationStatus {\r\n PENDING,\r\n APPLIED,\r\n CANCELLED,\r\n FAILED,\r\n}\n\n data object APPLIED : ReplayOutcome\n\n data class FAILED(\n val failure: WalletOperationReplayFailure\n ) : ReplayOutcome" + }, + "CancelVerifierDcqlActivationArgs": { + "kind": "data class", + "name": "CancelVerifierDcqlActivationArgs", + "module": "public", + "source": "@Serializable\ndata class CancelVerifierDcqlActivationArgs(\n val verifierId: String,\n val queryId: String,\n val activationId: String,\n)" + }, + "ListVerifiersForDcqlArgs": { + "kind": "data class", + "name": "ListVerifiersForDcqlArgs", + "module": "public", + "source": "@Serializable\ndata class ListVerifiersForDcqlArgs(\n val queryId: String,\n)" + }, + "CreatePersonArgs": { + "kind": "data class", + "name": "CreatePersonArgs", + "module": "service-api", + "source": "@Serializable\ndata class CreatePersonArgs(\n val displayName: String,\n val firstName: String? = null,\n val middleName: String? = null,\n val lastName: String? = null,\n val birthDate: LocalDate? = null,\n val origin: PartyOrigin = PartyOrigin.MANAGED,\n val uri: String? = null,\n val jurisdiction: String? = null,\n val ownerId: Uuid? = null,\n val organizationUnitId: Uuid? = null,\n val specializations: List = emptyList(),\n)\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class PartySpecialization\n @JvmOverloads\n constructor(\n /** Human role label for this specialization (e.g. \"employee\", \"customer\", \"supplier\", \"student\") */\n @SerialName(\"subtype\")\n val subtype: String,\n /** The bound semantic Profile id; null indicates an untyped declaration */\n @SerialName(\"profileId\")\n val profileId: String? = null,\n /** The profile version the values were validated/captured against */\n @SerialName(\"profileVersion\")\n val profileVersion: String? = null,\n /**\n * The organization unit this role is scoped to; null means the role is not unit-scoped\n * (tenant-global) and falls back to the party's home organization unit.\n */\n @SerialName(\"organizationUnitId\")\n val organizationUnitId: Uuid? = null,\n /** Values for THIS specialization; populated only when licensed */\n @SerialName(\"attributes\")\n val attributes: JsonObject? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }\n\n @Serializable\n data class Human(\n override val id: String,\n /** Correlation key the engine binds to; UI signals completion against this key. */\n val correlationKey: String,\n /** Bounded wait; null means wait until the workflow's overall deadline. */\n val timeoutSeconds: Long? = null,\n val next: String? = null,\n ) : WorkflowTask()" + }, + "Person": { + "kind": "data class", + "name": "Person", + "module": "public", + "source": " * data class Person(val name: String, val age: Int)" + }, + "GetPersonArgs": { + "kind": "data class", + "name": "GetPersonArgs", + "module": "service-api", + "source": "@Serializable\ndata class GetPersonArgs(val id: Uuid, val include: Set = emptySet())" + }, + "ListPersonsArgs": { + "kind": "data class", + "name": "ListPersonsArgs", + "module": "service-api", + "source": "@Serializable\ndata class ListPersonsArgs(\n val firstName: String? = null,\n val lastName: String? = null,\n val displayName: String? = null,\n val page: PageRequest = PageRequest.DEFAULT,\n val include: Set = emptySet(),\n)\n\n@Serializable\n@JsExportCompat\ndata class PageRequest(\n val pageToken: String? = null,\n val pageSize: Int = DEFAULT_PAGE_SIZE,\n) {\n init {\n require(pageSize in 1..MAX_PAGE_SIZE) {\n \"pageSize must be in 1..$MAX_PAGE_SIZE (was $pageSize)\"\n }\n }\n\n companion object {\n const val DEFAULT_PAGE_SIZE: Int = 50\n const val MAX_PAGE_SIZE: Int = 500\n }\n}" + }, + "UpdatePersonArgs": { + "kind": "data class", + "name": "UpdatePersonArgs", + "module": "service-api", + "source": "@Serializable\ndata class UpdatePersonArgs(\n val id: Uuid,\n val displayName: String? = null,\n val firstName: String? = null,\n val middleName: String? = null,\n val lastName: String? = null,\n val birthDate: LocalDate? = null,\n val uri: String? = null,\n val jurisdiction: String? = null,\n val organizationUnitId: Uuid? = null,\n val specializations: List = emptyList(),\n)\n\n@JsExportCompat\n@Serializable\ndata class PartySpecialization\n @JvmOverloads\n constructor(\n /** Human role label for this specialization (e.g. \"employee\", \"customer\", \"supplier\", \"student\") */\n @SerialName(\"subtype\")\n val subtype: String,\n /** The bound semantic Profile id; null indicates an untyped declaration */\n @SerialName(\"profileId\")\n val profileId: String? = null,\n /** The profile version the values were validated/captured against */\n @SerialName(\"profileVersion\")\n val profileVersion: String? = null,\n /**\n * The organization unit this role is scoped to; null means the role is not unit-scoped\n * (tenant-global) and falls back to the party's home organization unit.\n */\n @SerialName(\"organizationUnitId\")\n val organizationUnitId: Uuid? = null,\n /** Values for THIS specialization; populated only when licensed */\n @SerialName(\"attributes\")\n val attributes: JsonObject? = null,\n )\n\n @Serializable\n data class Human(\n override val id: String,\n /** Correlation key the engine binds to; UI signals completion against this key. */\n val correlationKey: String,\n /** Bounded wait; null means wait until the workflow's overall deadline. */\n val timeoutSeconds: Long? = null,\n val next: String? = null,\n ) : WorkflowTask()" + }, + "DeletePersonArgs": { + "kind": "data class", + "name": "DeletePersonArgs", + "module": "service-api", + "source": "@Serializable\ndata class DeletePersonArgs(val id: Uuid)" + }, + "DeletePersonResult": { + "kind": "data class", + "name": "DeletePersonResult", + "module": "service-api", + "source": "@Serializable\ndata class DeletePersonResult(val deleted: Boolean)" + }, + "CreateOrganizationArgs": { + "kind": "data class", + "name": "CreateOrganizationArgs", + "module": "service-api", + "source": "@Serializable\ndata class CreateOrganizationArgs(\n val displayName: String,\n val legalName: String,\n val organizationType: String? = null,\n val industry: String? = null,\n val contactEmail: String? = null,\n val websiteUrl: String? = null,\n val privacyPolicyUri: String? = null,\n val tosUri: String? = null,\n val origin: PartyOrigin = PartyOrigin.MANAGED,\n val uri: String? = null,\n val jurisdiction: String? = null,\n val ownerId: Uuid? = null,\n val organizationUnitId: Uuid? = null,\n val specializations: List = emptyList(),\n)\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class PartySpecialization\n @JvmOverloads\n constructor(\n /** Human role label for this specialization (e.g. \"employee\", \"customer\", \"supplier\", \"student\") */\n @SerialName(\"subtype\")\n val subtype: String,\n /** The bound semantic Profile id; null indicates an untyped declaration */\n @SerialName(\"profileId\")\n val profileId: String? = null,\n /** The profile version the values were validated/captured against */\n @SerialName(\"profileVersion\")\n val profileVersion: String? = null,\n /**\n * The organization unit this role is scoped to; null means the role is not unit-scoped\n * (tenant-global) and falls back to the party's home organization unit.\n */\n @SerialName(\"organizationUnitId\")\n val organizationUnitId: Uuid? = null,\n /** Values for THIS specialization; populated only when licensed */\n @SerialName(\"attributes\")\n val attributes: JsonObject? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }\n\n @Serializable\n data class Human(\n override val id: String,\n /** Correlation key the engine binds to; UI signals completion against this key. */\n val correlationKey: String,\n /** Bounded wait; null means wait until the workflow's overall deadline. */\n val timeoutSeconds: Long? = null,\n val next: String? = null,\n ) : WorkflowTask()" + }, + "Organization": { + "kind": "data class", + "name": "Organization", + "module": "public", + "source": "@JsExportCompat\n@Serializable\n@SerialName(\"organization\")\ndata class Organization\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n override val partyId: Uuid,\n @SerialName(\"tenantId\")\n override val tenantId: String,\n override val origin: PartyOrigin,\n @SerialName(\"displayName\")\n override val displayName: String,\n override val uri: String? = null,\n override val jurisdiction: String? = null,\n @SerialName(\"ownerId\")\n override val ownerId: Uuid? = null,\n @SerialName(\"organizationUnitId\")\n override val organizationUnitId: Uuid? = null,\n @SerialName(\"specializations\")\n override val specializations: List = emptyList(),\n @SerialName(\"createdAt\")\n override val createdAt: Instant,\n @SerialName(\"createdById\")\n override val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n override val updatedAt: Instant,\n @SerialName(\"updatedById\")\n override val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n override val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n override val deletedById: Uuid? = null,\n @SerialName(\"electronicAddresses\")\n override val electronicAddresses: List? = null,\n @SerialName(\"physicalAddresses\")\n override val physicalAddresses: List? = null,\n /** Registered legal name */\n @SerialName(\"legalName\")\n val legalName: String,\n /** Organization type (e.g. company, foundation, government) */\n @SerialName(\"organizationType\")\n val organizationType: String? = null,\n /** Industry classification */\n @SerialName(\"industry\")\n val industry: String? = null,\n /** Primary contact email */\n @SerialName(\"contactEmail\")\n val contactEmail: String? = null,\n /** Public website URL */\n @SerialName(\"websiteUrl\")\n val websiteUrl: String? = null,\n /** Privacy policy URI */\n @SerialName(\"privacyPolicyUri\")\n val privacyPolicyUri: String? = null,\n /** Terms of service URI */\n @SerialName(\"tosUri\")\n val tosUri: String? = null,\n ) : PartyEntity {\n override val partyType: PartyType get() = PartyType.ORGANIZATION\n }\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class PartySpecialization\n @JvmOverloads\n constructor(\n /** Human role label for this specialization (e.g. \"employee\", \"customer\", \"supplier\", \"student\") */\n @SerialName(\"subtype\")\n val subtype: String,\n /** The bound semantic Profile id; null indicates an untyped declaration */\n @SerialName(\"profileId\")\n val profileId: String? = null,\n /** The profile version the values were validated/captured against */\n @SerialName(\"profileVersion\")\n val profileVersion: String? = null,\n /**\n * The organization unit this role is scoped to; null means the role is not unit-scoped\n * (tenant-global) and falls back to the party's home organization unit.\n */\n @SerialName(\"organizationUnitId\")\n val organizationUnitId: Uuid? = null,\n /** Values for THIS specialization; populated only when licensed */\n @SerialName(\"attributes\")\n val attributes: JsonObject? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class ElectronicAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Type of address (e.g. EMAIL, PHONE, URL, SOCIAL_MEDIA) */\n @SerialName(\"addressType\")\n val addressType: String,\n /** The address value */\n @SerialName(\"value\")\n val value: String,\n /** Optional label (e.g. \"Work\", \"Personal\", \"Mobile\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Whether this address has been verified */\n @SerialName(\"isVerified\")\n val isVerified: Boolean = false,\n /** When the address was verified */\n @SerialName(\"verifiedAt\")\n val verifiedAt: Instant? = null,\n /** When the address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When the address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n)\n\n@JsExportCompat\n@Serializable\ndata class PhysicalAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type/purpose of this address */\n @SerialName(\"addressType\")\n val addressType: String,\n /** User-friendly label (e.g. \"Headquarters\", \"Home\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Street address (house number, street name, unit) */\n @SerialName(\"streetAddress\")\n val streetAddress: String? = null,\n /** City/municipality name */\n @SerialName(\"city\")\n val city: String? = null,\n /** State/province/region */\n @SerialName(\"province\")\n val province: String? = null,\n /** Postal/ZIP code */\n @SerialName(\"postalCode\")\n val postalCode: String? = null,\n /** Country code (ISO 3166-1 alpha-2) */\n @SerialName(\"countryCode\")\n val countryCode: String? = null,\n /** Latitude coordinate */\n @SerialName(\"latitude\")\n val latitude: Double? = null,\n /** Longitude coordinate */\n @SerialName(\"longitude\")\n val longitude: Double? = null,\n /** When this address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When this address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n /** When the address was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the address (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the address was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the address (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the address was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the address (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n)\n\n@JsExportCompat\n@Serializable\n@JsonClassDiscriminator(\"partyType\")\nsealed interface PartyEntity {\n /** Unique identifier for the party */\n val partyId: Uuid\n\n /** Tenant this party belongs to */\n val tenantId: String\n\n /** The type of party (matches the JSON class discriminator) */\n val partyType: PartyType\n\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin\n\n /** User-friendly display name */\n val displayName: String\n\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String?\n\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String?\n\n /** Reference to the owning party */\n val ownerId: Uuid?\n\n /** The single home organization unit; null means the tenant root */\n val organizationUnitId: Uuid?\n\n /** The specializations (roles) this party bears; multi-typing allows several */\n val specializations: List\n\n /** When the party was created */\n val createdAt: Instant\n\n /** Who created the party (party ID) */\n val createdById: Uuid?\n\n /** When the party was last updated */\n val updatedAt: Instant\n\n /** Who last updated the party (party ID) */\n val updatedById: Uuid?\n\n /** When the party was soft-deleted (null if not deleted) */\n val deletedAt: Instant?\n\n /** Who deleted the party (party ID) */\n val deletedById: Uuid?\n\n /**\n * The party's electronic addresses, hydrated on demand. Null means the association was not\n * requested (default); an empty list means it was requested and there are none.\n */\n val electronicAddresses: List?\n\n /**\n * The party's physical addresses, hydrated on demand. Null means the association was not\n * requested (default); an empty list means it was requested and there are none.\n */\n val physicalAddresses: List?\n}\n\n@Serializable\n@JvmInline\nvalue class PartyType(\n val value: String,\n) {\n companion object {\n /** A human individual */\n val NATURAL_PERSON = PartyType(\"natural_person\")\n\n /** Alias for [NATURAL_PERSON] */\n val PERSON = NATURAL_PERSON\n\n /** A company, institution, or other legal entity */\n val ORGANIZATION = PartyType(\"organization\")\n\n /** A software-backed service participant (endpoint, integration, automated actor) */\n val SERVICE = PartyType(\"service\")\n\n /** A software product or deployable component. */\n val SOFTWARE = PartyType(\"software\")\n\n /** A physical, digital, or logical asset that can participate in relationships. */\n val ASSET = PartyType(\"asset\")\n\n /** A unit within an organization (department, division, sub-tenant scope) */\n val ORGANIZATION_UNIT = PartyType(\"organization_unit\")\n\n /** A collection of parties grouped for addressing or authorization */\n val GROUP = PartyType(\"group\")\n\n /** An autonomous actor acting on behalf of another party */\n val AGENT = PartyType(\"agent\")\n }\n\n override fun toString(): String = value\n}\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }\n\n @Serializable\n data class Human(\n override val id: String,\n /** Correlation key the engine binds to; UI signals completion against this key. */\n val correlationKey: String,\n /** Bounded wait; null means wait until the workflow's overall deadline. */\n val timeoutSeconds: Long? = null,\n val next: String? = null,\n ) : WorkflowTask()\n\n@JsExportCompat\r\n@Serializable\r\ndata class Tenant\r\n @JvmOverloads\r\n constructor(\r\n @SerialName(\"id\")\r\n val tenantId: String,\r\n @SerialName(\"tenantType\")\r\n val tenantType: TenantType,\r\n val name: String,\r\n val description: String? = null,\r\n /**\r\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\r\n * platform subdomain label and the dispatcher's peelable path segment.\r\n */\r\n val slug: String,\r\n /**\r\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\r\n * time (cycle detection walks up `parent_tenant_id`).\r\n */\r\n @SerialName(\"parentTenantId\")\r\n val parentTenantId: String? = null,\r\n val status: TenantStatus = TenantStatus.ACTIVE,\r\n /**\r\n * Generic \"system tenant\" flag. System tenants are excluded from default\r\n * listings and from all slug-based / parent-based resolution queries. Customer\r\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\r\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\r\n * their own system-tenant patterns. EDK does not define what a system tenant\r\n * is or what privileges it carries.\r\n */\r\n val system: Boolean = false,\r\n @SerialName(\"ownerPartyId\")\r\n val ownerPartyId: Uuid? = null,\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null,\r\n ) : HasId {\r\n override val id: String get() = tenantId\r\n }\n\n enum class Type {\n WORKFLOW_EXECUTION_STARTED,\n WORKFLOW_EXECUTION_COMPLETED,\n WORKFLOW_EXECUTION_FAILED,\n WORKFLOW_EXECUTION_TIMED_OUT,\n WORKFLOW_EXECUTION_CANCELED,\n WORKFLOW_EXECUTION_TERMINATED,\n WORKFLOW_EXECUTION_CONTINUED_AS_NEW,\n WORKFLOW_TASK_SCHEDULED,\n WORKFLOW_TASK_STARTED,\n WORKFLOW_TASK_COMPLETED,\n WORKFLOW_TASK_FAILED,\n WORKFLOW_TASK_TIMED_OUT,\n ACTIVITY_TASK_SCHEDULED,\n ACTIVITY_TASK_STARTED,\n ACTIVITY_TASK_COMPLETED,\n ACTIVITY_TASK_FAILED,\n ACTIVITY_TASK_TIMED_OUT,\n ACTIVITY_TASK_CANCEL_REQUESTED,\n ACTIVITY_TASK_CANCELED,\n TIMER_STARTED,\n TIMER_FIRED,\n TIMER_CANCELED,\n WORKFLOW_EXECUTION_SIGNALED,\n WORKFLOW_EXECUTION_UPDATE_ACCEPTED,\n WORKFLOW_EXECUTION_UPDATE_COMPLETED,\n WORKFLOW_EXECUTION_UPDATE_REJECTED,\n CHILD_WORKFLOW_EXECUTION_STARTED,\n CHILD_WORKFLOW_EXECUTION_COMPLETED,\n CHILD_WORKFLOW_EXECUTION_FAILED,\n MARKER_RECORDED,\n OTHER,\n }\n\n enum class State {\n CLOSED,\n OPEN,\n HALF_OPEN\n }\n\n /** Filter by schema object ID */\r\n @SerialName(\"schemaId\")\n\n-- discriminator-tagged sealed-interface JSON via kotlinx-serialization." + }, + "CreateOrganizationUnitArgs": { + "kind": "data class", + "name": "CreateOrganizationUnitArgs", + "module": "service-api", + "source": "@Serializable\ndata class CreateOrganizationUnitArgs(\n val displayName: String,\n val name: String,\n val parentOuId: Uuid? = null,\n val tosUri: String? = null,\n val branding: JsonObject? = null,\n val ouInheritancePolicy: String = \"READ_ONLY_ANCESTOR\",\n val origin: PartyOrigin = PartyOrigin.MANAGED,\n val uri: String? = null,\n val jurisdiction: String? = null,\n val ownerId: Uuid? = null,\n val organizationUnitId: Uuid? = null,\n val specializations: List = emptyList(),\n)\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class PartySpecialization\n @JvmOverloads\n constructor(\n /** Human role label for this specialization (e.g. \"employee\", \"customer\", \"supplier\", \"student\") */\n @SerialName(\"subtype\")\n val subtype: String,\n /** The bound semantic Profile id; null indicates an untyped declaration */\n @SerialName(\"profileId\")\n val profileId: String? = null,\n /** The profile version the values were validated/captured against */\n @SerialName(\"profileVersion\")\n val profileVersion: String? = null,\n /**\n * The organization unit this role is scoped to; null means the role is not unit-scoped\n * (tenant-global) and falls back to the party's home organization unit.\n */\n @SerialName(\"organizationUnitId\")\n val organizationUnitId: Uuid? = null,\n /** Values for THIS specialization; populated only when licensed */\n @SerialName(\"attributes\")\n val attributes: JsonObject? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }\n\n @Serializable\n data class Human(\n override val id: String,\n /** Correlation key the engine binds to; UI signals completion against this key. */\n val correlationKey: String,\n /** Bounded wait; null means wait until the workflow's overall deadline. */\n val timeoutSeconds: Long? = null,\n val next: String? = null,\n ) : WorkflowTask()" + }, + "OrganizationUnit": { + "kind": "data class", + "name": "OrganizationUnit", + "module": "public", + "source": "@JsExportCompat\n@Serializable\n@SerialName(\"organization_unit\")\ndata class OrganizationUnit\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n override val partyId: Uuid,\n @SerialName(\"tenantId\")\n override val tenantId: String,\n override val origin: PartyOrigin,\n @SerialName(\"displayName\")\n override val displayName: String,\n override val uri: String? = null,\n override val jurisdiction: String? = null,\n @SerialName(\"ownerId\")\n override val ownerId: Uuid? = null,\n @SerialName(\"organizationUnitId\")\n override val organizationUnitId: Uuid? = null,\n @SerialName(\"specializations\")\n override val specializations: List = emptyList(),\n @SerialName(\"createdAt\")\n override val createdAt: Instant,\n @SerialName(\"createdById\")\n override val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n override val updatedAt: Instant,\n @SerialName(\"updatedById\")\n override val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n override val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n override val deletedById: Uuid? = null,\n @SerialName(\"electronicAddresses\")\n override val electronicAddresses: List? = null,\n @SerialName(\"physicalAddresses\")\n override val physicalAddresses: List? = null,\n /** Parent organization unit; null means this unit sits directly under the organization root */\n @SerialName(\"parentOuId\")\n val parentOuId: Uuid? = null,\n /** Unit name */\n @SerialName(\"name\")\n val name: String,\n /** Terms of service URI for this unit */\n @SerialName(\"tosUri\")\n val tosUri: String? = null,\n /** Unit-level branding configuration */\n @SerialName(\"branding\")\n val branding: JsonObject? = null,\n /** How this unit inherits configuration from its ancestors */\n @SerialName(\"ouInheritancePolicy\")\n val ouInheritancePolicy: String = \"READ_ONLY_ANCESTOR\",\n /**\n * The direct child organization units, hydrated on demand. Null means the association\n * was not requested (default); an empty list means it was requested and there are none.\n */\n @SerialName(\"childUnits\")\n val childUnits: List? = null,\n /**\n * The parties that have this unit as their home organization unit, hydrated on demand.\n * Null means the association was not requested (default).\n */\n @SerialName(\"members\")\n val members: List? = null,\n ) : PartyEntity {\n override val partyType: PartyType get() = PartyType.ORGANIZATION_UNIT\n }\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class PartySpecialization\n @JvmOverloads\n constructor(\n /** Human role label for this specialization (e.g. \"employee\", \"customer\", \"supplier\", \"student\") */\n @SerialName(\"subtype\")\n val subtype: String,\n /** The bound semantic Profile id; null indicates an untyped declaration */\n @SerialName(\"profileId\")\n val profileId: String? = null,\n /** The profile version the values were validated/captured against */\n @SerialName(\"profileVersion\")\n val profileVersion: String? = null,\n /**\n * The organization unit this role is scoped to; null means the role is not unit-scoped\n * (tenant-global) and falls back to the party's home organization unit.\n */\n @SerialName(\"organizationUnitId\")\n val organizationUnitId: Uuid? = null,\n /** Values for THIS specialization; populated only when licensed */\n @SerialName(\"attributes\")\n val attributes: JsonObject? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class ElectronicAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Type of address (e.g. EMAIL, PHONE, URL, SOCIAL_MEDIA) */\n @SerialName(\"addressType\")\n val addressType: String,\n /** The address value */\n @SerialName(\"value\")\n val value: String,\n /** Optional label (e.g. \"Work\", \"Personal\", \"Mobile\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Whether this address has been verified */\n @SerialName(\"isVerified\")\n val isVerified: Boolean = false,\n /** When the address was verified */\n @SerialName(\"verifiedAt\")\n val verifiedAt: Instant? = null,\n /** When the address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When the address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n)\n\n@JsExportCompat\n@Serializable\ndata class PhysicalAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type/purpose of this address */\n @SerialName(\"addressType\")\n val addressType: String,\n /** User-friendly label (e.g. \"Headquarters\", \"Home\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Street address (house number, street name, unit) */\n @SerialName(\"streetAddress\")\n val streetAddress: String? = null,\n /** City/municipality name */\n @SerialName(\"city\")\n val city: String? = null,\n /** State/province/region */\n @SerialName(\"province\")\n val province: String? = null,\n /** Postal/ZIP code */\n @SerialName(\"postalCode\")\n val postalCode: String? = null,\n /** Country code (ISO 3166-1 alpha-2) */\n @SerialName(\"countryCode\")\n val countryCode: String? = null,\n /** Latitude coordinate */\n @SerialName(\"latitude\")\n val latitude: Double? = null,\n /** Longitude coordinate */\n @SerialName(\"longitude\")\n val longitude: Double? = null,\n /** When this address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When this address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n /** When the address was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the address (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the address was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the address (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the address was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the address (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n)\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNull\")\n @Serializable(with = CDDLSerializer::class)\n object Null : CDDL(\"null\", MajorType.SPECIAL, 22, arrayOf(nil)) {\n fun newNull() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n@JsExportCompat\n@Serializable\n@JsonClassDiscriminator(\"partyType\")\nsealed interface PartyEntity {\n /** Unique identifier for the party */\n val partyId: Uuid\n\n /** Tenant this party belongs to */\n val tenantId: String\n\n /** The type of party (matches the JSON class discriminator) */\n val partyType: PartyType\n\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin\n\n /** User-friendly display name */\n val displayName: String\n\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String?\n\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String?\n\n /** Reference to the owning party */\n val ownerId: Uuid?\n\n /** The single home organization unit; null means the tenant root */\n val organizationUnitId: Uuid?\n\n /** The specializations (roles) this party bears; multi-typing allows several */\n val specializations: List\n\n /** When the party was created */\n val createdAt: Instant\n\n /** Who created the party (party ID) */\n val createdById: Uuid?\n\n /** When the party was last updated */\n val updatedAt: Instant\n\n /** Who last updated the party (party ID) */\n val updatedById: Uuid?\n\n /** When the party was soft-deleted (null if not deleted) */\n val deletedAt: Instant?\n\n /** Who deleted the party (party ID) */\n val deletedById: Uuid?\n\n /**\n * The party's electronic addresses, hydrated on demand. Null means the association was not\n * requested (default); an empty list means it was requested and there are none.\n */\n val electronicAddresses: List?\n\n /**\n * The party's physical addresses, hydrated on demand. Null means the association was not\n * requested (default); an empty list means it was requested and there are none.\n */\n val physicalAddresses: List?\n}\n\n@Serializable\n@JvmInline\nvalue class PartyType(\n val value: String,\n) {\n companion object {\n /** A human individual */\n val NATURAL_PERSON = PartyType(\"natural_person\")\n\n /** Alias for [NATURAL_PERSON] */\n val PERSON = NATURAL_PERSON\n\n /** A company, institution, or other legal entity */\n val ORGANIZATION = PartyType(\"organization\")\n\n /** A software-backed service participant (endpoint, integration, automated actor) */\n val SERVICE = PartyType(\"service\")\n\n /** A software product or deployable component. */\n val SOFTWARE = PartyType(\"software\")\n\n /** A physical, digital, or logical asset that can participate in relationships. */\n val ASSET = PartyType(\"asset\")\n\n /** A unit within an organization (department, division, sub-tenant scope) */\n val ORGANIZATION_UNIT = PartyType(\"organization_unit\")\n\n /** A collection of parties grouped for addressing or authorization */\n val GROUP = PartyType(\"group\")\n\n /** An autonomous actor acting on behalf of another party */\n val AGENT = PartyType(\"agent\")\n }\n\n override fun toString(): String = value\n}\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }\n\n @Serializable\n data class Human(\n override val id: String,\n /** Correlation key the engine binds to; UI signals completion against this key. */\n val correlationKey: String,\n /** Bounded wait; null means wait until the workflow's overall deadline. */\n val timeoutSeconds: Long? = null,\n val next: String? = null,\n ) : WorkflowTask()\n\n@JsExportCompat\r\n@Serializable\r\ndata class Tenant\r\n @JvmOverloads\r\n constructor(\r\n @SerialName(\"id\")\r\n val tenantId: String,\r\n @SerialName(\"tenantType\")\r\n val tenantType: TenantType,\r\n val name: String,\r\n val description: String? = null,\r\n /**\r\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\r\n * platform subdomain label and the dispatcher's peelable path segment.\r\n */\r\n val slug: String,\r\n /**\r\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\r\n * time (cycle detection walks up `parent_tenant_id`).\r\n */\r\n @SerialName(\"parentTenantId\")\r\n val parentTenantId: String? = null,\r\n val status: TenantStatus = TenantStatus.ACTIVE,\r\n /**\r\n * Generic \"system tenant\" flag. System tenants are excluded from default\r\n * listings and from all slug-based / parent-based resolution queries. Customer\r\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\r\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\r\n * their own system-tenant patterns. EDK does not define what a system tenant\r\n * is or what privileges it carries.\r\n */\r\n val system: Boolean = false,\r\n @SerialName(\"ownerPartyId\")\r\n val ownerPartyId: Uuid? = null,\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null,\r\n ) : HasId {\r\n override val id: String get() = tenantId\r\n }\n\n enum class Type {\n WORKFLOW_EXECUTION_STARTED,\n WORKFLOW_EXECUTION_COMPLETED,\n WORKFLOW_EXECUTION_FAILED,\n WORKFLOW_EXECUTION_TIMED_OUT,\n WORKFLOW_EXECUTION_CANCELED,\n WORKFLOW_EXECUTION_TERMINATED,\n WORKFLOW_EXECUTION_CONTINUED_AS_NEW,\n WORKFLOW_TASK_SCHEDULED,\n WORKFLOW_TASK_STARTED,\n WORKFLOW_TASK_COMPLETED,\n WORKFLOW_TASK_FAILED,\n WORKFLOW_TASK_TIMED_OUT,\n ACTIVITY_TASK_SCHEDULED,\n ACTIVITY_TASK_STARTED,\n ACTIVITY_TASK_COMPLETED,\n ACTIVITY_TASK_FAILED,\n ACTIVITY_TASK_TIMED_OUT,\n ACTIVITY_TASK_CANCEL_REQUESTED,\n ACTIVITY_TASK_CANCELED,\n TIMER_STARTED,\n TIMER_FIRED,\n TIMER_CANCELED,\n WORKFLOW_EXECUTION_SIGNALED,\n WORKFLOW_EXECUTION_UPDATE_ACCEPTED,\n WORKFLOW_EXECUTION_UPDATE_COMPLETED,\n WORKFLOW_EXECUTION_UPDATE_REJECTED,\n CHILD_WORKFLOW_EXECUTION_STARTED,\n CHILD_WORKFLOW_EXECUTION_COMPLETED,\n CHILD_WORKFLOW_EXECUTION_FAILED,\n MARKER_RECORDED,\n OTHER,\n }\n\n enum class State {\n CLOSED,\n OPEN,\n HALF_OPEN\n }\n\n /** Filter by schema object ID */\r\n @SerialName(\"schemaId\")" + }, + "CreateServiceArgs": { + "kind": "data class", + "name": "CreateServiceArgs", + "module": "service-api", + "source": "@Serializable\ndata class CreateServiceArgs(\n val displayName: String,\n val serviceType: String? = null,\n val endpointUri: String? = null,\n val oauthClientId: String? = null,\n val origin: PartyOrigin = PartyOrigin.MANAGED,\n val uri: String? = null,\n val jurisdiction: String? = null,\n val ownerId: Uuid? = null,\n val organizationUnitId: Uuid? = null,\n val specializations: List = emptyList(),\n)\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class PartySpecialization\n @JvmOverloads\n constructor(\n /** Human role label for this specialization (e.g. \"employee\", \"customer\", \"supplier\", \"student\") */\n @SerialName(\"subtype\")\n val subtype: String,\n /** The bound semantic Profile id; null indicates an untyped declaration */\n @SerialName(\"profileId\")\n val profileId: String? = null,\n /** The profile version the values were validated/captured against */\n @SerialName(\"profileVersion\")\n val profileVersion: String? = null,\n /**\n * The organization unit this role is scoped to; null means the role is not unit-scoped\n * (tenant-global) and falls back to the party's home organization unit.\n */\n @SerialName(\"organizationUnitId\")\n val organizationUnitId: Uuid? = null,\n /** Values for THIS specialization; populated only when licensed */\n @SerialName(\"attributes\")\n val attributes: JsonObject? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }\n\n @Serializable\n data class Human(\n override val id: String,\n /** Correlation key the engine binds to; UI signals completion against this key. */\n val correlationKey: String,\n /** Bounded wait; null means wait until the workflow's overall deadline. */\n val timeoutSeconds: Long? = null,\n val next: String? = null,\n ) : WorkflowTask()" + }, + "Service": { + "kind": "data class", + "name": "Service", + "module": "public", + "source": " public data class Service(\n public val uuid: Uuid,\n ) : Filter()\n\n@JsExportCompat\npublic sealed class Filter {\n /**\n * | Platform | Supported | Details |\n * |------------|:---------------:|----------------------------------------------------------------------------------------------|\n * | Android | Yes | Supported natively |\n * | Apple | Yes1 | Supported natively if the only filter type used, otherwise provided by Kable via flow filter |\n * | JavaScript | Yes | Supported natively |\n *\n * 1: The recommended practice is to provide only [service filter][Filter.Service]s on Apple platform.\n * If any filters other than [Filter.Service] are used on Apple platform, then filtering will not be performed natively.\n */\n public data class Service(\n public val uuid: Uuid,\n ) : Filter()\n\n public sealed class Name : Filter() {\n /**\n * | Platform | Supported | Details |\n * |------------|:---------:|-------------------------------------------|\n * | Android | Yes | Supported natively |\n * | Apple | Yes | Support provided by Kable via flow filter |\n * | JavaScript | Yes | Supported natively |\n */\n public data class Exact(\n public val exact: String,\n ) : Name()\n\n /**\n * | Platform | Supported | Details |\n * |------------|:---------:|-------------------------------------------|\n * | Android | Yes | Support provided by Kable via flow filter |\n * | Apple | Yes | Support provided by Kable via flow filter |\n * | JavaScript | Yes | Supported natively |\n */\n public data class Prefix(\n val prefix: String,\n ) : Name()\n }\n\n /**\n * | Platform | Supported | Details |\n * |------------|:---------:|----------------------------------------|\n * | Android | Yes | Supported natively |\n * | Apple | No | Throws [UnsupportedOperationException] |\n * | JavaScript | No | Throws [UnsupportedOperationException] |\n */\n public data class Address(\n public val address: String,\n ) : Filter()\n\n /**\n * Provides support for filtering against advertisement manufacturer data.\n *\n * If only portions of the manufacturer [data] needs to match, then [dataMask] can be used to identify the relevant\n * bits.\n *\n * Some examples to demonstrate the [dataMask] functionality:\n *\n * | [dataMask] value | Bit representation | [data] only needs to match... |\n * |---------------------------|---------------------|----------------------------------------------------------------|\n * | `byteArrayOf(0x0F, 0x00)` | 0000 1111 0000 0000 | bits 0-3 of the first byte of advertisement manufacturer data. |\n * | `byteArrayOf(0x00, 0xFF)` | 0000 0000 1111 1111 | the 2nd byte of advertisement manufacturer data. |\n * | `byteArrayOf(0xF0)` | 1111 0000 | bits 4-7 of the first byte of advertisement manufacturer data. |\n *\n * | Platform | Supported | Details |\n * |------------|:---------:|-------------------------------------------|\n * | Android | Yes | Supported natively |\n * | Apple | Yes | Support provided by Kable via flow filter |\n * | JavaScript | Yes | Supported natively |\n *\n * JavaScript support was added in Chrome 92 according to: https://developer.chrome.com/articles/bluetooth/#manufacturer-data-filter\n */\n public class ManufacturerData(\n /**\n * Company identifier (16-bit).\n * A negative [id] is considered an invalid id.\n *\n * List of assigned numbers can be found at (section: 7 Company Identifiers): https://www.bluetooth.com/specifications/assigned-numbers/\n */\n public val id: Int,\n /** Must be non-`null` if [dataMask] is non-`null`. */\n public val data: ByteArray? = null,\n /**\n * For any bit in the mask, set it to 1 if advertisement manufacturer data needs to match the corresponding bit\n * in [data], otherwise set it to 0. If [dataMask] is not `null`, then it must have the same length as [data].\n */\n public val dataMask: ByteArray? = null,\n ) : Filter() {\n @JvmOverloads\n public constructor(id: ByteArray, data: ByteArray? = null, dataMask: ByteArray? = null) : this(id.toShort(), data, dataMask)\n\n init {\n require(id >= 0) { \"Company identifier cannot be negative, was $id\" }\n require(id <= 65535) { \"Company identifier cannot be more than 16-bits (65535), was $id\" }\n require(data == null || data.isNotEmpty()) { \"If data is present (non-null), it must be non-empty\" }\n if (dataMask != null) {\n requireNotNull(data) { \"Data is null but must be non-null when dataMask is non-null\" }\n requireDataAndMaskHaveSameLength(data, dataMask)\n }\n }\n\n override fun toString(): String = \"ManufacturerData(id=$id, data=${data?.toHexString()}, dataMask=${dataMask?.toHexString()})\"\n }\n\n /**\n * Provides support for filtering against advertisement service data.\n *\n * If only portions of the service [data] needs to match, then [dataMask] can be used to\n * identify the relevant bits.\n *\n * Some examples to demonstrate the [dataMask] functionality:\n *\n * | [dataMask] value | Bit representation | [data] only needs to match... |\n * |---------------------------|---------------------|-----------------------------------------------------------|\n * | `byteArrayOf(0x0F, 0x00)` | 0000 1111 0000 0000 | bits 0-3 of the first byte of advertisement service data. |\n * | `byteArrayOf(0x00, 0xFF)` | 0000 0000 1111 1111 | the 2nd byte of advertisement service data. |\n * | `byteArrayOf(0xF0)` | 1111 0000 | bits 4-7 of the first byte of advertisement service data. |\n *\n * | Platform | Supported | Details |\n * |------------|:---------:|-------------------------------------------|\n * | Android | Yes | Supported natively |\n * | Apple | Yes | Support provided by Kable via flow filter |\n * | JavaScript | Yes | Support provided by Kable via flow filter |\n */\n public class ServiceData(\n public val uuid: Uuid,\n public val data: ByteArray? = null,\n /**\n * For any bit in the mask, set it to 1 if advertisement service data needs to match the\n * corresponding bit in [data], otherwise set it to 0. If [dataMask] is not `null`, then it\n * must have the same length as [data].\n */\n public val dataMask: ByteArray? = null,\n ) : Filter() {\n init {\n require(data == null || data.isNotEmpty()) { \"If data is present (non-null), it must be non-empty\" }\n if (dataMask != null) {\n requireNotNull(data) { \"Data is null but must be non-null when dataMask is non-null\" }\n requireDataAndMaskHaveSameLength(data, dataMask)\n }\n }\n\n override fun toString(): String = \"ServiceData(uuid=$uuid, data=${data?.toHexString()}, dataMask=${dataMask?.toHexString()})\"\n }\n}\n\n public sealed class Name : Filter() {\n /**\n * | Platform | Supported | Details |\n * |------------|:---------:|-------------------------------------------|\n * | Android | Yes | Supported natively |\n * | Apple | Yes | Support provided by Kable via flow filter |\n * | JavaScript | Yes | Supported natively |\n */\n public data class Exact(\n public val exact: String,\n ) : Name()\n\n /**\n * | Platform | Supported | Details |\n * |------------|:---------:|-------------------------------------------|\n * | Android | Yes | Support provided by Kable via flow filter |\n * | Apple | Yes | Support provided by Kable via flow filter |\n * | JavaScript | Yes | Supported natively |\n */\n public data class Prefix(\n val prefix: String,\n ) : Name()\n }\n\n public data class Exact(\n public val exact: String,\n ) : Name()\n\n public data class Prefix(\n val prefix: String,\n ) : Name()\n\n public data class Address(\n public val address: String,\n ) : Filter()\n\n public class ManufacturerData(\n /**\n * Company identifier (16-bit).\n * A negative [id] is considered an invalid id.\n *\n * List of assigned numbers can be found at (section: 7 Company Identifiers): https://www.bluetooth.com/specifications/assigned-numbers/\n */\n public val id: Int,\n /** Must be non-`null` if [dataMask] is non-`null`. */\n public val data: ByteArray? = null,\n /**\n * For any bit in the mask, set it to 1 if advertisement manufacturer data needs to match the corresponding bit\n * in [data], otherwise set it to 0. If [dataMask] is not `null`, then it must have the same length as [data].\n */\n public val dataMask: ByteArray? = null,\n ) : Filter() {\n @JvmOverloads\n public constructor(id: ByteArray, data: ByteArray? = null, dataMask: ByteArray? = null) : this(id.toShort(), data, dataMask)\n\n init {\n require(id >= 0) { \"Company identifier cannot be negative, was $id\" }\n require(id <= 65535) { \"Company identifier cannot be more than 16-bits (65535), was $id\" }\n require(data == null || data.isNotEmpty()) { \"If data is present (non-null), it must be non-empty\" }\n if (dataMask != null) {\n requireNotNull(data) { \"Data is null but must be non-null when dataMask is non-null\" }\n requireDataAndMaskHaveSameLength(data, dataMask)\n }\n }\n\n override fun toString(): String = \"ManufacturerData(id=$id, data=${data?.toHexString()}, dataMask=${dataMask?.toHexString()})\"\n }\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"Data\", exact = true)\n data class Data(\n val value: ByteArray,\n ) : BleResponse()\n\n public class ServiceData(\n public val uuid: Uuid,\n public val data: ByteArray? = null,\n /**\n * For any bit in the mask, set it to 1 if advertisement service data needs to match the\n * corresponding bit in [data], otherwise set it to 0. If [dataMask] is not `null`, then it\n * must have the same length as [data].\n */\n public val dataMask: ByteArray? = null,\n ) : Filter() {\n init {\n require(data == null || data.isNotEmpty()) { \"If data is present (non-null), it must be non-empty\" }\n if (dataMask != null) {\n requireNotNull(data) { \"Data is null but must be non-null when dataMask is non-null\" }\n requireDataAndMaskHaveSameLength(data, dataMask)\n }\n }\n\n override fun toString(): String = \"ServiceData(uuid=$uuid, data=${data?.toHexString()}, dataMask=${dataMask?.toHexString()})\"\n }" + }, + "SetApplicationLoginConfigArgs": { + "kind": "data class", + "name": "SetApplicationLoginConfigArgs", + "module": "service-api", + "source": "@Serializable\ndata class SetApplicationLoginConfigArgs(\n val applicationId: Uuid,\n val allowedMethods: Set = emptySet(),\n val loginIdentifierTypes: Set = emptySet(),\n val allowedIdpIds: Set = emptySet(),\n val selfRegistration: Boolean = false,\n)\n\n@Serializable\n@JvmInline\nvalue class AuthMethod(\n val value: String,\n) {\n companion object {\n /** Username/identifier plus password. */\n val PASSWORD = AuthMethod(\"password\")\n\n /** One-time passcode delivered by email. */\n val EMAIL_OTP = AuthMethod(\"email_otp\")\n\n /** Single-use magic link delivered out of band. */\n val MAGIC_LINK = AuthMethod(\"magic_link\")\n\n /** Time-based one-time password (authenticator app). */\n val TOTP = AuthMethod(\"totp\")\n\n /** Federated login via an external OIDC identity provider. */\n val FEDERATED_OIDC = AuthMethod(\"federated_oidc\")\n\n /** Wallet-based authentication (verifiable presentation). */\n val WALLET = AuthMethod(\"wallet\")\n }\n\n override fun toString(): String = value\n}\n\n@Serializable\n@JvmInline\nvalue class IdentifierType(\n val value: String,\n) {\n companion object {\n /** W3C Decentralized Identifier */\n val DID = IdentifierType(\"did\")\n\n /** X.509 Certificate (has identifier_x509 extension) */\n val X509 = IdentifierType(\"x509\")\n\n val VAT = IdentifierType(\"vat\")\n val NTR = IdentifierType(\"ntr\")\n val PSD = IdentifierType(\"psd\")\n val LEI = IdentifierType(\"lei\")\n val LEGAL_LOCAL = IdentifierType(\"legal_local\")\n\n val PAS = IdentifierType(\"pas\")\n val IDC = IdentifierType(\"idc\")\n val PNO = IdentifierType(\"pno\")\n val TIN = IdentifierType(\"tin\")\n val TAX = IdentifierType(\"tax\")\n val EID = IdentifierType(\"eid\")\n val NATURAL_LOCAL = IdentifierType(\"natural_local\")\n\n val EORI = IdentifierType(\"eori\")\n val EUID = IdentifierType(\"euid\")\n val VATIN = IdentifierType(\"vatin\")\n val LEGAL_TIN = IdentifierType(\"legal_tin\")\n val EXCISE = IdentifierType(\"excise\")\n\n val ISO6523_ORG_ID = IdentifierType(\"iso6523_org_id\")\n val VLEI = IdentifierType(\"vlei\")\n val BIC = IdentifierType(\"bic\")\n val ISNI = IdentifierType(\"isni\")\n val IBAN = IdentifierType(\"iban\")\n val IIN = IdentifierType(\"iin\")\n val PAN = IdentifierType(\"pan\")\n val ISIN = IdentifierType(\"isin\")\n val MIC = IdentifierType(\"mic\")\n val UUID = IdentifierType(\"uuid\")\n val OID = IdentifierType(\"oid\")\n val ISO15459_ID = IdentifierType(\"iso15459_id\")\n val VIN = IdentifierType(\"vin\")\n val WMI = IdentifierType(\"wmi\")\n val CONTAINER_ID = IdentifierType(\"container_id\")\n\n val EMAIL = IdentifierType(\"email\")\n val PHONE = IdentifierType(\"phone\")\n val DOMAIN = IdentifierType(\"domain\")\n val URL = IdentifierType(\"url\")\n val WEBSITE = IdentifierType(\"website\")\n val ISSUER = IdentifierType(\"issuer\")\n val OIDC_ISSUER = IdentifierType(\"oidc_issuer\")\n val OID4VCI_ISSUER = IdentifierType(\"oid4vci_issuer\")\n val VERIFIER = IdentifierType(\"verifier\")\n val JWKS_URL = IdentifierType(\"jwks_url\")\n }\n\n override fun toString(): String = value\n}\n\n @Serializable\r\n data class Federated(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n /**\n * Owner's stable identifier inside the external IDP — typically the `sub`\r\n * claim, but can be any claim agreed in [FederationProviderInput.claimMapping].\r\n */\r\n val externalSubject: String,\n val ownerPartyId: Uuid? = null,\n ) : OwnerInput()\n\ninterface Wallet {\n /** Access to persisted credential records and metadata sidecars. */\n val credentials: WalletCredentialStore\n\n /** Access to pending/resumable OID4VCI issuance sessions. */\n val issuanceSessions: WalletIssuanceSessionStore\n\n /**\n * Creates (or retrieves) a holder key scoped to [walletInstanceId], returning the\n * managed key alias. If [alias] is null a wallet-scoped alias is generated automatically.\n */\n suspend fun createHolderKey(\n walletInstanceId: String,\n alias: String? = null,\n ): IdkResult\n\n /**\n * Initiates an authorization code flow for the given issuer, returning the data\n * needed to redirect the user to the authorization endpoint.\n */\n suspend fun startAuthorizationCodeFlow(\n credentialIssuer: String,\n config: WalletConfig,\n scope: String? = null,\n ): IdkResult\n\n /**\n * Completes an authorization code flow by exchanging the authorization code for tokens.\n */\n suspend fun completeAuthorizationCodeFlow(\n start: AuthCodeStart,\n code: String,\n ): IdkResult\n\n /**\n * Exchanges a pre-authorized code (from a credential offer) for tokens.\n */\n suspend fun exchangePreAuthorizedCode(\n credentialIssuer: String,\n preAuthorizedCode: String,\n txCode: String? = null,\n config: WalletConfig? = null,\n ): IdkResult\n\n /**\n * Obtains one or more credential instances from the issuer. Synchronous issuance stores a\n * [CredentialRecord]; deferred issuance stores an [IssuanceSession] without creating a\n * credential record until polling returns an actual credential artifact.\n */\n suspend fun obtainCredential(request: ObtainCredentialRequest): IdkResult\n\n /**\n * Polls a persisted deferred issuance session and stores the resulting credential only after\n * the deferred endpoint returns the credential artifact.\n */\n suspend fun resumeDeferredIssuance(request: ResumeDeferredIssuanceRequest): IdkResult\n\n /**\n * Refreshes or reissues an existing credential record as a new credential instance.\n * The prior credential body is never overwritten.\n */\n suspend fun refreshCredential(request: RefreshCredentialRequest): IdkResult\n\n /**\n * Responds to a verifier's authorization request URI, performing a presentation exchange.\n */\n suspend fun present(\n requestUri: String,\n config: WalletConfig,\n ): IdkResult\n}" + }, + "ApplicationLoginConfigResult": { + "kind": "data class", + "name": "ApplicationLoginConfigResult", + "module": "persistence-api", + "source": "@Serializable\r\ndata class ApplicationLoginConfigResult(\r\n @SerialName(\"applicationId\")\r\n val applicationId: Uuid,\r\n\r\n @SerialName(\"tenantId\")\r\n val tenantId: String,\r\n\r\n @SerialName(\"allowedMethods\")\r\n val allowedMethods: Set = emptySet(),\r\n\r\n @SerialName(\"loginIdentifierTypes\")\r\n val loginIdentifierTypes: Set = emptySet(),\r\n\r\n @SerialName(\"allowedIdpIds\")\r\n val allowedIdpIds: Set = emptySet(),\r\n\r\n @SerialName(\"selfRegistration\")\r\n val selfRegistration: Boolean = false,\r\n\r\n // Audit fields\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null\r\n) {\r\n companion object {\r\n fun from(config: ApplicationLoginConfig) = ApplicationLoginConfigResult(\r\n applicationId = config.applicationId,\r\n tenantId = config.tenantId,\r\n allowedMethods = config.allowedMethods,\r\n loginIdentifierTypes = config.loginIdentifierTypes,\r\n allowedIdpIds = config.allowedIdpIds,\r\n selfRegistration = config.selfRegistration,\r\n createdAt = config.createdAt,\r\n createdById = config.createdById,\r\n updatedAt = config.updatedAt,\r\n updatedById = config.updatedById,\r\n deletedAt = config.deletedAt,\r\n deletedById = config.deletedById\r\n )\r\n }\r\n\r\n fun toApplicationLoginConfig() = ApplicationLoginConfig(\r\n applicationId = applicationId,\r\n tenantId = tenantId,\r\n allowedMethods = allowedMethods,\r\n loginIdentifierTypes = loginIdentifierTypes,\r\n allowedIdpIds = allowedIdpIds,\r\n selfRegistration = selfRegistration,\r\n createdAt = createdAt,\r\n createdById = createdById,\r\n updatedAt = updatedAt,\r\n updatedById = updatedById,\r\n deletedAt = deletedAt,\r\n deletedById = deletedById\r\n )\r\n}\n\n@Serializable\n@JvmInline\nvalue class AuthMethod(\n val value: String,\n) {\n companion object {\n /** Username/identifier plus password. */\n val PASSWORD = AuthMethod(\"password\")\n\n /** One-time passcode delivered by email. */\n val EMAIL_OTP = AuthMethod(\"email_otp\")\n\n /** Single-use magic link delivered out of band. */\n val MAGIC_LINK = AuthMethod(\"magic_link\")\n\n /** Time-based one-time password (authenticator app). */\n val TOTP = AuthMethod(\"totp\")\n\n /** Federated login via an external OIDC identity provider. */\n val FEDERATED_OIDC = AuthMethod(\"federated_oidc\")\n\n /** Wallet-based authentication (verifiable presentation). */\n val WALLET = AuthMethod(\"wallet\")\n }\n\n override fun toString(): String = value\n}\n\n@Serializable\n@JvmInline\nvalue class IdentifierType(\n val value: String,\n) {\n companion object {\n /** W3C Decentralized Identifier */\n val DID = IdentifierType(\"did\")\n\n /** X.509 Certificate (has identifier_x509 extension) */\n val X509 = IdentifierType(\"x509\")\n\n val VAT = IdentifierType(\"vat\")\n val NTR = IdentifierType(\"ntr\")\n val PSD = IdentifierType(\"psd\")\n val LEI = IdentifierType(\"lei\")\n val LEGAL_LOCAL = IdentifierType(\"legal_local\")\n\n val PAS = IdentifierType(\"pas\")\n val IDC = IdentifierType(\"idc\")\n val PNO = IdentifierType(\"pno\")\n val TIN = IdentifierType(\"tin\")\n val TAX = IdentifierType(\"tax\")\n val EID = IdentifierType(\"eid\")\n val NATURAL_LOCAL = IdentifierType(\"natural_local\")\n\n val EORI = IdentifierType(\"eori\")\n val EUID = IdentifierType(\"euid\")\n val VATIN = IdentifierType(\"vatin\")\n val LEGAL_TIN = IdentifierType(\"legal_tin\")\n val EXCISE = IdentifierType(\"excise\")\n\n val ISO6523_ORG_ID = IdentifierType(\"iso6523_org_id\")\n val VLEI = IdentifierType(\"vlei\")\n val BIC = IdentifierType(\"bic\")\n val ISNI = IdentifierType(\"isni\")\n val IBAN = IdentifierType(\"iban\")\n val IIN = IdentifierType(\"iin\")\n val PAN = IdentifierType(\"pan\")\n val ISIN = IdentifierType(\"isin\")\n val MIC = IdentifierType(\"mic\")\n val UUID = IdentifierType(\"uuid\")\n val OID = IdentifierType(\"oid\")\n val ISO15459_ID = IdentifierType(\"iso15459_id\")\n val VIN = IdentifierType(\"vin\")\n val WMI = IdentifierType(\"wmi\")\n val CONTAINER_ID = IdentifierType(\"container_id\")\n\n val EMAIL = IdentifierType(\"email\")\n val PHONE = IdentifierType(\"phone\")\n val DOMAIN = IdentifierType(\"domain\")\n val URL = IdentifierType(\"url\")\n val WEBSITE = IdentifierType(\"website\")\n val ISSUER = IdentifierType(\"issuer\")\n val OIDC_ISSUER = IdentifierType(\"oidc_issuer\")\n val OID4VCI_ISSUER = IdentifierType(\"oid4vci_issuer\")\n val VERIFIER = IdentifierType(\"verifier\")\n val JWKS_URL = IdentifierType(\"jwks_url\")\n }\n\n override fun toString(): String = value\n}\n\n@Serializable\r\ndata class ApplicationLoginConfig(\r\n /** Application party id - primary key (the `service` login surface) */\r\n @SerialName(\"applicationId\")\r\n val applicationId: Uuid,\r\n\r\n /** Tenant this login config belongs to */\r\n @SerialName(\"tenantId\")\r\n val tenantId: String,\r\n\r\n /**\r\n * The authentication methods this application accepts.\r\n * Stored as a JSON-encoded TEXT column at the persistence layer.\r\n */\r\n @SerialName(\"allowedMethods\")\r\n val allowedMethods: Set = emptySet(),\r\n\r\n /**\r\n * The identifier types that may be used to log in to this application.\r\n * Stored as a JSON-encoded TEXT column at the persistence layer.\r\n */\r\n @SerialName(\"loginIdentifierTypes\")\r\n val loginIdentifierTypes: Set = emptySet(),\r\n\r\n /**\r\n * The external IdP ids permitted for federated login to this application.\r\n * Stored as a JSON-encoded TEXT column at the persistence layer.\r\n */\r\n @SerialName(\"allowedIdpIds\")\r\n val allowedIdpIds: Set = emptySet(),\r\n\r\n /** Whether identities may self-register against this application */\r\n @SerialName(\"selfRegistration\")\r\n val selfRegistration: Boolean = false,\r\n\r\n // Audit fields\r\n /** When the login config was created */\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n\r\n /** Who created the login config (party ID) */\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n\r\n /** When the login config was last updated */\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n\r\n /** Who last updated the login config (party ID) */\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n\r\n /** When the login config was soft-deleted (null if not deleted) */\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n\r\n /** Who deleted the login config (party ID) */\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null\r\n) : HasId {\r\n override val id: String get() = applicationId.toString()\r\n}\n\n @Serializable\r\n data class Federated(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n /**\n * Owner's stable identifier inside the external IDP — typically the `sub`\r\n * claim, but can be any claim agreed in [FederationProviderInput.claimMapping].\r\n */\r\n val externalSubject: String,\n val ownerPartyId: Uuid? = null,\n ) : OwnerInput()\n\ninterface Wallet {\n /** Access to persisted credential records and metadata sidecars. */\n val credentials: WalletCredentialStore\n\n /** Access to pending/resumable OID4VCI issuance sessions. */\n val issuanceSessions: WalletIssuanceSessionStore\n\n /**\n * Creates (or retrieves) a holder key scoped to [walletInstanceId], returning the\n * managed key alias. If [alias] is null a wallet-scoped alias is generated automatically.\n */\n suspend fun createHolderKey(\n walletInstanceId: String,\n alias: String? = null,\n ): IdkResult\n\n /**\n * Initiates an authorization code flow for the given issuer, returning the data\n * needed to redirect the user to the authorization endpoint.\n */\n suspend fun startAuthorizationCodeFlow(\n credentialIssuer: String,\n config: WalletConfig,\n scope: String? = null,\n ): IdkResult\n\n /**\n * Completes an authorization code flow by exchanging the authorization code for tokens.\n */\n suspend fun completeAuthorizationCodeFlow(\n start: AuthCodeStart,\n code: String,\n ): IdkResult\n\n /**\n * Exchanges a pre-authorized code (from a credential offer) for tokens.\n */\n suspend fun exchangePreAuthorizedCode(\n credentialIssuer: String,\n preAuthorizedCode: String,\n txCode: String? = null,\n config: WalletConfig? = null,\n ): IdkResult\n\n /**\n * Obtains one or more credential instances from the issuer. Synchronous issuance stores a\n * [CredentialRecord]; deferred issuance stores an [IssuanceSession] without creating a\n * credential record until polling returns an actual credential artifact.\n */\n suspend fun obtainCredential(request: ObtainCredentialRequest): IdkResult\n\n /**\n * Polls a persisted deferred issuance session and stores the resulting credential only after\n * the deferred endpoint returns the credential artifact.\n */\n suspend fun resumeDeferredIssuance(request: ResumeDeferredIssuanceRequest): IdkResult\n\n /**\n * Refreshes or reissues an existing credential record as a new credential instance.\n * The prior credential body is never overwritten.\n */\n suspend fun refreshCredential(request: RefreshCredentialRequest): IdkResult\n\n /**\n * Responds to a verifier's authorization request URI, performing a presentation exchange.\n */\n suspend fun present(\n requestUri: String,\n config: WalletConfig,\n ): IdkResult\n}\n\n@JsExportCompat\n@Serializable\ndata class Application\n @JvmOverloads\n constructor(\n val applicationId: String,\n val tenantId: String,\n val productType: ProductType,\n val name: String,\n val description: String? = null,\n val managed: Boolean = false,\n val instanceRef: String? = null,\n val createdAt: Instant? = null,\n val updatedAt: Instant? = null,\n )\n\n@JsExportCompat\r\n@Serializable\r\ndata class Tenant\r\n @JvmOverloads\r\n constructor(\r\n @SerialName(\"id\")\r\n val tenantId: String,\r\n @SerialName(\"tenantType\")\r\n val tenantType: TenantType,\r\n val name: String,\r\n val description: String? = null,\r\n /**\r\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\r\n * platform subdomain label and the dispatcher's peelable path segment.\r\n */\r\n val slug: String,\r\n /**\r\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\r\n * time (cycle detection walks up `parent_tenant_id`).\r\n */\r\n @SerialName(\"parentTenantId\")\r\n val parentTenantId: String? = null,\r\n val status: TenantStatus = TenantStatus.ACTIVE,\r\n /**\r\n * Generic \"system tenant\" flag. System tenants are excluded from default\r\n * listings and from all slug-based / parent-based resolution queries. Customer\r\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\r\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\r\n * their own system-tenant patterns. EDK does not define what a system tenant\r\n * is or what privileges it carries.\r\n */\r\n val system: Boolean = false,\r\n @SerialName(\"ownerPartyId\")\r\n val ownerPartyId: Uuid? = null,\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null,\r\n ) : HasId {\r\n override val id: String get() = tenantId\r\n }\n\n @Serializable\n @SerialName(\"stored\")\n data class Stored(\n val record: CredentialRecord,\n ) : ObtainCredentialResult()\n\n-- discriminator-tagged sealed-interface JSON via kotlinx-serialization.\n\n /** Filter by schema object ID */\r\n @SerialName(\"schemaId\")\n\n@JsExportCompat\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"HasId\", exact = true)\ninterface HasId {\n val id: String\n}" + }, + "SetIdentityApplicationBindingArgs": { + "kind": "data class", + "name": "SetIdentityApplicationBindingArgs", + "module": "service-api", + "source": "@Serializable\ndata class SetIdentityApplicationBindingArgs(\n val identityId: Uuid,\n val applicationId: Uuid,\n val capabilities: Set = emptySet(),\n val allowedMethods: Set = emptySet(),\n val specializationSubtype: String? = null,\n val status: BindingStatus = BindingStatus.ACTIVE,\n val validFrom: Instant? = null,\n val validUntil: Instant? = null,\n)\n\n@Serializable\n@JvmInline\nvalue class ApplicationCapability(\n val value: String,\n) {\n companion object {\n /** The application can authenticate identities. */\n val AUTHENTICABLE = ApplicationCapability(\"authenticable\")\n }\n\n override fun toString(): String = value\n}\n\n@Serializable\n@JvmInline\nvalue class AuthMethod(\n val value: String,\n) {\n companion object {\n /** Username/identifier plus password. */\n val PASSWORD = AuthMethod(\"password\")\n\n /** One-time passcode delivered by email. */\n val EMAIL_OTP = AuthMethod(\"email_otp\")\n\n /** Single-use magic link delivered out of band. */\n val MAGIC_LINK = AuthMethod(\"magic_link\")\n\n /** Time-based one-time password (authenticator app). */\n val TOTP = AuthMethod(\"totp\")\n\n /** Federated login via an external OIDC identity provider. */\n val FEDERATED_OIDC = AuthMethod(\"federated_oidc\")\n\n /** Wallet-based authentication (verifiable presentation). */\n val WALLET = AuthMethod(\"wallet\")\n }\n\n override fun toString(): String = value\n}\n\n@JsExportCompat\n@Serializable\nenum class BindingStatus {\n /** The binding is active and may be used to authenticate. */\n @SerialName(\"active\")\n ACTIVE,\n\n /** The binding is temporarily suspended and may not be used to authenticate. */\n @SerialName(\"suspended\")\n SUSPENDED,\n\n /** The binding is permanently revoked. */\n @SerialName(\"revoked\")\n REVOKED,\n}\n\n @Serializable\r\n data class Federated(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n /**\n * Owner's stable identifier inside the external IDP — typically the `sub`\r\n * claim, but can be any claim agreed in [FederationProviderInput.claimMapping].\r\n */\r\n val externalSubject: String,\n val ownerPartyId: Uuid? = null,\n ) : OwnerInput()\n\ninterface Wallet {\n /** Access to persisted credential records and metadata sidecars. */\n val credentials: WalletCredentialStore\n\n /** Access to pending/resumable OID4VCI issuance sessions. */\n val issuanceSessions: WalletIssuanceSessionStore\n\n /**\n * Creates (or retrieves) a holder key scoped to [walletInstanceId], returning the\n * managed key alias. If [alias] is null a wallet-scoped alias is generated automatically.\n */\n suspend fun createHolderKey(\n walletInstanceId: String,\n alias: String? = null,\n ): IdkResult\n\n /**\n * Initiates an authorization code flow for the given issuer, returning the data\n * needed to redirect the user to the authorization endpoint.\n */\n suspend fun startAuthorizationCodeFlow(\n credentialIssuer: String,\n config: WalletConfig,\n scope: String? = null,\n ): IdkResult\n\n /**\n * Completes an authorization code flow by exchanging the authorization code for tokens.\n */\n suspend fun completeAuthorizationCodeFlow(\n start: AuthCodeStart,\n code: String,\n ): IdkResult\n\n /**\n * Exchanges a pre-authorized code (from a credential offer) for tokens.\n */\n suspend fun exchangePreAuthorizedCode(\n credentialIssuer: String,\n preAuthorizedCode: String,\n txCode: String? = null,\n config: WalletConfig? = null,\n ): IdkResult\n\n /**\n * Obtains one or more credential instances from the issuer. Synchronous issuance stores a\n * [CredentialRecord]; deferred issuance stores an [IssuanceSession] without creating a\n * credential record until polling returns an actual credential artifact.\n */\n suspend fun obtainCredential(request: ObtainCredentialRequest): IdkResult\n\n /**\n * Polls a persisted deferred issuance session and stores the resulting credential only after\n * the deferred endpoint returns the credential artifact.\n */\n suspend fun resumeDeferredIssuance(request: ResumeDeferredIssuanceRequest): IdkResult\n\n /**\n * Refreshes or reissues an existing credential record as a new credential instance.\n * The prior credential body is never overwritten.\n */\n suspend fun refreshCredential(request: RefreshCredentialRequest): IdkResult\n\n /**\n * Responds to a verifier's authorization request URI, performing a presentation exchange.\n */\n suspend fun present(\n requestUri: String,\n config: WalletConfig,\n ): IdkResult\n}" + }, + "IdentityApplicationBindingResult": { + "kind": "data class", + "name": "IdentityApplicationBindingResult", + "module": "persistence-api", + "source": "@Serializable\r\ndata class IdentityApplicationBindingResult(\r\n @SerialName(\"id\")\r\n val bindingId: Uuid,\r\n\r\n @SerialName(\"tenantId\")\r\n val tenantId: String,\r\n\r\n @SerialName(\"identityId\")\r\n val identityId: Uuid,\r\n\r\n @SerialName(\"applicationId\")\r\n val applicationId: Uuid,\r\n\r\n @SerialName(\"capabilities\")\r\n val capabilities: Set = emptySet(),\r\n\r\n @SerialName(\"allowedMethods\")\r\n val allowedMethods: Set = emptySet(),\r\n\r\n @SerialName(\"specializationSubtype\")\r\n val specializationSubtype: String? = null,\r\n\r\n @SerialName(\"status\")\r\n val status: BindingStatus = BindingStatus.ACTIVE,\r\n\r\n @SerialName(\"validFrom\")\r\n val validFrom: Instant,\r\n\r\n @SerialName(\"validUntil\")\r\n val validUntil: Instant? = null,\r\n\r\n // Audit fields\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null\r\n) {\r\n companion object {\r\n fun from(binding: IdentityApplicationBinding) = IdentityApplicationBindingResult(\r\n bindingId = binding.bindingId,\r\n tenantId = binding.tenantId,\r\n identityId = binding.identityId,\r\n applicationId = binding.applicationId,\r\n capabilities = binding.capabilities,\r\n allowedMethods = binding.allowedMethods,\r\n specializationSubtype = binding.specializationSubtype,\r\n status = binding.status,\r\n validFrom = binding.validFrom,\r\n validUntil = binding.validUntil,\r\n createdAt = binding.createdAt,\r\n createdById = binding.createdById,\r\n updatedAt = binding.updatedAt,\r\n updatedById = binding.updatedById,\r\n deletedAt = binding.deletedAt,\r\n deletedById = binding.deletedById\r\n )\r\n }\r\n\r\n fun toIdentityApplicationBinding() = IdentityApplicationBinding(\r\n bindingId = bindingId,\r\n tenantId = tenantId,\r\n identityId = identityId,\r\n applicationId = applicationId,\r\n capabilities = capabilities,\r\n allowedMethods = allowedMethods,\r\n specializationSubtype = specializationSubtype,\r\n status = status,\r\n validFrom = validFrom,\r\n validUntil = validUntil,\r\n createdAt = createdAt,\r\n createdById = createdById,\r\n updatedAt = updatedAt,\r\n updatedById = updatedById,\r\n deletedAt = deletedAt,\r\n deletedById = deletedById\r\n )\r\n}\n\n@Serializable\n@JvmInline\nvalue class ApplicationCapability(\n val value: String,\n) {\n companion object {\n /** The application can authenticate identities. */\n val AUTHENTICABLE = ApplicationCapability(\"authenticable\")\n }\n\n override fun toString(): String = value\n}\n\n@Serializable\n@JvmInline\nvalue class AuthMethod(\n val value: String,\n) {\n companion object {\n /** Username/identifier plus password. */\n val PASSWORD = AuthMethod(\"password\")\n\n /** One-time passcode delivered by email. */\n val EMAIL_OTP = AuthMethod(\"email_otp\")\n\n /** Single-use magic link delivered out of band. */\n val MAGIC_LINK = AuthMethod(\"magic_link\")\n\n /** Time-based one-time password (authenticator app). */\n val TOTP = AuthMethod(\"totp\")\n\n /** Federated login via an external OIDC identity provider. */\n val FEDERATED_OIDC = AuthMethod(\"federated_oidc\")\n\n /** Wallet-based authentication (verifiable presentation). */\n val WALLET = AuthMethod(\"wallet\")\n }\n\n override fun toString(): String = value\n}\n\n@JsExportCompat\n@Serializable\nenum class BindingStatus {\n /** The binding is active and may be used to authenticate. */\n @SerialName(\"active\")\n ACTIVE,\n\n /** The binding is temporarily suspended and may not be used to authenticate. */\n @SerialName(\"suspended\")\n SUSPENDED,\n\n /** The binding is permanently revoked. */\n @SerialName(\"revoked\")\n REVOKED,\n}\n\n@Serializable\r\ndata class IdentityApplicationBinding(\r\n /** Unique identifier for this binding row */\r\n @SerialName(\"id\")\r\n val bindingId: Uuid,\r\n\r\n /** Tenant this binding belongs to */\r\n @SerialName(\"tenantId\")\r\n val tenantId: String,\r\n\r\n /** The identity that is bound to the application */\r\n @SerialName(\"identityId\")\r\n val identityId: Uuid,\r\n\r\n /** The application (party of party-type `service`) the identity is bound to */\r\n @SerialName(\"applicationId\")\r\n val applicationId: Uuid,\r\n\r\n /**\r\n * The capabilities this binding grants the identity on the application.\r\n * Stored as a JSON-encoded TEXT column at the persistence layer.\r\n */\r\n @SerialName(\"capabilities\")\r\n val capabilities: Set = emptySet(),\r\n\r\n /**\r\n * The authentication methods this binding permits the identity to use.\r\n * Stored as a JSON-encoded TEXT column at the persistence layer.\r\n */\r\n @SerialName(\"allowedMethods\")\r\n val allowedMethods: Set = emptySet(),\r\n\r\n /** The identity's role within the application, if any */\r\n @SerialName(\"specializationSubtype\")\r\n val specializationSubtype: String? = null,\r\n\r\n /** Lifecycle status of this binding */\r\n @SerialName(\"status\")\r\n val status: BindingStatus = BindingStatus.ACTIVE,\r\n\r\n /** When this binding becomes valid */\r\n @SerialName(\"validFrom\")\r\n val validFrom: Instant,\r\n\r\n /** When this binding stops being valid (null means open-ended) */\r\n @SerialName(\"validUntil\")\r\n val validUntil: Instant? = null,\r\n\r\n // Audit fields\r\n /** When the binding was created */\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n\r\n /** Who created the binding (party ID) */\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n\r\n /** When the binding was last updated */\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n\r\n /** Who last updated the binding (party ID) */\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n\r\n /** When the binding was soft-deleted (null if not deleted) */\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n\r\n /** Who deleted the binding (party ID) */\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null\r\n) : HasId {\r\n override val id: String get() = bindingId.toString()\r\n}\n\n @Serializable\r\n data class Federated(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n /**\n * Owner's stable identifier inside the external IDP — typically the `sub`\r\n * claim, but can be any claim agreed in [FederationProviderInput.claimMapping].\r\n */\r\n val externalSubject: String,\n val ownerPartyId: Uuid? = null,\n ) : OwnerInput()\n\ninterface Wallet {\n /** Access to persisted credential records and metadata sidecars. */\n val credentials: WalletCredentialStore\n\n /** Access to pending/resumable OID4VCI issuance sessions. */\n val issuanceSessions: WalletIssuanceSessionStore\n\n /**\n * Creates (or retrieves) a holder key scoped to [walletInstanceId], returning the\n * managed key alias. If [alias] is null a wallet-scoped alias is generated automatically.\n */\n suspend fun createHolderKey(\n walletInstanceId: String,\n alias: String? = null,\n ): IdkResult\n\n /**\n * Initiates an authorization code flow for the given issuer, returning the data\n * needed to redirect the user to the authorization endpoint.\n */\n suspend fun startAuthorizationCodeFlow(\n credentialIssuer: String,\n config: WalletConfig,\n scope: String? = null,\n ): IdkResult\n\n /**\n * Completes an authorization code flow by exchanging the authorization code for tokens.\n */\n suspend fun completeAuthorizationCodeFlow(\n start: AuthCodeStart,\n code: String,\n ): IdkResult\n\n /**\n * Exchanges a pre-authorized code (from a credential offer) for tokens.\n */\n suspend fun exchangePreAuthorizedCode(\n credentialIssuer: String,\n preAuthorizedCode: String,\n txCode: String? = null,\n config: WalletConfig? = null,\n ): IdkResult\n\n /**\n * Obtains one or more credential instances from the issuer. Synchronous issuance stores a\n * [CredentialRecord]; deferred issuance stores an [IssuanceSession] without creating a\n * credential record until polling returns an actual credential artifact.\n */\n suspend fun obtainCredential(request: ObtainCredentialRequest): IdkResult\n\n /**\n * Polls a persisted deferred issuance session and stores the resulting credential only after\n * the deferred endpoint returns the credential artifact.\n */\n suspend fun resumeDeferredIssuance(request: ResumeDeferredIssuanceRequest): IdkResult\n\n /**\n * Refreshes or reissues an existing credential record as a new credential instance.\n * The prior credential body is never overwritten.\n */\n suspend fun refreshCredential(request: RefreshCredentialRequest): IdkResult\n\n /**\n * Responds to a verifier's authorization request URI, performing a presentation exchange.\n */\n suspend fun present(\n requestUri: String,\n config: WalletConfig,\n ): IdkResult\n}\n\n@JsExportCompat\r\n@Serializable\r\ndata class Tenant\r\n @JvmOverloads\r\n constructor(\r\n @SerialName(\"id\")\r\n val tenantId: String,\r\n @SerialName(\"tenantType\")\r\n val tenantType: TenantType,\r\n val name: String,\r\n val description: String? = null,\r\n /**\r\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\r\n * platform subdomain label and the dispatcher's peelable path segment.\r\n */\r\n val slug: String,\r\n /**\r\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\r\n * time (cycle detection walks up `parent_tenant_id`).\r\n */\r\n @SerialName(\"parentTenantId\")\r\n val parentTenantId: String? = null,\r\n val status: TenantStatus = TenantStatus.ACTIVE,\r\n /**\r\n * Generic \"system tenant\" flag. System tenants are excluded from default\r\n * listings and from all slug-based / parent-based resolution queries. Customer\r\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\r\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\r\n * their own system-tenant patterns. EDK does not define what a system tenant\r\n * is or what privileges it carries.\r\n */\r\n val system: Boolean = false,\r\n @SerialName(\"ownerPartyId\")\r\n val ownerPartyId: Uuid? = null,\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null,\r\n ) : HasId {\r\n override val id: String get() = tenantId\r\n }\n\n @Serializable\n @SerialName(\"stored\")\n data class Stored(\n val record: CredentialRecord,\n ) : ObtainCredentialResult()\n\n-- discriminator-tagged sealed-interface JSON via kotlinx-serialization.\n\n /** Filter by schema object ID */\r\n @SerialName(\"schemaId\")\n\n@JsExportCompat\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"HasId\", exact = true)\ninterface HasId {\n val id: String\n}" + }, + "DeleteIdentityApplicationBindingArgs": { + "kind": "data class", + "name": "DeleteIdentityApplicationBindingArgs", + "module": "service-api", + "source": "@Serializable\ndata class DeleteIdentityApplicationBindingArgs(val identityId: Uuid, val applicationId: Uuid)" + }, + "DeleteIdentityApplicationBindingResult": { + "kind": "data class", + "name": "DeleteIdentityApplicationBindingResult", + "module": "service-api", + "source": "@Serializable\ndata class DeleteIdentityApplicationBindingResult(val deleted: Boolean)" + }, + "CreateGroupArgs": { + "kind": "data class", + "name": "CreateGroupArgs", + "module": "service-api", + "source": "@Serializable\ndata class CreateGroupArgs(\n val displayName: String,\n val name: String,\n val origin: PartyOrigin = PartyOrigin.MANAGED,\n val uri: String? = null,\n val jurisdiction: String? = null,\n val ownerId: Uuid? = null,\n val organizationUnitId: Uuid? = null,\n)\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }" + }, + "Group": { + "kind": "data class", + "name": "Group", + "module": "public", + "source": "@JsExportCompat\n@Serializable\n@SerialName(\"group\")\ndata class Group\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n override val partyId: Uuid,\n @SerialName(\"tenantId\")\n override val tenantId: String,\n override val origin: PartyOrigin,\n @SerialName(\"displayName\")\n override val displayName: String,\n override val uri: String? = null,\n override val jurisdiction: String? = null,\n @SerialName(\"ownerId\")\n override val ownerId: Uuid? = null,\n @SerialName(\"organizationUnitId\")\n override val organizationUnitId: Uuid? = null,\n @SerialName(\"createdAt\")\n override val createdAt: Instant,\n @SerialName(\"createdById\")\n override val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n override val updatedAt: Instant,\n @SerialName(\"updatedById\")\n override val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n override val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n override val deletedById: Uuid? = null,\n @SerialName(\"electronicAddresses\")\n override val electronicAddresses: List? = null,\n @SerialName(\"physicalAddresses\")\n override val physicalAddresses: List? = null,\n /** Group name */\n @SerialName(\"name\")\n val name: String,\n /**\n * The member parties of this group, hydrated on demand. Null means the association was\n * not requested (default); an empty list means it was requested and there are none.\n */\n @SerialName(\"members\")\n val members: List? = null,\n ) : PartyEntity {\n override val partyType: PartyType get() = PartyType.GROUP\n\n /** A group never bears specializations. */\n @SerialName(\"specializations\")\n override val specializations: List = emptyList()\n }\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class ElectronicAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Type of address (e.g. EMAIL, PHONE, URL, SOCIAL_MEDIA) */\n @SerialName(\"addressType\")\n val addressType: String,\n /** The address value */\n @SerialName(\"value\")\n val value: String,\n /** Optional label (e.g. \"Work\", \"Personal\", \"Mobile\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Whether this address has been verified */\n @SerialName(\"isVerified\")\n val isVerified: Boolean = false,\n /** When the address was verified */\n @SerialName(\"verifiedAt\")\n val verifiedAt: Instant? = null,\n /** When the address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When the address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n)\n\n@JsExportCompat\n@Serializable\ndata class PhysicalAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type/purpose of this address */\n @SerialName(\"addressType\")\n val addressType: String,\n /** User-friendly label (e.g. \"Headquarters\", \"Home\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Street address (house number, street name, unit) */\n @SerialName(\"streetAddress\")\n val streetAddress: String? = null,\n /** City/municipality name */\n @SerialName(\"city\")\n val city: String? = null,\n /** State/province/region */\n @SerialName(\"province\")\n val province: String? = null,\n /** Postal/ZIP code */\n @SerialName(\"postalCode\")\n val postalCode: String? = null,\n /** Country code (ISO 3166-1 alpha-2) */\n @SerialName(\"countryCode\")\n val countryCode: String? = null,\n /** Latitude coordinate */\n @SerialName(\"latitude\")\n val latitude: Double? = null,\n /** Longitude coordinate */\n @SerialName(\"longitude\")\n val longitude: Double? = null,\n /** When this address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When this address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n /** When the address was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the address (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the address was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the address (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the address was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the address (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n)\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNull\")\n @Serializable(with = CDDLSerializer::class)\n object Null : CDDL(\"null\", MajorType.SPECIAL, 22, arrayOf(nil)) {\n fun newNull() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n@JsExportCompat\n@Serializable\n@JsonClassDiscriminator(\"partyType\")\nsealed interface PartyEntity {\n /** Unique identifier for the party */\n val partyId: Uuid\n\n /** Tenant this party belongs to */\n val tenantId: String\n\n /** The type of party (matches the JSON class discriminator) */\n val partyType: PartyType\n\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin\n\n /** User-friendly display name */\n val displayName: String\n\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String?\n\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String?\n\n /** Reference to the owning party */\n val ownerId: Uuid?\n\n /** The single home organization unit; null means the tenant root */\n val organizationUnitId: Uuid?\n\n /** The specializations (roles) this party bears; multi-typing allows several */\n val specializations: List\n\n /** When the party was created */\n val createdAt: Instant\n\n /** Who created the party (party ID) */\n val createdById: Uuid?\n\n /** When the party was last updated */\n val updatedAt: Instant\n\n /** Who last updated the party (party ID) */\n val updatedById: Uuid?\n\n /** When the party was soft-deleted (null if not deleted) */\n val deletedAt: Instant?\n\n /** Who deleted the party (party ID) */\n val deletedById: Uuid?\n\n /**\n * The party's electronic addresses, hydrated on demand. Null means the association was not\n * requested (default); an empty list means it was requested and there are none.\n */\n val electronicAddresses: List?\n\n /**\n * The party's physical addresses, hydrated on demand. Null means the association was not\n * requested (default); an empty list means it was requested and there are none.\n */\n val physicalAddresses: List?\n}\n\n@Serializable\n@JvmInline\nvalue class PartyType(\n val value: String,\n) {\n companion object {\n /** A human individual */\n val NATURAL_PERSON = PartyType(\"natural_person\")\n\n /** Alias for [NATURAL_PERSON] */\n val PERSON = NATURAL_PERSON\n\n /** A company, institution, or other legal entity */\n val ORGANIZATION = PartyType(\"organization\")\n\n /** A software-backed service participant (endpoint, integration, automated actor) */\n val SERVICE = PartyType(\"service\")\n\n /** A software product or deployable component. */\n val SOFTWARE = PartyType(\"software\")\n\n /** A physical, digital, or logical asset that can participate in relationships. */\n val ASSET = PartyType(\"asset\")\n\n /** A unit within an organization (department, division, sub-tenant scope) */\n val ORGANIZATION_UNIT = PartyType(\"organization_unit\")\n\n /** A collection of parties grouped for addressing or authorization */\n val GROUP = PartyType(\"group\")\n\n /** An autonomous actor acting on behalf of another party */\n val AGENT = PartyType(\"agent\")\n }\n\n override fun toString(): String = value\n}\n\n@JsExportCompat\n@Serializable\ndata class PartySpecialization\n @JvmOverloads\n constructor(\n /** Human role label for this specialization (e.g. \"employee\", \"customer\", \"supplier\", \"student\") */\n @SerialName(\"subtype\")\n val subtype: String,\n /** The bound semantic Profile id; null indicates an untyped declaration */\n @SerialName(\"profileId\")\n val profileId: String? = null,\n /** The profile version the values were validated/captured against */\n @SerialName(\"profileVersion\")\n val profileVersion: String? = null,\n /**\n * The organization unit this role is scoped to; null means the role is not unit-scoped\n * (tenant-global) and falls back to the party's home organization unit.\n */\n @SerialName(\"organizationUnitId\")\n val organizationUnitId: Uuid? = null,\n /** Values for THIS specialization; populated only when licensed */\n @SerialName(\"attributes\")\n val attributes: JsonObject? = null,\n )\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }\n\n@JsExportCompat\r\n@Serializable\r\ndata class Tenant\r\n @JvmOverloads\r\n constructor(\r\n @SerialName(\"id\")\r\n val tenantId: String,\r\n @SerialName(\"tenantType\")\r\n val tenantType: TenantType,\r\n val name: String,\r\n val description: String? = null,\r\n /**\r\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\r\n * platform subdomain label and the dispatcher's peelable path segment.\r\n */\r\n val slug: String,\r\n /**\r\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\r\n * time (cycle detection walks up `parent_tenant_id`).\r\n */\r\n @SerialName(\"parentTenantId\")\r\n val parentTenantId: String? = null,\r\n val status: TenantStatus = TenantStatus.ACTIVE,\r\n /**\r\n * Generic \"system tenant\" flag. System tenants are excluded from default\r\n * listings and from all slug-based / parent-based resolution queries. Customer\r\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\r\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\r\n * their own system-tenant patterns. EDK does not define what a system tenant\r\n * is or what privileges it carries.\r\n */\r\n val system: Boolean = false,\r\n @SerialName(\"ownerPartyId\")\r\n val ownerPartyId: Uuid? = null,\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null,\r\n ) : HasId {\r\n override val id: String get() = tenantId\r\n }\n\n enum class Type {\n WORKFLOW_EXECUTION_STARTED,\n WORKFLOW_EXECUTION_COMPLETED,\n WORKFLOW_EXECUTION_FAILED,\n WORKFLOW_EXECUTION_TIMED_OUT,\n WORKFLOW_EXECUTION_CANCELED,\n WORKFLOW_EXECUTION_TERMINATED,\n WORKFLOW_EXECUTION_CONTINUED_AS_NEW,\n WORKFLOW_TASK_SCHEDULED,\n WORKFLOW_TASK_STARTED,\n WORKFLOW_TASK_COMPLETED,\n WORKFLOW_TASK_FAILED,\n WORKFLOW_TASK_TIMED_OUT,\n ACTIVITY_TASK_SCHEDULED,\n ACTIVITY_TASK_STARTED,\n ACTIVITY_TASK_COMPLETED,\n ACTIVITY_TASK_FAILED,\n ACTIVITY_TASK_TIMED_OUT,\n ACTIVITY_TASK_CANCEL_REQUESTED,\n ACTIVITY_TASK_CANCELED,\n TIMER_STARTED,\n TIMER_FIRED,\n TIMER_CANCELED,\n WORKFLOW_EXECUTION_SIGNALED,\n WORKFLOW_EXECUTION_UPDATE_ACCEPTED,\n WORKFLOW_EXECUTION_UPDATE_COMPLETED,\n WORKFLOW_EXECUTION_UPDATE_REJECTED,\n CHILD_WORKFLOW_EXECUTION_STARTED,\n CHILD_WORKFLOW_EXECUTION_COMPLETED,\n CHILD_WORKFLOW_EXECUTION_FAILED,\n MARKER_RECORDED,\n OTHER,\n }\n\n enum class State {\n CLOSED,\n OPEN,\n HALF_OPEN\n }\n\n /** Filter by schema object ID */\r\n @SerialName(\"schemaId\")\n\ninternal object CDDLSerializer : KSerializer {\n override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(\"CDDL\", PrimitiveKind.STRING)\n\n override fun serialize(\n encoder: Encoder,\n value: CDDL,\n ) {\n encoder.encodeString(value.format)\n }\n\n override fun deserialize(decoder: Decoder): CDDL = CDDL.util.fromFormat(decoder.decodeString())\n}" + }, + "AddGroupMemberArgs": { + "kind": "data class", + "name": "AddGroupMemberArgs", + "module": "service-api", + "source": "@Serializable\ndata class AddGroupMemberArgs(\n val groupId: Uuid,\n val memberId: Uuid,\n val role: String = \"member\",\n)" + }, + "GroupMembershipResult": { + "kind": "data class", + "name": "GroupMembershipResult", + "module": "persistence-api", + "source": "@Serializable\r\ndata class GroupMembershipResult(\r\n @SerialName(\"id\")\r\n val membershipId: Uuid,\r\n\r\n @SerialName(\"tenantId\")\r\n val tenantId: String,\r\n\r\n @SerialName(\"groupId\")\r\n val groupId: Uuid,\r\n\r\n @SerialName(\"memberPartyId\")\r\n val memberPartyId: Uuid,\r\n\r\n @SerialName(\"role\")\r\n val role: String,\r\n\r\n // Audit fields\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null\r\n) {\r\n companion object {\r\n fun from(membership: GroupMembership) = GroupMembershipResult(\r\n membershipId = membership.membershipId,\r\n tenantId = membership.tenantId,\r\n groupId = membership.groupId,\r\n memberPartyId = membership.memberPartyId,\r\n role = membership.role,\r\n createdAt = membership.createdAt,\r\n createdById = membership.createdById,\r\n updatedAt = membership.updatedAt,\r\n updatedById = membership.updatedById,\r\n deletedAt = membership.deletedAt,\r\n deletedById = membership.deletedById\r\n )\r\n }\r\n\r\n fun toGroupMembership() = GroupMembership(\r\n membershipId = membershipId,\r\n tenantId = tenantId,\r\n groupId = groupId,\r\n memberPartyId = memberPartyId,\r\n role = role,\r\n createdAt = createdAt,\r\n createdById = createdById,\r\n updatedAt = updatedAt,\r\n updatedById = updatedById,\r\n deletedAt = deletedAt,\r\n deletedById = deletedById\r\n )\r\n}\n\n@Serializable\r\ndata class GroupMembership(\r\n /** Unique identifier for this membership row */\r\n @SerialName(\"id\")\r\n val membershipId: Uuid,\r\n\r\n /** Tenant this membership belongs to */\r\n @SerialName(\"tenantId\")\r\n val tenantId: String,\r\n\r\n /** The group the member belongs to (party ID of the group) */\r\n @SerialName(\"groupId\")\r\n val groupId: Uuid,\r\n\r\n /** The party that is a member of the group */\r\n @SerialName(\"memberPartyId\")\r\n val memberPartyId: Uuid,\r\n\r\n /** The member's role within the group */\r\n @SerialName(\"role\")\r\n val role: String,\r\n\r\n // Audit fields\r\n /** When the membership was created */\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n\r\n /** Who created the membership (party ID) */\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n\r\n /** When the membership was last updated */\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n\r\n /** Who last updated the membership (party ID) */\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n\r\n /** When the membership was soft-deleted (null if not deleted) */\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n\r\n /** Who deleted the membership (party ID) */\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null\r\n) : HasId {\r\n override val id: String get() = membershipId.toString()\r\n}\n\n@JsExportCompat\r\n@Serializable\r\ndata class Tenant\r\n @JvmOverloads\r\n constructor(\r\n @SerialName(\"id\")\r\n val tenantId: String,\r\n @SerialName(\"tenantType\")\r\n val tenantType: TenantType,\r\n val name: String,\r\n val description: String? = null,\r\n /**\r\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\r\n * platform subdomain label and the dispatcher's peelable path segment.\r\n */\r\n val slug: String,\r\n /**\r\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\r\n * time (cycle detection walks up `parent_tenant_id`).\r\n */\r\n @SerialName(\"parentTenantId\")\r\n val parentTenantId: String? = null,\r\n val status: TenantStatus = TenantStatus.ACTIVE,\r\n /**\r\n * Generic \"system tenant\" flag. System tenants are excluded from default\r\n * listings and from all slug-based / parent-based resolution queries. Customer\r\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\r\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\r\n * their own system-tenant patterns. EDK does not define what a system tenant\r\n * is or what privileges it carries.\r\n */\r\n val system: Boolean = false,\r\n @SerialName(\"ownerPartyId\")\r\n val ownerPartyId: Uuid? = null,\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null,\r\n ) : HasId {\r\n override val id: String get() = tenantId\r\n }\n\n /** Filter by schema object ID */\r\n @SerialName(\"schemaId\")\n\n@JsExportCompat\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"HasId\", exact = true)\ninterface HasId {\n val id: String\n}" + }, + "CreateElectronicAddressArgs": { + "kind": "data class", + "name": "CreateElectronicAddressArgs", + "module": "service-api", + "source": "@Serializable\ndata class CreateElectronicAddressArgs(\n val partyId: Uuid,\n val addressType: String,\n val value: String,\n val label: String? = null,\n val isPrimary: Boolean = false,\n val isVerified: Boolean = false,\n val verifiedAt: Instant? = null,\n val validFrom: Instant? = null,\n val validUntil: Instant? = null,\n val identifierId: Uuid? = null,\n)" + }, + "ElectronicAddress": { + "kind": "data class", + "name": "ElectronicAddress", + "module": "public", + "source": "@JsExportCompat\n@Serializable\ndata class ElectronicAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Type of address (e.g. EMAIL, PHONE, URL, SOCIAL_MEDIA) */\n @SerialName(\"addressType\")\n val addressType: String,\n /** The address value */\n @SerialName(\"value\")\n val value: String,\n /** Optional label (e.g. \"Work\", \"Personal\", \"Mobile\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Whether this address has been verified */\n @SerialName(\"isVerified\")\n val isVerified: Boolean = false,\n /** When the address was verified */\n @SerialName(\"verifiedAt\")\n val verifiedAt: Instant? = null,\n /** When the address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When the address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n)\n\n@JsExportCompat\r\n@Serializable\r\ndata class Tenant\r\n @JvmOverloads\r\n constructor(\r\n @SerialName(\"id\")\r\n val tenantId: String,\r\n @SerialName(\"tenantType\")\r\n val tenantType: TenantType,\r\n val name: String,\r\n val description: String? = null,\r\n /**\r\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\r\n * platform subdomain label and the dispatcher's peelable path segment.\r\n */\r\n val slug: String,\r\n /**\r\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\r\n * time (cycle detection walks up `parent_tenant_id`).\r\n */\r\n @SerialName(\"parentTenantId\")\r\n val parentTenantId: String? = null,\r\n val status: TenantStatus = TenantStatus.ACTIVE,\r\n /**\r\n * Generic \"system tenant\" flag. System tenants are excluded from default\r\n * listings and from all slug-based / parent-based resolution queries. Customer\r\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\r\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\r\n * their own system-tenant patterns. EDK does not define what a system tenant\r\n * is or what privileges it carries.\r\n */\r\n val system: Boolean = false,\r\n @SerialName(\"ownerPartyId\")\r\n val ownerPartyId: Uuid? = null,\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null,\r\n ) : HasId {\r\n override val id: String get() = tenantId\r\n }\n\n enum class Type {\n WORKFLOW_EXECUTION_STARTED,\n WORKFLOW_EXECUTION_COMPLETED,\n WORKFLOW_EXECUTION_FAILED,\n WORKFLOW_EXECUTION_TIMED_OUT,\n WORKFLOW_EXECUTION_CANCELED,\n WORKFLOW_EXECUTION_TERMINATED,\n WORKFLOW_EXECUTION_CONTINUED_AS_NEW,\n WORKFLOW_TASK_SCHEDULED,\n WORKFLOW_TASK_STARTED,\n WORKFLOW_TASK_COMPLETED,\n WORKFLOW_TASK_FAILED,\n WORKFLOW_TASK_TIMED_OUT,\n ACTIVITY_TASK_SCHEDULED,\n ACTIVITY_TASK_STARTED,\n ACTIVITY_TASK_COMPLETED,\n ACTIVITY_TASK_FAILED,\n ACTIVITY_TASK_TIMED_OUT,\n ACTIVITY_TASK_CANCEL_REQUESTED,\n ACTIVITY_TASK_CANCELED,\n TIMER_STARTED,\n TIMER_FIRED,\n TIMER_CANCELED,\n WORKFLOW_EXECUTION_SIGNALED,\n WORKFLOW_EXECUTION_UPDATE_ACCEPTED,\n WORKFLOW_EXECUTION_UPDATE_COMPLETED,\n WORKFLOW_EXECUTION_UPDATE_REJECTED,\n CHILD_WORKFLOW_EXECUTION_STARTED,\n CHILD_WORKFLOW_EXECUTION_COMPLETED,\n CHILD_WORKFLOW_EXECUTION_FAILED,\n MARKER_RECORDED,\n OTHER,\n }\n\n@Serializable\n@JvmInline\nvalue class TenantType(\n val value: String,\n) {\n companion object {\n /** Platform/system tenant (for multi-tenant SaaS platforms) */\n val PLATFORM = TenantType(\"platform\")\n\n /** Enterprise tenant (business, company) */\n val ENTERPRISE = TenantType(\"enterprise\")\n\n /** Partner tenant (external partner organization) */\n val PARTNER = TenantType(\"partner\")\n\n /** Sandbox tenant (for testing and development) */\n val SANDBOX = TenantType(\"sandbox\")\n }\n\n override fun toString(): String = value\n}\n\n @Serializable\n @SerialName(\"lowercase\")\n data object Lowercase : ClaimTransformation\n\n@JsExportCompat\r\n@Serializable\r\nenum class TenantStatus {\r\n ACTIVE,\r\n SUSPENDED,\r\n PENDING_VERIFICATION,\r\n}\n\n data class Generic(\n val exception: Throwable? = null,\n override val message: String = \"Consent error\",\n ) : ConsentError\n\n @Serializable\n data class System(\n override val id: String,\n val commandId: String,\n /** Mapping expression (engine-interpreted) producing the command's input from prior outputs. */\n val inputExpression: String,\n val next: String? = null,\n ) : WorkflowTask()\n\n@JsExportCompat\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"HasId\", exact = true)\ninterface HasId {\n val id: String\n}" + }, + "ListElectronicAddressesArgs": { + "kind": "data class", + "name": "ListElectronicAddressesArgs", + "module": "service-api", + "source": "@Serializable\ndata class ListElectronicAddressesArgs(val partyId: Uuid)" + }, + "GetPartyArgs": { + "kind": "data class", + "name": "GetPartyArgs", + "module": "service-api", + "source": "@Serializable\ndata class GetPartyArgs(val id: Uuid, val include: Set = emptySet())" + }, + "PartyEntity": { + "kind": "sealed interface", + "name": "PartyEntity", + "module": "public", + "source": "@JsExportCompat\n@Serializable\n@JsonClassDiscriminator(\"partyType\")\nsealed interface PartyEntity {\n /** Unique identifier for the party */\n val partyId: Uuid\n\n /** Tenant this party belongs to */\n val tenantId: String\n\n /** The type of party (matches the JSON class discriminator) */\n val partyType: PartyType\n\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin\n\n /** User-friendly display name */\n val displayName: String\n\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String?\n\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String?\n\n /** Reference to the owning party */\n val ownerId: Uuid?\n\n /** The single home organization unit; null means the tenant root */\n val organizationUnitId: Uuid?\n\n /** The specializations (roles) this party bears; multi-typing allows several */\n val specializations: List\n\n /** When the party was created */\n val createdAt: Instant\n\n /** Who created the party (party ID) */\n val createdById: Uuid?\n\n /** When the party was last updated */\n val updatedAt: Instant\n\n /** Who last updated the party (party ID) */\n val updatedById: Uuid?\n\n /** When the party was soft-deleted (null if not deleted) */\n val deletedAt: Instant?\n\n /** Who deleted the party (party ID) */\n val deletedById: Uuid?\n\n /**\n * The party's electronic addresses, hydrated on demand. Null means the association was not\n * requested (default); an empty list means it was requested and there are none.\n */\n val electronicAddresses: List?\n\n /**\n * The party's physical addresses, hydrated on demand. Null means the association was not\n * requested (default); an empty list means it was requested and there are none.\n */\n val physicalAddresses: List?\n}\n\n@JsExportCompat\r\n@Serializable\r\ndata class Tenant\r\n @JvmOverloads\r\n constructor(\r\n @SerialName(\"id\")\r\n val tenantId: String,\r\n @SerialName(\"tenantType\")\r\n val tenantType: TenantType,\r\n val name: String,\r\n val description: String? = null,\r\n /**\r\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\r\n * platform subdomain label and the dispatcher's peelable path segment.\r\n */\r\n val slug: String,\r\n /**\r\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\r\n * time (cycle detection walks up `parent_tenant_id`).\r\n */\r\n @SerialName(\"parentTenantId\")\r\n val parentTenantId: String? = null,\r\n val status: TenantStatus = TenantStatus.ACTIVE,\r\n /**\r\n * Generic \"system tenant\" flag. System tenants are excluded from default\r\n * listings and from all slug-based / parent-based resolution queries. Customer\r\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\r\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\r\n * their own system-tenant patterns. EDK does not define what a system tenant\r\n * is or what privileges it carries.\r\n */\r\n val system: Boolean = false,\r\n @SerialName(\"ownerPartyId\")\r\n val ownerPartyId: Uuid? = null,\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null,\r\n ) : HasId {\r\n override val id: String get() = tenantId\r\n }\n\n-- discriminator-tagged sealed-interface JSON via kotlinx-serialization.\n\n@Serializable\n@JvmInline\nvalue class PartyType(\n val value: String,\n) {\n companion object {\n /** A human individual */\n val NATURAL_PERSON = PartyType(\"natural_person\")\n\n /** Alias for [NATURAL_PERSON] */\n val PERSON = NATURAL_PERSON\n\n /** A company, institution, or other legal entity */\n val ORGANIZATION = PartyType(\"organization\")\n\n /** A software-backed service participant (endpoint, integration, automated actor) */\n val SERVICE = PartyType(\"service\")\n\n /** A software product or deployable component. */\n val SOFTWARE = PartyType(\"software\")\n\n /** A physical, digital, or logical asset that can participate in relationships. */\n val ASSET = PartyType(\"asset\")\n\n /** A unit within an organization (department, division, sub-tenant scope) */\n val ORGANIZATION_UNIT = PartyType(\"organization_unit\")\n\n /** A collection of parties grouped for addressing or authorization */\n val GROUP = PartyType(\"group\")\n\n /** An autonomous actor acting on behalf of another party */\n val AGENT = PartyType(\"agent\")\n }\n\n override fun toString(): String = value\n}\n\n@JsExportCompat\n@Serializable\nenum class Origin {\n /** Resource was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Resource was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n ;\n\n companion object {\n fun fromValue(value: String): Origin =\n entries.firstOrNull { it.name.equals(value, ignoreCase = true) }\n ?: throw IllegalArgumentException(\"Unknown origin: $value\")\n }\n}\n\n@JsExportCompat\n@Serializable\nenum class PartyOrigin {\n /** Party was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Party was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n}\n\n@JsExportCompat\n@Serializable\ndata class PartySpecialization\n @JvmOverloads\n constructor(\n /** Human role label for this specialization (e.g. \"employee\", \"customer\", \"supplier\", \"student\") */\n @SerialName(\"subtype\")\n val subtype: String,\n /** The bound semantic Profile id; null indicates an untyped declaration */\n @SerialName(\"profileId\")\n val profileId: String? = null,\n /** The profile version the values were validated/captured against */\n @SerialName(\"profileVersion\")\n val profileVersion: String? = null,\n /**\n * The organization unit this role is scoped to; null means the role is not unit-scoped\n * (tenant-global) and falls back to the party's home organization unit.\n */\n @SerialName(\"organizationUnitId\")\n val organizationUnitId: Uuid? = null,\n /** Values for THIS specialization; populated only when licensed */\n @SerialName(\"attributes\")\n val attributes: JsonObject? = null,\n )\n\n /** Filter by schema object ID */\r\n @SerialName(\"schemaId\")\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNull\")\n @Serializable(with = CDDLSerializer::class)\n object Null : CDDL(\"null\", MajorType.SPECIAL, 22, arrayOf(nil)) {\n fun newNull() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n@JsExportCompat\n@Serializable\ndata class ElectronicAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Type of address (e.g. EMAIL, PHONE, URL, SOCIAL_MEDIA) */\n @SerialName(\"addressType\")\n val addressType: String,\n /** The address value */\n @SerialName(\"value\")\n val value: String,\n /** Optional label (e.g. \"Work\", \"Personal\", \"Mobile\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Whether this address has been verified */\n @SerialName(\"isVerified\")\n val isVerified: Boolean = false,\n /** When the address was verified */\n @SerialName(\"verifiedAt\")\n val verifiedAt: Instant? = null,\n /** When the address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When the address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n)\n\n@JsExportCompat\n@Serializable\ndata class PhysicalAddress(\n /** Unique identifier for this address */\n @SerialName(\"id\")\n val id: Uuid,\n /** The party this address belongs to */\n @SerialName(\"partyId\")\n val partyId: Uuid,\n /** Optional identity identifier this address is tied to */\n @SerialName(\"identifierId\")\n val identifierId: Uuid? = null,\n /** Tenant this address belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type/purpose of this address */\n @SerialName(\"addressType\")\n val addressType: String,\n /** User-friendly label (e.g. \"Headquarters\", \"Home\") */\n @SerialName(\"label\")\n val label: String? = null,\n /** Whether this is the primary address of its type */\n @SerialName(\"isPrimary\")\n val isPrimary: Boolean = false,\n /** Street address (house number, street name, unit) */\n @SerialName(\"streetAddress\")\n val streetAddress: String? = null,\n /** City/municipality name */\n @SerialName(\"city\")\n val city: String? = null,\n /** State/province/region */\n @SerialName(\"province\")\n val province: String? = null,\n /** Postal/ZIP code */\n @SerialName(\"postalCode\")\n val postalCode: String? = null,\n /** Country code (ISO 3166-1 alpha-2) */\n @SerialName(\"countryCode\")\n val countryCode: String? = null,\n /** Latitude coordinate */\n @SerialName(\"latitude\")\n val latitude: Double? = null,\n /** Longitude coordinate */\n @SerialName(\"longitude\")\n val longitude: Double? = null,\n /** When this address became valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant,\n /** When this address expired (null = current) */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n /** When the address was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the address (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the address was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the address (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the address was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the address (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n)\n\n@Serializable\n@JvmInline\nvalue class TenantType(\n val value: String,\n) {\n companion object {\n /** Platform/system tenant (for multi-tenant SaaS platforms) */\n val PLATFORM = TenantType(\"platform\")\n\n /** Enterprise tenant (business, company) */\n val ENTERPRISE = TenantType(\"enterprise\")\n\n /** Partner tenant (external partner organization) */\n val PARTNER = TenantType(\"partner\")\n\n /** Sandbox tenant (for testing and development) */\n val SANDBOX = TenantType(\"sandbox\")\n }\n\n override fun toString(): String = value\n}\n\n @Serializable\n @SerialName(\"lowercase\")\n data object Lowercase : ClaimTransformation\n\n@JsExportCompat\r\n@Serializable\r\nenum class TenantStatus {\r\n ACTIVE,\r\n SUSPENDED,\r\n PENDING_VERIFICATION,\r\n}" + }, + "CreateRelationshipArgs": { + "kind": "data class", + "name": "CreateRelationshipArgs", + "module": "service-api", + "source": "@Serializable\ndata class CreateRelationshipArgs(\n val leftId: Uuid,\n val rightId: Uuid,\n val relationshipType: String,\n val status: String? = null,\n val validFrom: Instant? = null,\n val validUntil: Instant? = null,\n)" + }, + "PartyRelationshipResult": { + "kind": "data class", + "name": "PartyRelationshipResult", + "module": "persistence-api", + "source": "@Serializable\ndata class PartyRelationshipResult(\n // Core fields\n /** Unique identifier for this relationship */\n @SerialName(\"id\")\n val id: Uuid,\n\n /** Tenant this relationship belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n\n /** The \"left\" party in the relationship */\n @SerialName(\"leftId\")\n val leftPartyId: Uuid,\n\n /** The \"right\" party in the relationship */\n @SerialName(\"rightId\")\n val rightPartyId: Uuid,\n\n /** Type of relationship */\n @SerialName(\"relationshipType\")\n val relationshipType: String,\n\n /** Status of the relationship */\n @SerialName(\"status\")\n val status: String,\n\n /** When the relationship becomes valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant? = null,\n\n /** When the relationship expires */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n\n /** When the relationship was verified */\n @SerialName(\"verifiedAt\")\n val verifiedAt: Instant? = null,\n\n /** Who verified the relationship (party ID) */\n @SerialName(\"verifiedById\")\n val verifiedById: Uuid? = null,\n\n // Audit fields\n /** When the record was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n /** Who created the record (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n\n /** When the record was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n\n /** Who last updated the record (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n\n // Populated associations (based on FetchOptions)\n /**\n * The left party details.\n * Populated when [PartyRelationshipFetchOptions.includeLeftParty] is true.\n */\n @SerialName(\"leftParty\")\n val leftParty: Party? = null,\n\n /**\n * The right party details.\n * Populated when [PartyRelationshipFetchOptions.includeRightParty] is true.\n */\n @SerialName(\"rightParty\")\n val rightParty: Party? = null,\n\n /**\n * The relationship type definition.\n * Populated when [PartyRelationshipFetchOptions.includeRelationshipType] is true.\n */\n @SerialName(\"relationshipTypeDefinition\")\n val relationshipTypeDefinition: RelationshipType? = null,\n\n /**\n * Employment extension data.\n * Populated when [PartyRelationshipFetchOptions.includeEmploymentExtension] is true.\n */\n @SerialName(\"employmentExtension\")\n val employmentExtension: RelationshipEmployment? = null,\n\n /**\n * Membership extension data.\n * Populated when [PartyRelationshipFetchOptions.includeMembershipExtension] is true.\n */\n @SerialName(\"membershipExtension\")\n val membershipExtension: RelationshipMembership? = null,\n\n /**\n * Guardianship extension data.\n * Populated when [PartyRelationshipFetchOptions.includeGuardianshipExtension] is true.\n */\n @SerialName(\"guardianshipExtension\")\n val guardianshipExtension: RelationshipGuardianship? = null,\n\n /**\n * Delegation extension data.\n * Populated when [PartyRelationshipFetchOptions.includeDelegationExtension] is true.\n */\n @SerialName(\"delegationExtension\")\n val delegationExtension: RelationshipDelegation? = null\n) {\n /** Check if the relationship has been verified */\n val isVerified: Boolean get() = verifiedAt != null\n\n companion object {\n /**\n * Create a PartyRelationshipResult from a PartyRelationship entity.\n */\n fun from(\n relationship: PartyRelationship,\n leftParty: Party? = null,\n rightParty: Party? = null,\n relationshipTypeDefinition: RelationshipType? = null,\n employmentExtension: RelationshipEmployment? = null,\n membershipExtension: RelationshipMembership? = null,\n guardianshipExtension: RelationshipGuardianship? = null,\n delegationExtension: RelationshipDelegation? = null\n ) = PartyRelationshipResult(\n id = relationship.id,\n tenantId = relationship.tenantId,\n leftPartyId = relationship.leftPartyId,\n rightPartyId = relationship.rightPartyId,\n relationshipType = relationship.relationshipType,\n status = relationship.status,\n validFrom = relationship.validFrom,\n validUntil = relationship.validUntil,\n verifiedAt = relationship.verifiedAt,\n verifiedById = relationship.verifiedById,\n createdAt = relationship.createdAt,\n createdById = relationship.createdById,\n updatedAt = relationship.updatedAt,\n updatedById = relationship.updatedById,\n leftParty = leftParty,\n rightParty = rightParty,\n relationshipTypeDefinition = relationshipTypeDefinition,\n employmentExtension = employmentExtension,\n membershipExtension = membershipExtension,\n guardianshipExtension = guardianshipExtension,\n delegationExtension = delegationExtension\n )\n }\n\n /** Convert back to the core PartyRelationship entity (without associations) */\n fun toPartyRelationship() = PartyRelationship(\n id = id,\n tenantId = tenantId,\n leftPartyId = leftPartyId,\n rightPartyId = rightPartyId,\n relationshipType = relationshipType,\n status = status,\n validFrom = validFrom,\n validUntil = validUntil,\n verifiedAt = verifiedAt,\n verifiedById = verifiedById,\n createdAt = createdAt,\n createdById = createdById,\n updatedAt = updatedAt,\n updatedById = updatedById\n )\n}\n\n@JsExportCompat\r\n@Serializable\r\ndata class Tenant\r\n @JvmOverloads\r\n constructor(\r\n @SerialName(\"id\")\r\n val tenantId: String,\r\n @SerialName(\"tenantType\")\r\n val tenantType: TenantType,\r\n val name: String,\r\n val description: String? = null,\r\n /**\r\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\r\n * platform subdomain label and the dispatcher's peelable path segment.\r\n */\r\n val slug: String,\r\n /**\r\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\r\n * time (cycle detection walks up `parent_tenant_id`).\r\n */\r\n @SerialName(\"parentTenantId\")\r\n val parentTenantId: String? = null,\r\n val status: TenantStatus = TenantStatus.ACTIVE,\r\n /**\r\n * Generic \"system tenant\" flag. System tenants are excluded from default\r\n * listings and from all slug-based / parent-based resolution queries. Customer\r\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\r\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\r\n * their own system-tenant patterns. EDK does not define what a system tenant\r\n * is or what privileges it carries.\r\n */\r\n val system: Boolean = false,\r\n @SerialName(\"ownerPartyId\")\r\n val ownerPartyId: Uuid? = null,\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null,\r\n ) : HasId {\r\n override val id: String get() = tenantId\r\n }\n\n enum class Type {\n WORKFLOW_EXECUTION_STARTED,\n WORKFLOW_EXECUTION_COMPLETED,\n WORKFLOW_EXECUTION_FAILED,\n WORKFLOW_EXECUTION_TIMED_OUT,\n WORKFLOW_EXECUTION_CANCELED,\n WORKFLOW_EXECUTION_TERMINATED,\n WORKFLOW_EXECUTION_CONTINUED_AS_NEW,\n WORKFLOW_TASK_SCHEDULED,\n WORKFLOW_TASK_STARTED,\n WORKFLOW_TASK_COMPLETED,\n WORKFLOW_TASK_FAILED,\n WORKFLOW_TASK_TIMED_OUT,\n ACTIVITY_TASK_SCHEDULED,\n ACTIVITY_TASK_STARTED,\n ACTIVITY_TASK_COMPLETED,\n ACTIVITY_TASK_FAILED,\n ACTIVITY_TASK_TIMED_OUT,\n ACTIVITY_TASK_CANCEL_REQUESTED,\n ACTIVITY_TASK_CANCELED,\n TIMER_STARTED,\n TIMER_FIRED,\n TIMER_CANCELED,\n WORKFLOW_EXECUTION_SIGNALED,\n WORKFLOW_EXECUTION_UPDATE_ACCEPTED,\n WORKFLOW_EXECUTION_UPDATE_COMPLETED,\n WORKFLOW_EXECUTION_UPDATE_REJECTED,\n CHILD_WORKFLOW_EXECUTION_STARTED,\n CHILD_WORKFLOW_EXECUTION_COMPLETED,\n CHILD_WORKFLOW_EXECUTION_FAILED,\n MARKER_RECORDED,\n OTHER,\n }\n\n data class Status(\n val response: HttpResponse\n ) : RetryTrigger() {\n override fun toString(): String = \"HTTP ${response.status.value}\"\n }\n\n /** Filter by schema object ID */\r\n @SerialName(\"schemaId\")\n\n@Serializable\ndata class PartyRelationshipFetchOptions(\n /** Include the left party details */\n @SerialName(\"includeLeftParty\")\n val includeLeftParty: Boolean = false,\n\n /** Include the right party details */\n @SerialName(\"includeRightParty\")\n val includeRightParty: Boolean = false,\n\n /** Include the relationship type definition */\n @SerialName(\"includeRelationshipType\")\n val includeRelationshipType: Boolean = false,\n\n /** Include employment extension data (if applicable) */\n @SerialName(\"includeEmploymentExtension\")\n val includeEmploymentExtension: Boolean = false,\n\n /** Include membership extension data (if applicable) */\n @SerialName(\"includeMembershipExtension\")\n val includeMembershipExtension: Boolean = false,\n\n /** Include guardianship extension data (if applicable) */\n @SerialName(\"includeGuardianshipExtension\")\n val includeGuardianshipExtension: Boolean = false,\n\n /** Include delegation extension data (if applicable) */\n @SerialName(\"includeDelegationExtension\")\n val includeDelegationExtension: Boolean = false\n) {\n companion object {\n /** Load only core relationship data (default) */\n val MINIMAL = PartyRelationshipFetchOptions()\n\n /** Load relationship with both parties */\n val WITH_PARTIES = PartyRelationshipFetchOptions(\n includeLeftParty = true,\n includeRightParty = true\n )\n\n /** Load relationship with all extensions */\n val WITH_EXTENSIONS = PartyRelationshipFetchOptions(\n includeEmploymentExtension = true,\n includeMembershipExtension = true,\n includeGuardianshipExtension = true,\n includeDelegationExtension = true\n )\n\n /** Load everything (all associations and extensions) */\n val FULL = PartyRelationshipFetchOptions(\n includeLeftParty = true,\n includeRightParty = true,\n includeRelationshipType = true,\n includeEmploymentExtension = true,\n includeMembershipExtension = true,\n includeGuardianshipExtension = true,\n includeDelegationExtension = true\n )\n }\n\n /** Builder method to include left party */\n fun withLeftParty() = copy(includeLeftParty = true)\n\n /** Builder method to include right party */\n fun withRightParty() = copy(includeRightParty = true)\n\n /** Builder method to include both parties */\n fun withParties() = copy(includeLeftParty = true, includeRightParty = true)\n\n /** Builder method to include relationship type */\n fun withRelationshipType() = copy(includeRelationshipType = true)\n\n /** Builder method to include all extensions */\n fun withAllExtensions() = copy(\n includeEmploymentExtension = true,\n includeMembershipExtension = true,\n includeGuardianshipExtension = true,\n includeDelegationExtension = true\n )\n}\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }\n\n@Serializable\ndata class RelationshipType(\n /** The relationship type identifier (e.g., \"EMPLOYMENT\", \"MEMBERSHIP\") */\n @SerialName(\"type\")\n val type: String,\n\n /** I18n key for describing left→right direction (e.g., \"employee_of\") */\n @SerialName(\"leftToRightI18nKey\")\n val leftToRightI18nKey: String,\n\n /** I18n key for describing right→left direction (e.g., \"employs\") */\n @SerialName(\"rightToLeftI18nKey\")\n val rightToLeftI18nKey: String,\n\n /** Optional description i18n key */\n @SerialName(\"descriptionI18nKey\")\n val descriptionI18nKey: String? = null\n)\n\n@Serializable\ndata class RelationshipEmployment(\n /** The relationship this extends (references party_relationship.id) */\n @SerialName(\"relationshipId\")\n val relationshipId: Uuid,\n\n /** Job title of the employee */\n @SerialName(\"jobTitle\")\n val jobTitle: String? = null,\n\n /** Department within the organization */\n @SerialName(\"department\")\n val department: String? = null,\n\n /** Employee number/ID */\n @SerialName(\"employeeNumber\")\n val employeeNumber: String? = null,\n\n /** Cost center for accounting purposes */\n @SerialName(\"costCenter\")\n val costCenter: String? = null,\n\n /** When the record was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n /** When the record was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant\n)\n\n@Serializable\ndata class RelationshipMembership(\n /** The relationship this extends (references party_relationship.id) */\n @SerialName(\"relationshipId\")\n val relationshipId: Uuid,\n\n /** Role within the membership (e.g., \"ADMIN\", \"MEMBER\", \"OBSERVER\") */\n @SerialName(\"memberRole\")\n val memberRole: String? = null,\n\n /** When the membership started */\n @SerialName(\"memberSince\")\n val memberSince: Instant? = null,\n\n /** Membership tier (e.g., \"GOLD\", \"SILVER\", \"BRONZE\") */\n @SerialName(\"tier\")\n val tier: String? = null,\n\n /** When the record was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n /** When the record was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant\n)\n\n@Serializable\ndata class RelationshipGuardianship(\n /** The relationship this extends (references party_relationship.id) */\n @SerialName(\"relationshipId\")\n val relationshipId: Uuid,\n\n /** Type of guardianship (e.g., \"LEGAL\", \"TEMPORARY\", \"MEDICAL\") */\n @SerialName(\"guardianshipType\")\n val guardianshipType: String? = null,\n\n /** Reference to the court order establishing guardianship */\n @SerialName(\"courtOrderReference\")\n val courtOrderReference: String? = null,\n\n /** Jurisdiction where guardianship was established */\n @SerialName(\"jurisdiction\")\n val jurisdiction: String? = null,\n\n /** When guardianship was granted */\n @SerialName(\"grantedAt\")\n val grantedAt: Instant? = null,\n\n /** When guardianship expires */\n @SerialName(\"expiresAt\")\n val expiresAt: Instant? = null,\n\n /** When the record was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n /** When the record was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant\n)\n\n@Serializable\ndata class RelationshipDelegation(\n /** The relationship this extends (references party_relationship.id) */\n @SerialName(\"relationshipId\")\n val relationshipId: Uuid,\n\n /** Type of delegation (e.g., \"POWER_OF_ATTORNEY\", \"PROXY\", \"MANDATE\") */\n @SerialName(\"delegationType\")\n val delegationType: String? = null,\n\n /** Scope of the delegation (what actions are permitted) */\n @SerialName(\"scope\")\n val scope: String? = null,\n\n /** Reference to the legal document establishing delegation */\n @SerialName(\"legalDocumentRef\")\n val legalDocumentRef: String? = null,\n\n /** Whether witness signature is required for actions */\n @SerialName(\"requiresWitness\")\n val requiresWitness: Boolean? = null,\n\n /** When the record was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n /** When the record was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant\n)\n\n@Serializable\ndata class PartyRelationship(\n /** Unique identifier for this relationship */\n @SerialName(\"id\")\n val id: Uuid,\n\n /** Tenant this relationship belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n\n /** The \"left\" party in the relationship (e.g., employee) */\n @SerialName(\"leftPartyId\")\n val leftPartyId: Uuid,\n\n /** The \"right\" party in the relationship (e.g., employer) */\n @SerialName(\"rightPartyId\")\n val rightPartyId: Uuid,\n\n /** Type of relationship (references relationship_type.type) */\n @SerialName(\"relationshipType\")\n val relationshipType: String,\n\n /** Status of the relationship */\n @SerialName(\"status\")\n val status: String = RelationshipStatus.ACTIVE,\n\n /** When the relationship becomes valid */\n @SerialName(\"validFrom\")\n val validFrom: Instant? = null,\n\n /** When the relationship expires */\n @SerialName(\"validUntil\")\n val validUntil: Instant? = null,\n\n /** When the relationship was verified */\n @SerialName(\"verifiedAt\")\n val verifiedAt: Instant? = null,\n\n /** Who verified the relationship (party ID) */\n @SerialName(\"verifiedById\")\n val verifiedById: Uuid? = null,\n\n // Audit fields\n /** When the record was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n\n /** Who created the record (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n\n /** When the record was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n\n /** Who last updated the record (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null\n) {\n /** Check if the relationship is currently active */\n fun isActive(at: Instant): Boolean {\n if (status != RelationshipStatus.ACTIVE) return false\n val afterStart = validFrom?.let { at >= it } ?: true\n val beforeEnd = validUntil?.let { at <= it } ?: true\n return afterStart && beforeEnd\n }\n\n /** Check if the relationship has been verified */\n val isVerified: Boolean get() = verifiedAt != null\n}\n\n@Serializable\n@JvmInline\nvalue class TenantType(\n val value: String,\n) {\n companion object {\n /** Platform/system tenant (for multi-tenant SaaS platforms) */\n val PLATFORM = TenantType(\"platform\")\n\n /** Enterprise tenant (business, company) */\n val ENTERPRISE = TenantType(\"enterprise\")\n\n /** Partner tenant (external partner organization) */\n val PARTNER = TenantType(\"partner\")\n\n /** Sandbox tenant (for testing and development) */\n val SANDBOX = TenantType(\"sandbox\")\n }\n\n override fun toString(): String = value\n}" + }, + "ListRelationshipsByPartyArgs": { + "kind": "data class", + "name": "ListRelationshipsByPartyArgs", + "module": "service-api", + "source": "@Serializable\ndata class ListRelationshipsByPartyArgs(val partyId: Uuid)" + }, + "CreateTenantIdpArgs": { + "kind": "data class", + "name": "CreateTenantIdpArgs", + "module": "public", + "source": "@JsExportCompat\r\n@Serializable\r\ndata class CreateTenantIdpArgs(\r\n val displayName: String,\r\n val issuer: String,\r\n val clientId: String,\r\n val idpId: String? = null,\r\n val clientSecret: String? = null,\r\n val clientSecretRef: String? = null,\r\n val scopes: List = listOf(\"openid\", \"profile\", \"email\"),\r\n val claimsMapping: TenantIdpClaimsMapping = TenantIdpClaimsMapping(),\r\n val enabled: Boolean = false,\r\n)\n\n@Serializable\r\ndata class TenantIdpClaimsMapping(\r\n val subject: String = \"sub\",\r\n val email: String = \"email\",\r\n val displayName: String = \"name\",\r\n)" + }, + "TenantIdpRecord": { + "kind": "data class", + "name": "TenantIdpRecord", + "module": "public", + "source": "@Serializable\r\ndata class TenantIdpRecord(\r\n val idpId: String,\r\n val displayName: String,\r\n val issuer: String,\r\n val clientId: String,\r\n val clientSecretRef: String? = null,\r\n val scopes: List = listOf(\"openid\", \"profile\", \"email\"),\r\n val claimsMapping: TenantIdpClaimsMapping = TenantIdpClaimsMapping(),\r\n val enabled: Boolean = false,\r\n val createdAt: Instant? = null,\r\n val updatedAt: Instant? = null,\r\n)\n\n@Serializable\r\ndata class TenantIdpClaimsMapping(\r\n val subject: String = \"sub\",\r\n val email: String = \"email\",\r\n val displayName: String = \"name\",\r\n)" + }, + "RegisterTenantArgs": { + "kind": "data class", + "name": "RegisterTenantArgs", + "module": "public", + "source": "@JsExportCompat\r\n@Serializable\r\ndata class RegisterTenantArgs(\r\n val tenantType: TenantType,\r\n val name: String,\r\n val description: String? = null,\r\n /** URL-safe lowercase slug. Doubles as platform-subdomain label and path segment. */\r\n val slug: String,\r\n /** Parent tenant id; null = root tenant. */\r\n val parentTenantId: String? = null,\r\n /** Optional Party owner. When null, no Party is linked at registration. */\r\n val ownerPartyId: Uuid? = null,\r\n /**\r\n * When true (default), auto-create the platform subdomain row `.` in\r\n * `tenant_domain`.\r\n */\r\n val initialPlatformSubdomain: Boolean = true,\r\n /**\r\n * When true (default), provision a default AS instance (slug `default`) for this\r\n * tenant. When false, the tenant has no hosted AS — only viable with a\r\n * [OwnerInput.Federated] owner whose external IDP becomes the trusted issuer.\r\n */\r\n val hostedAs: Boolean = true,\r\n /**\r\n * When true (default), provision a default OID4VCI issuer instance for this tenant\r\n * and bind its public endpoint. Ignored when [hostedAs] = false (a tenant with no\r\n * hosted AS hosts no co-located issuer).\r\n */\r\n val addIssuer: Boolean = true,\r\n /**\r\n * When true (default), provision a default OID4VP verifier instance for this tenant\r\n * and bind its public endpoint. Ignored when [hostedAs] = false (a tenant with no\r\n * hosted AS hosts no co-located verifier).\r\n */\r\n val addVerifier: Boolean = true,\r\n val owner: OwnerInput,\n val contacts: TenantOnboardingContactsInput? = null,\n val login: TenantOnboardingLoginInput = TenantOnboardingLoginInput(),\n val provisioning: TenantOnboardingProvisioningInput = TenantOnboardingProvisioningInput(),\n /**\r\n * Optional one-shot override of the seeded default settings for this tenant's service instances,\r\n * applied on top of the app-scope + per-tenant defaults stores at registration. Outer key is the\r\n * service token (`oauth2-as` / `oid4vci-issuer` / `oid4vp-verifier`); inner map is section\r\n * field-name → value. Only fields known to a service's section catalogs are honored; unknown\r\n * keys are ignored. Null = use the resolved defaults only.\r\n */\r\n val serviceDefaults: Map>? = null,\r\n)\n\n@Serializable\n@JvmInline\nvalue class TenantType(\n val value: String,\n) {\n companion object {\n /** Platform/system tenant (for multi-tenant SaaS platforms) */\n val PLATFORM = TenantType(\"platform\")\n\n /** Enterprise tenant (business, company) */\n val ENTERPRISE = TenantType(\"enterprise\")\n\n /** Partner tenant (external partner organization) */\n val PARTNER = TenantType(\"partner\")\n\n /** Sandbox tenant (for testing and development) */\n val SANDBOX = TenantType(\"sandbox\")\n }\n\n override fun toString(): String = value\n}\n\n@JsExportCompat\n@Serializable\ndata class Party\n @JvmOverloads\n constructor(\n /** Unique identifier for the party */\n @SerialName(\"id\")\n val partyId: Uuid,\n /** Tenant this party belongs to */\n @SerialName(\"tenantId\")\n val tenantId: String,\n /** The type of party */\n @SerialName(\"partyType\")\n val partyType: PartyType,\n /** Origin of the party (external/managed) */\n val origin: PartyOrigin,\n /**\n * User-friendly display name (editable by user). Non-null: abstract\n * identity-backed parties get filled with the identity's own UUID at\n * create-time so the schema invariant holds without a semantically-\n * empty sentinel; concrete Party roles (NaturalPerson / Organization /\n * Contact / OID4VCI-issuer / OID4VP-verifier / credential-template)\n * populate this with a meaningful human-readable name.\n */\n @SerialName(\"displayName\")\n val displayName: String,\n /** Optional URI for the party (DID, URL, etc.) */\n val uri: String? = null,\n /** Primary jurisdiction for this party (ISO 3166-1 code or region, e.g. \"EU\", \"US\", \"NL\") */\n val jurisdiction: String? = null,\n /** Reference to the owning party (for identities, this is the person/org that owns the identity) */\n @SerialName(\"ownerId\")\n val ownerId: Uuid? = null,\n /** When the party was created */\n @SerialName(\"createdAt\")\n val createdAt: Instant,\n /** Who created the party (party ID) */\n @SerialName(\"createdById\")\n val createdById: Uuid? = null,\n /** When the party was last updated */\n @SerialName(\"updatedAt\")\n val updatedAt: Instant,\n /** Who last updated the party (party ID) */\n @SerialName(\"updatedById\")\n val updatedById: Uuid? = null,\n /** When the party was soft-deleted (null if not deleted) */\n @SerialName(\"deletedAt\")\n val deletedAt: Instant? = null,\n /** Who deleted the party (party ID) */\n @SerialName(\"deletedById\")\n val deletedById: Uuid? = null,\n ) : HasId {\n override val id: String get() = partyId.toString()\n }\n\n@JsExportCompat\r\n@Serializable\r\nsealed class OwnerInput {\r\n abstract val email: String\r\n abstract val displayName: String\r\n\r\n @Serializable\r\n data class Local(\n override val email: String,\n override val displayName: String,\n val ownerPartyId: Uuid? = null,\n ) : OwnerInput()\n\r\n @Serializable\r\n data class Federated(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n /**\n * Owner's stable identifier inside the external IDP — typically the `sub`\r\n * claim, but can be any claim agreed in [FederationProviderInput.claimMapping].\r\n */\r\n val externalSubject: String,\n val ownerPartyId: Uuid? = null,\n ) : OwnerInput()\n\r\n @Serializable\r\n data class Hybrid(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n val externalSubject: String,\n val ownerPartyId: Uuid? = null,\n ) : OwnerInput()\n}\n\n @Serializable\r\n data class Federated(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n /**\n * Owner's stable identifier inside the external IDP — typically the `sub`\r\n * claim, but can be any claim agreed in [FederationProviderInput.claimMapping].\r\n */\r\n val externalSubject: String,\n val ownerPartyId: Uuid? = null,\n ) : OwnerInput()\n\n * writes, this delegate creates a first-class OID4VCI issuer software-party\n\n * key the KMS-backed delegate writes, this delegate creates a first-class OID4VP\n\n@Serializable\ndata class TenantOnboardingContactsInput(\n val technical: TenantOnboardingPersonInput,\n val administrative: TenantOnboardingPersonInput? = null,\n val administrativeSameAsTechnical: Boolean = false,\n val ownerAdmin: TenantOnboardingOwnerAdminInput,\n)\n\n@Serializable\ndata class TenantOnboardingLoginInput(\n val enabled: Boolean = true,\n val deliveryMode: TenantOwnerDeliveryMode = TenantOwnerDeliveryMode.EMAIL,\n val defaultAuthorizationServerRequired: Boolean = true,\n val operatorPassword: String? = null,\n)\n\n@Serializable\ndata class TenantOnboardingProvisioningInput(\n val issuer: Boolean = true,\n val verifier: Boolean = true,\n val keysAndDids: Boolean = true,\n val sampleData: Boolean = true,\n)\n\n @OptIn(ExperimentalObjCName::class)\n @ObjCName(\"cddlNull\")\n @Serializable(with = CDDLSerializer::class)\n object Null : CDDL(\"null\", MajorType.SPECIAL, 22, arrayOf(nil)) {\n fun newNull() = CborSimple.NULL\n\n fun fromJson(value: JsonElement) = CborSimple.NULL\n }\n\n@JsExportCompat\r\n@Serializable\r\ndata class Tenant\r\n @JvmOverloads\r\n constructor(\r\n @SerialName(\"id\")\r\n val tenantId: String,\r\n @SerialName(\"tenantType\")\r\n val tenantType: TenantType,\r\n val name: String,\r\n val description: String? = null,\r\n /**\r\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\r\n * platform subdomain label and the dispatcher's peelable path segment.\r\n */\r\n val slug: String,\r\n /**\r\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\r\n * time (cycle detection walks up `parent_tenant_id`).\r\n */\r\n @SerialName(\"parentTenantId\")\r\n val parentTenantId: String? = null,\r\n val status: TenantStatus = TenantStatus.ACTIVE,\r\n /**\r\n * Generic \"system tenant\" flag. System tenants are excluded from default\r\n * listings and from all slug-based / parent-based resolution queries. Customer\r\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\r\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\r\n * their own system-tenant patterns. EDK does not define what a system tenant\r\n * is or what privileges it carries.\r\n */\r\n val system: Boolean = false,\r\n @SerialName(\"ownerPartyId\")\r\n val ownerPartyId: Uuid? = null,\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null,\r\n ) : HasId {\r\n override val id: String get() = tenantId\r\n }\n\n@Serializable\n@JvmInline\nvalue class PartyType(\n val value: String,\n) {\n companion object {\n /** A human individual */\n val NATURAL_PERSON = PartyType(\"natural_person\")\n\n /** Alias for [NATURAL_PERSON] */\n val PERSON = NATURAL_PERSON\n\n /** A company, institution, or other legal entity */\n val ORGANIZATION = PartyType(\"organization\")\n\n /** A software-backed service participant (endpoint, integration, automated actor) */\n val SERVICE = PartyType(\"service\")\n\n /** A software product or deployable component. */\n val SOFTWARE = PartyType(\"software\")\n\n /** A physical, digital, or logical asset that can participate in relationships. */\n val ASSET = PartyType(\"asset\")\n\n /** A unit within an organization (department, division, sub-tenant scope) */\n val ORGANIZATION_UNIT = PartyType(\"organization_unit\")\n\n /** A collection of parties grouped for addressing or authorization */\n val GROUP = PartyType(\"group\")\n\n /** An autonomous actor acting on behalf of another party */\n val AGENT = PartyType(\"agent\")\n }\n\n override fun toString(): String = value\n}\n\n@JsExportCompat\n@Serializable\nenum class Origin {\n /** Resource was synced from an outside source (IdP, external system, import, auto-discovery) */\n @SerialName(\"external\")\n EXTERNAL,\n\n /** Resource was created and is managed natively within this system */\n @SerialName(\"managed\")\n MANAGED,\n ;\n\n companion object {\n fun fromValue(value: String): Origin =\n entries.firstOrNull { it.name.equals(value, ignoreCase = true) }\n ?: throw IllegalArgumentException(\"Unknown origin: $value\")\n }\n}" + }, + "RegisterTenantResult": { + "kind": "data class", + "name": "RegisterTenantResult", + "module": "public", + "source": "@JsExportCompat\r\n@Serializable\r\ndata class RegisterTenantResult(\r\n val tenant: Tenant,\r\n /** Primary platform subdomain URL, e.g. `https://acme.saas.com`. */\r\n val primaryDomainUrl: String,\r\n /** Default AS issuer URL, null when `hostedAs = false`. */\r\n val issuerUrl: String? = null,\r\n /**\r\n * Default OID4VCI credential-issuer identifier URL, null when `hostedAs = false`.\r\n * For co-located AS + issuer deployments this is the same origin as [issuerUrl]\r\n * with an `/oid4vci` path suffix.\r\n */\r\n val oid4vciIssuerUrl: String? = null,\r\n /**\r\n * Default OID4VP verifier identifier URL, null when `hostedAs = false` or\r\n * `addVerifier = false`. For co-located AS + verifier deployments this is the\r\n * same origin as [issuerUrl] with an `/oid4vp` path suffix.\r\n */\r\n val oid4vpVerifierUrl: String? = null,\n /** Local user id assigned to the owner. */\n val ownerUserId: String,\n /** Owner LOGIN identity in the application/platform tenant, when materialized. */\n val ownerIdentityId: Uuid? = null,\n /** Organization/contact/relationship parties created for this onboarding run. */\n val parties: TenantOnboardingPartyMaterialization = TenantOnboardingPartyMaterialization(),\n /** Durable tenant registration log id for onboarding/status polling. */\n val correlationId: String = \"\",\n /** Single-use invitation token, only for Local/Hybrid owners. */\r\n val invitationToken: String? = null,\r\n)\n\n@JsExportCompat\r\n@Serializable\r\ndata class Tenant\r\n @JvmOverloads\r\n constructor(\r\n @SerialName(\"id\")\r\n val tenantId: String,\r\n @SerialName(\"tenantType\")\r\n val tenantType: TenantType,\r\n val name: String,\r\n val description: String? = null,\r\n /**\r\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\r\n * platform subdomain label and the dispatcher's peelable path segment.\r\n */\r\n val slug: String,\r\n /**\r\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\r\n * time (cycle detection walks up `parent_tenant_id`).\r\n */\r\n @SerialName(\"parentTenantId\")\r\n val parentTenantId: String? = null,\r\n val status: TenantStatus = TenantStatus.ACTIVE,\r\n /**\r\n * Generic \"system tenant\" flag. System tenants are excluded from default\r\n * listings and from all slug-based / parent-based resolution queries. Customer\r\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\r\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\r\n * their own system-tenant patterns. EDK does not define what a system tenant\r\n * is or what privileges it carries.\r\n */\r\n val system: Boolean = false,\r\n @SerialName(\"ownerPartyId\")\r\n val ownerPartyId: Uuid? = null,\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null,\r\n ) : HasId {\r\n override val id: String get() = tenantId\r\n }\n\n * writes, this delegate creates a first-class OID4VCI issuer software-party\n\n * key the KMS-backed delegate writes, this delegate creates a first-class OID4VP\n\n @Serializable\r\n data class Local(\n override val email: String,\n override val displayName: String,\n val ownerPartyId: Uuid? = null,\n ) : OwnerInput()\n\n@JsExportCompat\n@Serializable\n@SerialName(\"organization\")\ndata class Organization\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n override val partyId: Uuid,\n @SerialName(\"tenantId\")\n override val tenantId: String,\n override val origin: PartyOrigin,\n @SerialName(\"displayName\")\n override val displayName: String,\n override val uri: String? = null,\n override val jurisdiction: String? = null,\n @SerialName(\"ownerId\")\n override val ownerId: Uuid? = null,\n @SerialName(\"organizationUnitId\")\n override val organizationUnitId: Uuid? = null,\n @SerialName(\"specializations\")\n override val specializations: List = emptyList(),\n @SerialName(\"createdAt\")\n override val createdAt: Instant,\n @SerialName(\"createdById\")\n override val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n override val updatedAt: Instant,\n @SerialName(\"updatedById\")\n override val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n override val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n override val deletedById: Uuid? = null,\n @SerialName(\"electronicAddresses\")\n override val electronicAddresses: List? = null,\n @SerialName(\"physicalAddresses\")\n override val physicalAddresses: List? = null,\n /** Registered legal name */\n @SerialName(\"legalName\")\n val legalName: String,\n /** Organization type (e.g. company, foundation, government) */\n @SerialName(\"organizationType\")\n val organizationType: String? = null,\n /** Industry classification */\n @SerialName(\"industry\")\n val industry: String? = null,\n /** Primary contact email */\n @SerialName(\"contactEmail\")\n val contactEmail: String? = null,\n /** Public website URL */\n @SerialName(\"websiteUrl\")\n val websiteUrl: String? = null,\n /** Privacy policy URI */\n @SerialName(\"privacyPolicyUri\")\n val privacyPolicyUri: String? = null,\n /** Terms of service URI */\n @SerialName(\"tosUri\")\n val tosUri: String? = null,\n ) : PartyEntity {\n override val partyType: PartyType get() = PartyType.ORGANIZATION\n }\n\n@Serializable\ndata class TenantOnboardingPartyMaterialization(\n val ownerPartyId: Uuid? = null,\n val technicalContactPartyId: Uuid? = null,\n val administrativeContactPartyId: Uuid? = null,\n val ownerAdminPartyId: Uuid? = null,\n val relationshipIds: List = emptyList(),\n val createdPersonPartyIds: List = emptyList(),\n val createdElectronicAddressIds: List = emptyList(),\n)\n\n @Serializable\r\n data class Hybrid(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n val externalSubject: String,\n val ownerPartyId: Uuid? = null,\n ) : OwnerInput()\n\n@Serializable\n@JvmInline\nvalue class TenantType(\n val value: String,\n) {\n companion object {\n /** Platform/system tenant (for multi-tenant SaaS platforms) */\n val PLATFORM = TenantType(\"platform\")\n\n /** Enterprise tenant (business, company) */\n val ENTERPRISE = TenantType(\"enterprise\")\n\n /** Partner tenant (external partner organization) */\n val PARTNER = TenantType(\"partner\")\n\n /** Sandbox tenant (for testing and development) */\n val SANDBOX = TenantType(\"sandbox\")\n }\n\n override fun toString(): String = value\n}\n\n @Serializable\n @SerialName(\"lowercase\")\n data object Lowercase : ClaimTransformation\n\n@JsExportCompat\r\n@Serializable\r\nenum class TenantStatus {\r\n ACTIVE,\r\n SUSPENDED,\r\n PENDING_VERIFICATION,\r\n}\n\n data class Generic(\n val exception: Throwable? = null,\n override val message: String = \"Consent error\",\n ) : ConsentError\n\n @Serializable\n data class System(\n override val id: String,\n val commandId: String,\n /** Mapping expression (engine-interpreted) producing the command's input from prior outputs. */\n val inputExpression: String,\n val next: String? = null,\n ) : WorkflowTask()\n\n@JsExportCompat\n@OptIn(ExperimentalObjCName::class)\n@ObjCName(\"HasId\", exact = true)\ninterface HasId {\n val id: String\n}" + }, + "RequestTenantSignupArgs": { + "kind": "data class", + "name": "RequestTenantSignupArgs", + "module": "service", + "source": "@JsExportCompat\r\n@Serializable\r\ndata class RequestTenantSignupArgs(\r\n val email: String,\r\n val slug: String,\r\n /** null → SaaS root signup; non-null → subtenant signup under this parent. */\r\n val parentTenantId: String? = null,\r\n val displayName: String,\r\n /** Hashed source IP for SOC + rate-limit. Adapter computes the hash; command never sees raw IP. */\r\n val sourceIpHash: String? = null,\r\n /** Bot-defence challenge proof. Verifier may be no-op in dev / pure-EDK. */\r\n val challengeProof: String? = null,\r\n)" + }, + "RequestTenantSignupResult": { + "kind": "data class", + "name": "RequestTenantSignupResult", + "module": "service", + "source": "@JsExportCompat\r\n@Serializable\r\ndata class RequestTenantSignupResult(\r\n val signupRequestId: String,\r\n /**\r\n * Plaintext token. Sent out-of-band via the email channel by the calling\r\n * adapter; never persisted on the server. Returned ONLY in this in-process\r\n * call result — production REST adapters must NOT include it in the HTTP\r\n * response (the response is just the request id and expiry).\r\n */\r\n val plainVerificationToken: String,\r\n val expiresAt: Instant,\r\n val requiresApproval: Boolean,\r\n)\n\n data object Sent : Oid4vciIssuerNotificationResult()\n\nsealed class Oid4vciIssuerNotificationResult {\n data object Sent : Oid4vciIssuerNotificationResult()\n\n data object NotSupported : Oid4vciIssuerNotificationResult()\n\n data class Failed(\n val code: String,\n val messageKey: String,\n val retryable: Boolean = true,\n val arguments: Map = emptyMap(),\n ) : Oid4vciIssuerNotificationResult()\n}" + }, + "ConfirmTenantSignupArgs": { + "kind": "data class", + "name": "ConfirmTenantSignupArgs", + "module": "service", + "source": "@JsExportCompat\r\n@Serializable\r\ndata class ConfirmTenantSignupArgs(\r\n /** Plaintext token the requester clicked through email. The command hashes and looks up. */\r\n val plainVerificationToken: String,\r\n)" + }, + "ConfirmTenantSignupResult": { + "kind": "data class", + "name": "ConfirmTenantSignupResult", + "module": "service", + "source": "@JsExportCompat\r\n@Serializable\r\ndata class ConfirmTenantSignupResult(\r\n val signupRequestId: String,\r\n val status: TenantSignupStatus,\r\n val registration: RegisterTenantResult? = null,\r\n)\n\n@JsExportCompat\r\nenum class TenantSignupStatus {\r\n PENDING_EMAIL,\r\n PENDING_APPROVAL,\r\n CONFIRMED,\r\n REGISTERED,\r\n REJECTED,\r\n EXPIRED,\r\n FAILED,\r\n}\n\n@JsExportCompat\r\n@Serializable\r\ndata class RegisterTenantResult(\r\n val tenant: Tenant,\r\n /** Primary platform subdomain URL, e.g. `https://acme.saas.com`. */\r\n val primaryDomainUrl: String,\r\n /** Default AS issuer URL, null when `hostedAs = false`. */\r\n val issuerUrl: String? = null,\r\n /**\r\n * Default OID4VCI credential-issuer identifier URL, null when `hostedAs = false`.\r\n * For co-located AS + issuer deployments this is the same origin as [issuerUrl]\r\n * with an `/oid4vci` path suffix.\r\n */\r\n val oid4vciIssuerUrl: String? = null,\r\n /**\r\n * Default OID4VP verifier identifier URL, null when `hostedAs = false` or\r\n * `addVerifier = false`. For co-located AS + verifier deployments this is the\r\n * same origin as [issuerUrl] with an `/oid4vp` path suffix.\r\n */\r\n val oid4vpVerifierUrl: String? = null,\n /** Local user id assigned to the owner. */\n val ownerUserId: String,\n /** Owner LOGIN identity in the application/platform tenant, when materialized. */\n val ownerIdentityId: Uuid? = null,\n /** Organization/contact/relationship parties created for this onboarding run. */\n val parties: TenantOnboardingPartyMaterialization = TenantOnboardingPartyMaterialization(),\n /** Durable tenant registration log id for onboarding/status polling. */\n val correlationId: String = \"\",\n /** Single-use invitation token, only for Local/Hybrid owners. */\r\n val invitationToken: String? = null,\r\n)\n\n data class FAILED(\n val failure: WalletOperationReplayFailure\n ) : ReplayOutcome\n\n@JsExportCompat\r\n@Serializable\r\ndata class Tenant\r\n @JvmOverloads\r\n constructor(\r\n @SerialName(\"id\")\r\n val tenantId: String,\r\n @SerialName(\"tenantType\")\r\n val tenantType: TenantType,\r\n val name: String,\r\n val description: String? = null,\r\n /**\r\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\r\n * platform subdomain label and the dispatcher's peelable path segment.\r\n */\r\n val slug: String,\r\n /**\r\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\r\n * time (cycle detection walks up `parent_tenant_id`).\r\n */\r\n @SerialName(\"parentTenantId\")\r\n val parentTenantId: String? = null,\r\n val status: TenantStatus = TenantStatus.ACTIVE,\r\n /**\r\n * Generic \"system tenant\" flag. System tenants are excluded from default\r\n * listings and from all slug-based / parent-based resolution queries. Customer\r\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\r\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\r\n * their own system-tenant patterns. EDK does not define what a system tenant\r\n * is or what privileges it carries.\r\n */\r\n val system: Boolean = false,\r\n @SerialName(\"ownerPartyId\")\r\n val ownerPartyId: Uuid? = null,\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null,\r\n ) : HasId {\r\n override val id: String get() = tenantId\r\n }\n\n * writes, this delegate creates a first-class OID4VCI issuer software-party\n\n * key the KMS-backed delegate writes, this delegate creates a first-class OID4VP\n\n @Serializable\r\n data class Local(\n override val email: String,\n override val displayName: String,\n val ownerPartyId: Uuid? = null,\n ) : OwnerInput()\n\n@JsExportCompat\n@Serializable\n@SerialName(\"organization\")\ndata class Organization\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n override val partyId: Uuid,\n @SerialName(\"tenantId\")\n override val tenantId: String,\n override val origin: PartyOrigin,\n @SerialName(\"displayName\")\n override val displayName: String,\n override val uri: String? = null,\n override val jurisdiction: String? = null,\n @SerialName(\"ownerId\")\n override val ownerId: Uuid? = null,\n @SerialName(\"organizationUnitId\")\n override val organizationUnitId: Uuid? = null,\n @SerialName(\"specializations\")\n override val specializations: List = emptyList(),\n @SerialName(\"createdAt\")\n override val createdAt: Instant,\n @SerialName(\"createdById\")\n override val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n override val updatedAt: Instant,\n @SerialName(\"updatedById\")\n override val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n override val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n override val deletedById: Uuid? = null,\n @SerialName(\"electronicAddresses\")\n override val electronicAddresses: List? = null,\n @SerialName(\"physicalAddresses\")\n override val physicalAddresses: List? = null,\n /** Registered legal name */\n @SerialName(\"legalName\")\n val legalName: String,\n /** Organization type (e.g. company, foundation, government) */\n @SerialName(\"organizationType\")\n val organizationType: String? = null,\n /** Industry classification */\n @SerialName(\"industry\")\n val industry: String? = null,\n /** Primary contact email */\n @SerialName(\"contactEmail\")\n val contactEmail: String? = null,\n /** Public website URL */\n @SerialName(\"websiteUrl\")\n val websiteUrl: String? = null,\n /** Privacy policy URI */\n @SerialName(\"privacyPolicyUri\")\n val privacyPolicyUri: String? = null,\n /** Terms of service URI */\n @SerialName(\"tosUri\")\n val tosUri: String? = null,\n ) : PartyEntity {\n override val partyType: PartyType get() = PartyType.ORGANIZATION\n }\n\n@Serializable\ndata class TenantOnboardingPartyMaterialization(\n val ownerPartyId: Uuid? = null,\n val technicalContactPartyId: Uuid? = null,\n val administrativeContactPartyId: Uuid? = null,\n val ownerAdminPartyId: Uuid? = null,\n val relationshipIds: List = emptyList(),\n val createdPersonPartyIds: List = emptyList(),\n val createdElectronicAddressIds: List = emptyList(),\n)\n\n @Serializable\r\n data class Hybrid(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n val externalSubject: String,\n val ownerPartyId: Uuid? = null,\n ) : OwnerInput()" + }, + "ResendTenantSignupVerificationArgs": { + "kind": "data class", + "name": "ResendTenantSignupVerificationArgs", + "module": "service", + "source": "@JsExportCompat\r\n@Serializable\r\ndata class ResendTenantSignupVerificationArgs(\r\n val signupRequestId: String,\r\n /** Hashed source IP for rate-limit + audit. The adapter computes the hash. */\r\n val sourceIpHash: String? = null,\r\n)" + }, + "ResendTenantSignupVerificationResult": { + "kind": "data class", + "name": "ResendTenantSignupVerificationResult", + "module": "service", + "source": "@JsExportCompat\r\n@Serializable\r\ndata class ResendTenantSignupVerificationResult(\r\n val signupRequestId: String,\r\n /**\r\n * Fresh plaintext token. Same security model as\r\n * [RequestTenantSignupResult.plainVerificationToken] — sent out-of-band\r\n * via the email channel by the calling adapter; never persisted; never\r\n * returned in the public HTTP response.\r\n */\r\n val plainVerificationToken: String,\r\n val expiresAt: Instant,\r\n /**\r\n * Whether the parent tenant's signup policy requires operator\r\n * approval after email verification. Carried so the resend\r\n * notification email matches the actual post-click journey — the\r\n * request-time email already carries this flag and the resend must\r\n * not contradict it.\r\n */\r\n val requiresApproval: Boolean,\r\n)\n\n@JsExportCompat\r\n@Serializable\r\ndata class RequestTenantSignupResult(\r\n val signupRequestId: String,\r\n /**\r\n * Plaintext token. Sent out-of-band via the email channel by the calling\r\n * adapter; never persisted on the server. Returned ONLY in this in-process\r\n * call result — production REST adapters must NOT include it in the HTTP\r\n * response (the response is just the request id and expiry).\r\n */\r\n val plainVerificationToken: String,\r\n val expiresAt: Instant,\r\n val requiresApproval: Boolean,\r\n)\n\n data object Sent : Oid4vciIssuerNotificationResult()" + }, + "ReconcileExpiredTenantSignupsArgs": { + "kind": "data class", + "name": "ReconcileExpiredTenantSignupsArgs", + "module": "service", + "source": "@JsExportCompat\r\n@Serializable\r\ndata class ReconcileExpiredTenantSignupsArgs(val now: Instant)" + }, + "ReconcileExpiredTenantSignupsResult": { + "kind": "data class", + "name": "ReconcileExpiredTenantSignupsResult", + "module": "service", + "source": "@JsExportCompat\r\n@Serializable\r\ndata class ReconcileExpiredTenantSignupsResult(\r\n val expiredCount: Int,\r\n)" + }, + "ApplicationTenantBootstrapRequest": { + "kind": "data class", + "name": "ApplicationTenantBootstrapRequest", + "module": "application-admin", + "source": "@Serializable\r\ndata class ApplicationTenantBootstrapRequest(\r\n val operatorEmail: String? = null,\r\n val operatorDisplayName: String? = null,\r\n)" + }, + "ApplicationTenantStatusSnapshot": { + "kind": "data class", + "name": "ApplicationTenantStatusSnapshot", + "module": "application-admin", + "source": "@Serializable\r\ndata class ApplicationTenantStatusSnapshot(\r\n val tenantId: String,\r\n val status: ApplicationTenantStatus,\r\n val hostedAsAvailable: Boolean,\r\n val hostedAsIssuerUrl: String? = null,\r\n val canRegisterFirstRealTenant: Boolean,\r\n)\n\n@Serializable\r\nenum class ApplicationTenantStatus {\r\n @SerialName(\"ACTIVE\")\r\n ACTIVE,\r\n\r\n @SerialName(\"SUSPENDED\")\r\n SUSPENDED,\r\n\r\n @SerialName(\"PENDING_VERIFICATION\")\r\n PENDING_VERIFICATION,\r\n}" + }, + "ApproveTenantSignupArgs": { + "kind": "data class", + "name": "ApproveTenantSignupArgs", + "module": "service", + "source": "@JsExportCompat\r\n@Serializable\r\ndata class ApproveTenantSignupArgs(\r\n val signupRequestId: String,\r\n val notes: String? = null,\r\n)" + }, + "ApproveTenantSignupResult": { + "kind": "data class", + "name": "ApproveTenantSignupResult", + "module": "service", + "source": "@JsExportCompat\r\n@Serializable\r\ndata class ApproveTenantSignupResult(\r\n val signupRequestId: String,\r\n val status: TenantSignupStatus,\r\n val registration: RegisterTenantResult? = null,\r\n)\n\n@JsExportCompat\r\nenum class TenantSignupStatus {\r\n PENDING_EMAIL,\r\n PENDING_APPROVAL,\r\n CONFIRMED,\r\n REGISTERED,\r\n REJECTED,\r\n EXPIRED,\r\n FAILED,\r\n}\n\n@JsExportCompat\r\n@Serializable\r\ndata class RegisterTenantResult(\r\n val tenant: Tenant,\r\n /** Primary platform subdomain URL, e.g. `https://acme.saas.com`. */\r\n val primaryDomainUrl: String,\r\n /** Default AS issuer URL, null when `hostedAs = false`. */\r\n val issuerUrl: String? = null,\r\n /**\r\n * Default OID4VCI credential-issuer identifier URL, null when `hostedAs = false`.\r\n * For co-located AS + issuer deployments this is the same origin as [issuerUrl]\r\n * with an `/oid4vci` path suffix.\r\n */\r\n val oid4vciIssuerUrl: String? = null,\r\n /**\r\n * Default OID4VP verifier identifier URL, null when `hostedAs = false` or\r\n * `addVerifier = false`. For co-located AS + verifier deployments this is the\r\n * same origin as [issuerUrl] with an `/oid4vp` path suffix.\r\n */\r\n val oid4vpVerifierUrl: String? = null,\n /** Local user id assigned to the owner. */\n val ownerUserId: String,\n /** Owner LOGIN identity in the application/platform tenant, when materialized. */\n val ownerIdentityId: Uuid? = null,\n /** Organization/contact/relationship parties created for this onboarding run. */\n val parties: TenantOnboardingPartyMaterialization = TenantOnboardingPartyMaterialization(),\n /** Durable tenant registration log id for onboarding/status polling. */\n val correlationId: String = \"\",\n /** Single-use invitation token, only for Local/Hybrid owners. */\r\n val invitationToken: String? = null,\r\n)\n\n data class FAILED(\n val failure: WalletOperationReplayFailure\n ) : ReplayOutcome\n\n@JsExportCompat\r\n@Serializable\r\ndata class Tenant\r\n @JvmOverloads\r\n constructor(\r\n @SerialName(\"id\")\r\n val tenantId: String,\r\n @SerialName(\"tenantType\")\r\n val tenantType: TenantType,\r\n val name: String,\r\n val description: String? = null,\r\n /**\r\n * Globally unique URL-safe slug. Lowercase, hyphen-separated. Used as both the\r\n * platform subdomain label and the dispatcher's peelable path segment.\r\n */\r\n val slug: String,\r\n /**\r\n * Parent tenant id. `null` for root tenants. Hierarchy is enforced at insert\r\n * time (cycle detection walks up `parent_tenant_id`).\r\n */\r\n @SerialName(\"parentTenantId\")\r\n val parentTenantId: String? = null,\r\n val status: TenantStatus = TenantStatus.ACTIVE,\r\n /**\r\n * Generic \"system tenant\" flag. System tenants are excluded from default\r\n * listings and from all slug-based / parent-based resolution queries. Customer\r\n * tenants always have `system = false`. Higher layers (e.g. VDX) use this flag\r\n * to materialise their admin-control tenant; pure-EDK consumers can use it for\r\n * their own system-tenant patterns. EDK does not define what a system tenant\r\n * is or what privileges it carries.\r\n */\r\n val system: Boolean = false,\r\n @SerialName(\"ownerPartyId\")\r\n val ownerPartyId: Uuid? = null,\r\n @SerialName(\"createdAt\")\r\n val createdAt: Instant,\r\n @SerialName(\"createdById\")\r\n val createdById: Uuid? = null,\r\n @SerialName(\"updatedAt\")\r\n val updatedAt: Instant,\r\n @SerialName(\"updatedById\")\r\n val updatedById: Uuid? = null,\r\n @SerialName(\"deletedAt\")\r\n val deletedAt: Instant? = null,\r\n @SerialName(\"deletedById\")\r\n val deletedById: Uuid? = null,\r\n ) : HasId {\r\n override val id: String get() = tenantId\r\n }\n\n * writes, this delegate creates a first-class OID4VCI issuer software-party\n\n * key the KMS-backed delegate writes, this delegate creates a first-class OID4VP\n\n @Serializable\r\n data class Local(\n override val email: String,\n override val displayName: String,\n val ownerPartyId: Uuid? = null,\n ) : OwnerInput()\n\n@JsExportCompat\n@Serializable\n@SerialName(\"organization\")\ndata class Organization\n @JvmOverloads\n constructor(\n @SerialName(\"id\")\n override val partyId: Uuid,\n @SerialName(\"tenantId\")\n override val tenantId: String,\n override val origin: PartyOrigin,\n @SerialName(\"displayName\")\n override val displayName: String,\n override val uri: String? = null,\n override val jurisdiction: String? = null,\n @SerialName(\"ownerId\")\n override val ownerId: Uuid? = null,\n @SerialName(\"organizationUnitId\")\n override val organizationUnitId: Uuid? = null,\n @SerialName(\"specializations\")\n override val specializations: List = emptyList(),\n @SerialName(\"createdAt\")\n override val createdAt: Instant,\n @SerialName(\"createdById\")\n override val createdById: Uuid? = null,\n @SerialName(\"updatedAt\")\n override val updatedAt: Instant,\n @SerialName(\"updatedById\")\n override val updatedById: Uuid? = null,\n @SerialName(\"deletedAt\")\n override val deletedAt: Instant? = null,\n @SerialName(\"deletedById\")\n override val deletedById: Uuid? = null,\n @SerialName(\"electronicAddresses\")\n override val electronicAddresses: List? = null,\n @SerialName(\"physicalAddresses\")\n override val physicalAddresses: List? = null,\n /** Registered legal name */\n @SerialName(\"legalName\")\n val legalName: String,\n /** Organization type (e.g. company, foundation, government) */\n @SerialName(\"organizationType\")\n val organizationType: String? = null,\n /** Industry classification */\n @SerialName(\"industry\")\n val industry: String? = null,\n /** Primary contact email */\n @SerialName(\"contactEmail\")\n val contactEmail: String? = null,\n /** Public website URL */\n @SerialName(\"websiteUrl\")\n val websiteUrl: String? = null,\n /** Privacy policy URI */\n @SerialName(\"privacyPolicyUri\")\n val privacyPolicyUri: String? = null,\n /** Terms of service URI */\n @SerialName(\"tosUri\")\n val tosUri: String? = null,\n ) : PartyEntity {\n override val partyType: PartyType get() = PartyType.ORGANIZATION\n }\n\n@Serializable\ndata class TenantOnboardingPartyMaterialization(\n val ownerPartyId: Uuid? = null,\n val technicalContactPartyId: Uuid? = null,\n val administrativeContactPartyId: Uuid? = null,\n val ownerAdminPartyId: Uuid? = null,\n val relationshipIds: List = emptyList(),\n val createdPersonPartyIds: List = emptyList(),\n val createdElectronicAddressIds: List = emptyList(),\n)\n\n @Serializable\r\n data class Hybrid(\n override val email: String,\n override val displayName: String,\n val federationProvider: FederationProviderInput,\n val externalSubject: String,\n val ownerPartyId: Uuid? = null,\n ) : OwnerInput()" + }, + "RejectTenantSignupArgs": { + "kind": "data class", + "name": "RejectTenantSignupArgs", + "module": "service", + "source": "@JsExportCompat\r\n@Serializable\r\ndata class RejectTenantSignupArgs(\r\n val signupRequestId: String,\r\n val reason: String? = null,\r\n)" + }, + "RejectTenantSignupResult": { + "kind": "data class", + "name": "RejectTenantSignupResult", + "module": "service", + "source": "@JsExportCompat\r\n@Serializable\r\ndata class RejectTenantSignupResult(val rejected: Boolean)" + } +} diff --git a/docs-groups.json b/docs-groups.json index 8153f50..74bbf96 100644 --- a/docs-groups.json +++ b/docs-groups.json @@ -5,7 +5,7 @@ { "key": "verifiable-credentials", "label": "Digital Credentials", "apis": ["oid4vci-issuer", "oid4vci-issuer-session", "oid4vp-universal", "oid4vp-verifier", "credential-design", "dcql", "dcql-edk", "dcql-vdx", "statuslist-hosting", "statuslist-management"] }, { "key": "semantics", "label": "Semantics & Catalog", "apis": ["semantic-model-authoring", "semantic-binding", "semantic-vocabulary"] }, { "key": "parties", "label": "Parties & Accounts", "apis": ["party-manager", "user-manager", "identity-auth"] }, - { "key": "services", "label": "Services", "apis": ["software-manager", "connector", "resource-manager", "email", "asset"] }, + { "key": "services", "label": "Services", "apis": ["software-manager", "connector", "connector-integration", "resource-manager", "email", "asset", "theme"] }, { "key": "platform", "label": "Tenancy & Platform", "apis": ["platform-admin", "platform-setup", "platform-bootstrap", "platform-config", "invitation", "forms"] } ], "labels": { @@ -33,6 +33,7 @@ "resource-manager": "Resource & Booking", "software-manager": "Software / Instance Manager", "connector": "Connectors", + "connector-integration": "Connector Integration", "platform-admin": "Platform Admin", "platform-setup": "Platform Setup", "platform-bootstrap": "Platform Bootstrap", @@ -40,6 +41,7 @@ "invitation": "Invitations & Redemption", "email": "Email", "forms": "Forms", - "asset": "Tenant Assets" + "asset": "Tenant Assets", + "theme": "Branding & Theme" } } diff --git a/manifest-catalog.json b/manifest-catalog.json index 21a1181..9d9bb48 100644 --- a/manifest-catalog.json +++ b/manifest-catalog.json @@ -43,6 +43,7 @@ "unbound": [ { "division": "edk", "domain": "oid4vp-dcql", "specPath": "dcql-edk-openapi.yml", "ownerModule": null, "targets": ["edk"], "note": "EDK DCQL authoring/versioning layer ($ref-extends the idk dcql base). Runtime owner of authoring/versioning endpoints unconfirmed; documentation-only until wired." }, { "division": "vdx", "domain": "connector", "specPath": "connector-openapi.yml", "ownerModule": null, "targets": ["vdx"], "note": "Greenfield API-design-first Connector Registry API under /api/connector/v1. Part of the platform service settings plan, intentionally separate from platform-config until runtime ownership is implemented." }, + { "division": "vdx", "domain": "connector-integration", "specPath": "connector-integration-openapi.yml", "ownerModule": null, "targets": ["vdx"], "note": "Curated external connector integration profile derived from the v1 Connector Registry API for third-party connector builders, SDK consumers, and low-code importers." }, { "division": "edk", "domain": "oid4vci-issuance-template", "specPath": "oid4vci-issuance-template-openapi.yml", "ownerModule": null, "targets": ["edk","vdx"], "note": "Tenant-scoped reusable OID4VCI issuance templates under /api/oid4vci/v1 that store stable credential-offer settings and execute against the existing issuer-session credential-offer path. Bundled by admin-api-client codegen; runtime owner module unconfirmed until wired." }, { "division": "edk", "domain": "oid4vp-verification-template", "specPath": "oid4vp-verification-template-openapi.yml", "ownerModule": null, "targets": ["edk","vdx"], "note": "Tenant-scoped reusable OID4VP verification templates under /api/oid4vp/v1 that store stable authorization-request settings and execute against the universal verifier-session create-authorization-request path. Bundled by admin-api-client codegen; runtime owner module unconfirmed until wired." } ], diff --git a/theme-openapi.yml b/theme-openapi.yml index 48b306e..51b8d58 100644 --- a/theme-openapi.yml +++ b/theme-openapi.yml @@ -2,7 +2,7 @@ openapi: 3.0.4 info: title: Theme API version: 0.1.0 - x-products: [vdx] + x-products: [edk, vdx] description: | Tenant branding and theming API. Tenants brand every product surface from one system: a simple brand (app name, colors, logos, favicon, tagline) set once at tenant level,