visual-game-scenario-release.js 5.84 KB
import * as v from 'valibot'

const DateTime = v.pipe(v.string(), v.isoTimestamp())
const NullableString = v.nullable(v.string())
const NullableNumber = v.nullable(v.number())

const ScenarioReleasePack = v.strictObject({
  id: v.pipe(v.string(), v.minLength(1), v.maxLength(96)),
  title: v.pipe(v.string(), v.minLength(1), v.maxLength(160)),
  locale: v.pipe(v.string(), v.minLength(1), v.maxLength(16)),
  series_id: NullableString,
  episode_no: NullableNumber,
  status: v.literal('published'),
  visibility: v.pipe(v.string(), v.minLength(1), v.maxLength(24)),
  current_version_id: v.pipe(v.string(), v.minLength(1), v.maxLength(120)),
  tagline: NullableString,
  tags_json: v.array(v.pipe(
    v.string(),
    v.minLength(1),
    v.check(tag => tag.trim() === tag, 'tag must not have surrounding whitespace'),
  )),
  created_at: DateTime,
  updated_at: DateTime,
})

const ScenarioReleaseSeries = v.nullable(v.strictObject({
  id: v.pipe(v.string(), v.minLength(1), v.maxLength(96)),
  title: v.pipe(v.string(), v.minLength(1), v.maxLength(160)),
  locale: v.pipe(v.string(), v.minLength(1), v.maxLength(16)),
  tagline: NullableString,
  status: v.pipe(v.string(), v.minLength(1), v.maxLength(24)),
  visibility: v.pipe(v.string(), v.minLength(1), v.maxLength(24)),
  cover_url: NullableString,
  created_at: DateTime,
  updated_at: DateTime,
}))

const ScenarioReleaseVersion = v.strictObject({
  id: v.pipe(v.string(), v.minLength(1), v.maxLength(120)),
  pack_id: v.pipe(v.string(), v.minLength(1), v.maxLength(96)),
  version: v.pipe(v.number(), v.integer(), v.minValue(1)),
  status: v.literal('published'),
  title: v.pipe(v.string(), v.minLength(1), v.maxLength(160)),
  tagline: NullableString,
  asset_manifest_id: NullableString,
  portrait_cover_tag: NullableString,
  scenario_snapshot_json: v.string(),
  compile_result_json: v.string(),
  compiler_version: NullableString,
  published_at: DateTime,
  created_at: DateTime,
  updated_at: DateTime,
})

const ScenarioReleasePublishCheck = v.strictObject({
  id: v.pipe(v.string(), v.minLength(1), v.maxLength(120)),
  version_id: v.pipe(v.string(), v.minLength(1), v.maxLength(120)),
  check_type: v.pipe(v.string(), v.minLength(1), v.maxLength(64)),
  status: v.pipe(v.string(), v.minLength(1), v.maxLength(24)),
  message: NullableString,
  target_ref: NullableString,
  created_at: DateTime,
  updated_at: DateTime,
})

const ScenarioReleaseVersionAsset = v.strictObject({
  version_id: v.pipe(v.string(), v.minLength(1), v.maxLength(120)),
  asset_id: v.pipe(v.string(), v.minLength(1), v.maxLength(120)),
  tag: v.pipe(v.string(), v.minLength(1), v.maxLength(96)),
  object_key: NullableString,
  public_url: NullableString,
  mime: NullableString,
  size: NullableNumber,
  hash: NullableString,
  created_at: DateTime,
  updated_at: DateTime,
})

const ScenarioReleaseTranslation = v.strictObject({
  entity_type: v.picklist(['scenario_pack', 'scenario_version', 'series', 'ending']),
  entity_id: v.pipe(v.string(), v.minLength(1), v.maxLength(160)),
  locale: v.picklist(['zh-CN', 'en', 'ja', 'ko', 'es', 'pt']),
  field: v.picklist(['title', 'tagline', 'summary', 'description', 'runtime_texts']),
  content: v.pipe(v.string(), v.minLength(1)),
  created_at: DateTime,
  updated_at: DateTime,
})

const ScenarioReleaseRuntimeTranslationManifest = v.strictObject({
  version_id: v.pipe(v.string(), v.minLength(1), v.maxLength(160)),
  locale: v.pipe(v.string(), v.minLength(1), v.maxLength(16)),
  schema_version: v.pipe(v.number(), v.integer(), v.minValue(1)),
  entries_json: v.string(),
  created_at: DateTime,
  updated_at: DateTime,
})

export const VisualGameScenarioReleaseBundle = v.strictObject({
  pack: ScenarioReleasePack,
  series: ScenarioReleaseSeries,
  version: ScenarioReleaseVersion,
  publish_checks: v.array(ScenarioReleasePublishCheck),
  version_assets: v.array(ScenarioReleaseVersionAsset),
  translations: v.array(ScenarioReleaseTranslation),
  runtime_translation_manifests: v.array(ScenarioReleaseRuntimeTranslationManifest),
})

export const VisualGameScenarioReleaseRequest = v.strictObject({
  release_id: v.pipe(v.string(), v.uuid()),
  requested_by: v.pipe(v.string(), v.minLength(1), v.maxLength(64)),
  bundle_checksum: v.pipe(v.string(), v.regex(/^[a-f0-9]{64}$/)),
  bundle: VisualGameScenarioReleaseBundle,
})

export const VisualGameScenarioReleaseTargetState = v.strictObject({
  exists: v.boolean(),
  scenario_id: v.pipe(v.string(), v.minLength(1)),
  title: NullableString,
  current_version_id: NullableString,
  version: NullableNumber,
  published_at: v.nullable(DateTime),
  assets: v.number(),
})

export const VisualGameScenarioReleaseApplyResponse = v.strictObject({
  ok: v.literal(true),
  request_id: v.pipe(v.string(), v.uuid()),
  scenario_id: v.pipe(v.string(), v.minLength(1)),
  previous_version_id: NullableString,
  current_version_id: v.pipe(v.string(), v.minLength(1)),
  version: v.number(),
  assets_copied: v.number(),
  assets_reused: v.number(),
  bytes_copied: v.number(),
})

export const VisualGameScenarioReleaseRecord = v.strictObject({
  id: v.pipe(v.string(), v.uuid()),
  direction: v.picklist(['outbound', 'inbound']),
  scenario_id: v.pipe(v.string(), v.minLength(1), v.maxLength(96)),
  source_version_id: v.pipe(v.string(), v.minLength(1), v.maxLength(120)),
  bundle_checksum: v.pipe(v.string(), v.regex(/^[a-f0-9]{64}$/)),
  requested_by: v.pipe(v.string(), v.minLength(1), v.maxLength(64)),
  target_url: NullableString,
  status: v.picklist(['prepared', 'transferring', 'applying', 'succeeded', 'failed']),
  asset_count: v.number(),
  asset_bytes: v.number(),
  assets_copied: v.number(),
  assets_reused: v.number(),
  bytes_copied: v.number(),
  previous_version_id: NullableString,
  applied_version_id: NullableString,
  error_code: NullableString,
  error_message: NullableString,
  started_at: DateTime,
  completed_at: v.nullable(DateTime),
  created_at: DateTime,
  updated_at: v.nullable(DateTime),
})