import { CompositeSliceLegacySchema, SharedSliceLegacySchema } from "../legacy/slice" import type { CompositeSliceLegacy, SharedSliceLegacy, LegacySliceLegacy, SliceLegacy, } from "../legacy/slice" import { CompositeSliceContentSchema, CompositeSliceContentType, SharedSliceContentSchema, SharedSliceContentType, LegacySliceContentSchema, SliceContentSchema, } from "../slice" import type { CompositeSliceContent, SharedSliceContent, LegacySliceContent, SliceContent, } from "../slice" import { GroupItemLegacyCodec, NestableAndGroupLegacyCodec } from "./group" import { getFieldCtx, type LegacyCodec, type LegacyContentCtx } from "./legacyContentCtx" import { NestableLegacyCodec } from "./nestable" // Simple (before 2020) export const LegacySliceLegacyCodec = ( ctx: LegacyContentCtx, ): LegacyCodec => ({ name: "LegacySliceLegacy", is(input): input is LegacySliceContent { return LegacySliceContentSchema.safeParse(input).success }, toContent(input) { return NestableAndGroupLegacyCodec(ctx).toContent(input) }, fromContent(input) { return NestableAndGroupLegacyCodec(ctx).fromContent(input) }, }) // Composite (2020 to 2021) export const CompositeSliceLegacyCodec = ( ctx: LegacyContentCtx, ): LegacyCodec => ({ name: "CompositeSliceLegacy", is(input): input is CompositeSliceContent { return CompositeSliceContentSchema.safeParse(input).success }, toContent(input) { const parsed = CompositeSliceLegacySchema.safeParse(input) if (!parsed.success) { return parsed } const nonRepeat: CompositeSliceContent["nonRepeat"] = {} for (const [key, legacy] of Object.entries(parsed.data["non-repeat"] || {})) { const fieldCtx = getFieldCtx({ fieldKey: key, ctx, prefixes: ["non-repeat"], }) const result = NestableLegacyCodec(fieldCtx).toContent(legacy) if (!result.success) continue nonRepeat[key] = result.data } const repeat: CompositeSliceContent["repeat"] = [] for (let index = 0; index < (parsed.data.repeat?.length || 0); index++) { const item = parsed.data.repeat?.[index] const itemCtx = getFieldCtx({ fieldKey: "repeat", ctx }) const result = GroupItemLegacyCodec(itemCtx, index).toContent(item) if (!result.success) continue repeat.push(result.data) } return { success: true, data: { __TYPE__: CompositeSliceContentType, nonRepeat, repeat, }, } }, fromContent(input) { const legacy: ReturnType< LegacyCodec["fromContent"] > = { content: { "non-repeat": {}, repeat: [], }, types: { [ctx.keyOfType]: "Slice", }, keys: {}, } // Non-repeat for (const [key, content] of Object.entries(input.nonRepeat)) { const fieldCtx = getFieldCtx({ fieldKey: key, ctx, prefixes: ["non-repeat"], }) const result = NestableLegacyCodec(fieldCtx).fromContent(content) if (!result) continue legacy.content["non-repeat"]![key] = result.content legacy.types = { ...legacy.types, ...result.types } legacy.keys = { ...legacy.keys, ...result.keys } } // Repeat const repeatCtx = getFieldCtx({ fieldKey: "repeat", ctx }) for (let index = 0; index < input.repeat.length; index++) { const item = input.repeat[index] const result = GroupItemLegacyCodec(repeatCtx, index).fromContent(item) legacy.content.repeat!.push(result.content) legacy.types = { ...legacy.types, ...result.types } legacy.keys = { ...legacy.keys, ...result.keys } } return legacy }, }) // Shared (2021 to present) export const SharedSliceLegacyCodec = ( ctx: LegacyContentCtx, ): LegacyCodec => ({ name: "SharedSliceLegacy", is(input): input is SharedSliceContent { return SharedSliceContentSchema.safeParse(input).success }, toContent(input) { const parsed = SharedSliceLegacySchema.safeParse(input) if (!parsed.success) { return parsed } const primary: SharedSliceContent["primary"] = {} for (const [key, legacy] of Object.entries(parsed.data["primary"])) { const fieldCtx = getFieldCtx({ fieldKey: key, ctx, prefixes: ["variations", parsed.data.variation, "primary"], }) const result = NestableAndGroupLegacyCodec(fieldCtx).toContent(legacy) if (!result.success) continue primary[key] = result.data } const items: SharedSliceContent["items"] = [] for (let index = 0; index < parsed.data.items.length; index++) { const item = parsed.data.items[index] const itemCtx = getFieldCtx({ fieldKey: "items", ctx, prefixes: ["variations", parsed.data.variation], }) const result = GroupItemLegacyCodec(itemCtx, index).toContent(item) if (!result.success) continue items.push(result.data) } return { success: true, data: { __TYPE__: SharedSliceContentType, variation: parsed.data.variation, primary, items, }, } }, fromContent(input) { const legacy: ReturnType["fromContent"]> = { content: { primary: {}, items: [], variation: input.variation, }, types: { [ctx.keyOfType]: "SharedSlice", }, keys: {}, } // Primary for (const [key, content] of Object.entries(input.primary)) { const fieldCtx = getFieldCtx({ fieldKey: key, ctx, prefixes: ["variations", input.variation, "primary"], }) const result = NestableAndGroupLegacyCodec(fieldCtx).fromContent(content) if (!result) continue legacy.content.primary[key] = result.content legacy.types = { ...legacy.types, ...result.types } legacy.keys = { ...legacy.keys, ...result.keys } } // Items const repeatCtx = getFieldCtx({ fieldKey: "items", ctx, prefixes: ["variations", input.variation], }) for (let index = 0; index < input.items.length; index++) { const item = input.items[index] const result = GroupItemLegacyCodec(repeatCtx, index).fromContent(item) legacy.content.items.push(result.content) legacy.types = { ...legacy.types, ...result.types } legacy.keys = { ...legacy.keys, ...result.keys } } return legacy }, }) // All export const SliceLegacyCodec = ( ctx: LegacyContentCtx, ): LegacyCodec => ({ name: "SliceLegacy", is(input): input is SliceContent { return SliceContentSchema.safeParse(input).success }, toContent(input) { switch (ctx.fieldType) { case "Slice": return CompositeSliceLegacyCodec(ctx).toContent(input) case "SharedSlice": return SharedSliceLegacyCodec(ctx).toContent(input) default: return LegacySliceLegacyCodec(ctx).toContent(input) } }, fromContent(input) { switch (input.__TYPE__) { case CompositeSliceContentType: return CompositeSliceLegacyCodec(ctx).fromContent(input) case SharedSliceContentType: return SharedSliceLegacyCodec(ctx).fromContent(input) default: return LegacySliceLegacyCodec(ctx).fromContent(input) } }, })