68 lines
2.0 KiB
Go
68 lines
2.0 KiB
Go
package contracts
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
)
|
|
|
|
// ArtifactKind is the stable logical identity of a domain artifact.
|
|
type ArtifactKind string
|
|
|
|
// ArtifactSchema describes the durable representation owned by an artifact
|
|
// codec. JSONSchema is cloned whenever framework ownership changes.
|
|
type ArtifactSchema struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Version string `json:"version"`
|
|
JSONSchema []byte `json:"-"`
|
|
}
|
|
|
|
// SerializedArtifact is the domain-neutral representation of a typed
|
|
// artifact at an explicit serialization boundary.
|
|
type SerializedArtifact struct {
|
|
Kind ArtifactKind `json:"kind"`
|
|
Schema ArtifactSchema `json:"schema"`
|
|
MediaType string `json:"media_type"`
|
|
Content []byte `json:"-"`
|
|
Metadata map[string]any `json:"metadata,omitempty"`
|
|
}
|
|
|
|
// ArtifactCodec owns the stable encoding for one concrete artifact type.
|
|
type ArtifactCodec[T any] interface {
|
|
Kind() ArtifactKind
|
|
Schema() ArtifactSchema
|
|
MediaType() string
|
|
Encode(T) ([]byte, error)
|
|
Decode([]byte) (T, error)
|
|
}
|
|
|
|
// DigestArtifactSchema returns the SHA-256 digest of the exact JSON Schema
|
|
// bytes. Schema formatting is therefore part of the registered identity.
|
|
func DigestArtifactSchema(schema ArtifactSchema) string {
|
|
sum := sha256.Sum256(schema.JSONSchema)
|
|
return "sha256:" + hex.EncodeToString(sum[:])
|
|
}
|
|
|
|
func CloneArtifactSchema(schema ArtifactSchema) ArtifactSchema {
|
|
schema.JSONSchema = append([]byte(nil), schema.JSONSchema...)
|
|
return schema
|
|
}
|
|
|
|
func CloneSerializedArtifact(artifact SerializedArtifact) SerializedArtifact {
|
|
artifact.Schema = CloneArtifactSchema(artifact.Schema)
|
|
artifact.Content = append([]byte(nil), artifact.Content...)
|
|
artifact.Metadata = cloneArtifactMetadata(artifact.Metadata)
|
|
return artifact
|
|
}
|
|
|
|
func cloneArtifactMetadata(metadata map[string]any) map[string]any {
|
|
if len(metadata) == 0 {
|
|
return nil
|
|
}
|
|
out := make(map[string]any, len(metadata))
|
|
for key, value := range metadata {
|
|
out[key] = value
|
|
}
|
|
return out
|
|
}
|