{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "protobuf-v1-bridge", "title": "Protobuf-ES v1 migration bridge", "description": "Temporary source-copy bridge for staged Protobuf-ES v1 migrations. Install separately from the v2 runtime.", "dependencies": [ "@bufbuild/protobuf@^1.10.1" ], "registryDependencies": [ "@protoform/protoform-core" ], "files": [ { "path": "registry/base-nova/protoform/lib/protobuf-v1-bridge/index.ts", "content": "export {\n createProtobufV1Provider,\n type ProtobufV1Provider,\n type ProtobufV1SchemaValidation,\n} from \"./provider.js\";\n", "type": "registry:lib" }, { "path": "registry/base-nova/protoform/lib/protobuf-v1-bridge/provider.ts", "content": "import {\n type EnumType,\n type FieldInfo,\n LongType,\n type Message,\n type MessageType,\n type OneofInfo,\n type PartialMessage,\n protoBase64,\n ScalarType,\n} from \"@bufbuild/protobuf\";\nimport type {\n FormValues,\n ParsedField,\n ParsedSchema,\n ProviderCustomData,\n SchemaProvider,\n SchemaValidationContext,\n SchemaValidationError,\n} from \"../core/index.js\";\n\ninterface ProtobufV1CustomData extends ProviderCustomData {\n source: \"proto-v1\";\n supportsUnset?: boolean;\n syntax: \"proto2\" | \"proto3\";\n}\n\nexport type ProtobufV1SchemaValidation> =\n | { data: T; success: true }\n | { errors: SchemaValidationError[]; success: false };\n\nexport interface ProtobufV1Provider>\n extends SchemaProvider> {\n createMessage: (values: Record) => T;\n getMessageType: () => MessageType;\n validateSchema: (\n values: Record,\n context?: SchemaValidationContext\n ) => ProtobufV1SchemaValidation;\n}\n\ntype MapField = Extract;\ntype MapValue = MapField[\"V\"];\n\nfunction isRecord(value: unknown): value is Record {\n return Boolean(value && typeof value === \"object\" && !Array.isArray(value));\n}\n\nfunction getSyntax(messageType: MessageType): \"proto2\" | \"proto3\" {\n const { syntax } = messageType.runtime;\n if (syntax !== \"proto2\" && syntax !== \"proto3\") {\n throw new Error(`Unsupported Protobuf-ES v1 syntax: ${syntax}`);\n }\n return syntax;\n}\n\nfunction is64BitScalar(scalar: ScalarType): boolean {\n return (\n scalar === ScalarType.INT64 ||\n scalar === ScalarType.UINT64 ||\n scalar === ScalarType.SINT64 ||\n scalar === ScalarType.FIXED64 ||\n scalar === ScalarType.SFIXED64\n );\n}\n\nfunction scalarFieldType(scalar: ScalarType): string {\n if (scalar === ScalarType.STRING) {\n return \"string\";\n }\n if (scalar === ScalarType.BOOL) {\n return \"boolean\";\n }\n if (scalar === ScalarType.BYTES) {\n return \"bytes\";\n }\n return is64BitScalar(scalar) ? \"int64\" : \"number\";\n}\n\nconst CAMEL_BOUNDARY_PATTERN = /([a-z0-9])([A-Z])/g;\nconst WORD_SEPARATOR_PATTERN = /[_.-]+/g;\nconst WHITESPACE_PATTERN = /\\s+/g;\n\nfunction toScreamingSnakeCase(value: string): string {\n return value\n .replace(CAMEL_BOUNDARY_PATTERN, \"$1_$2\")\n .replace(WORD_SEPARATOR_PATTERN, \"_\")\n .toUpperCase();\n}\n\nfunction humanize(value: string): string {\n return value\n .replace(WORD_SEPARATOR_PATTERN, \" \")\n .replace(WHITESPACE_PATTERN, \" \")\n .trim()\n .toLowerCase()\n .replace(\n /(^|\\s)([a-z])/g,\n (_match, whitespace: string, character: string) =>\n `${whitespace}${character.toUpperCase()}`\n );\n}\n\nfunction enumOptions(enumType: EnumType): [string, string][] {\n const typeName = enumType.typeName.split(\".\").at(-1) ?? \"\";\n const prefix = `${toScreamingSnakeCase(typeName)}_`;\n return enumType.values.map((value) => [\n String(value.no),\n humanize(\n value.name.startsWith(prefix)\n ? value.name.slice(prefix.length)\n : value.name\n ),\n ]);\n}\n\nfunction scalarDefault(scalar: ScalarType): unknown {\n if (scalar === ScalarType.STRING || scalar === ScalarType.BYTES) {\n return \"\";\n }\n if (scalar === ScalarType.BOOL) {\n return false;\n }\n if (is64BitScalar(scalar)) {\n return \"0\";\n }\n return 0;\n}\n\nfunction fieldDeclaredDefault(field: FieldInfo): unknown {\n if (field.repeated || field.kind === \"map\") {\n return [];\n }\n if (field.default !== undefined) {\n if (field.default instanceof Uint8Array) {\n return protoBase64.enc(field.default);\n }\n return typeof field.default === \"bigint\"\n ? field.default.toString()\n : field.default;\n }\n if (field.kind === \"scalar\") {\n return scalarDefault(field.T);\n }\n if (field.kind === \"enum\") {\n return field.T.values[0]?.no ?? 0;\n }\n return;\n}\n\nfunction customData(\n messageType: MessageType,\n supportsUnset: boolean\n): ProtobufV1CustomData {\n return {\n source: \"proto-v1\",\n supportsUnset,\n syntax: getSyntax(messageType),\n };\n}\n\nfunction parsedScalar(\n messageType: MessageType,\n key: string,\n scalar: ScalarType,\n required: boolean,\n defaultValue: unknown,\n supportsUnset: boolean\n): ParsedField {\n return {\n default: defaultValue,\n fieldConfig: { customData: customData(messageType, supportsUnset) },\n hints: supportsUnset ? { supportsUnset: true } : undefined,\n key,\n required,\n type: scalarFieldType(scalar),\n };\n}\n\nfunction parsedEnum(\n messageType: MessageType,\n key: string,\n enumType: EnumType,\n required: boolean,\n defaultValue: unknown,\n supportsUnset: boolean\n): ParsedField {\n return {\n default: defaultValue,\n fieldConfig: { customData: customData(messageType, supportsUnset) },\n hints: supportsUnset ? { supportsUnset: true } : undefined,\n key,\n options: enumOptions(enumType),\n required,\n type: \"select\",\n };\n}\n\nfunction parseSingularField(\n messageType: MessageType,\n field: FieldInfo,\n key: string,\n ancestors: ReadonlySet,\n required = field.req\n): ParsedField {\n const supportsUnset = field.opt || field.req || field.oneof !== undefined;\n if (field.kind === \"scalar\") {\n return parsedScalar(\n messageType,\n key,\n field.T,\n required,\n fieldDeclaredDefault(field),\n supportsUnset\n );\n }\n if (field.kind === \"enum\") {\n return parsedEnum(\n messageType,\n key,\n field.T,\n required,\n fieldDeclaredDefault(field),\n supportsUnset\n );\n }\n if (field.kind === \"message\") {\n if (ancestors.has(field.T.typeName)) {\n return {\n fieldConfig: { customData: customData(messageType, supportsUnset) },\n key,\n required,\n type: \"json\",\n };\n }\n return {\n fieldConfig: { customData: customData(messageType, supportsUnset) },\n hints: supportsUnset ? { supportsUnset: true } : undefined,\n key,\n required,\n schema: parseMessageTypeInternal(field.T, ancestors).fields,\n type: \"object\",\n };\n }\n throw new Error(\n `Cannot parse map field ${field.localName} as a singular value`\n );\n}\n\nfunction parsedMapValue(\n messageType: MessageType,\n value: MapValue,\n ancestors: ReadonlySet\n): ParsedField {\n if (value.kind === \"scalar\") {\n return parsedScalar(\n messageType,\n \"value\",\n value.T,\n false,\n scalarDefault(value.T),\n false\n );\n }\n if (value.kind === \"enum\") {\n return parsedEnum(\n messageType,\n \"value\",\n value.T,\n false,\n value.T.values[0]?.no ?? 0,\n false\n );\n }\n if (ancestors.has(value.T.typeName)) {\n return {\n fieldConfig: { customData: customData(messageType, false) },\n key: \"value\",\n required: false,\n type: \"json\",\n };\n }\n return {\n fieldConfig: { customData: customData(messageType, false) },\n key: \"value\",\n required: false,\n schema: parseMessageTypeInternal(value.T, ancestors).fields,\n type: \"object\",\n };\n}\n\nfunction parseField(\n messageType: MessageType,\n field: FieldInfo,\n ancestors: ReadonlySet\n): ParsedField {\n if (field.kind === \"map\") {\n return {\n default: [],\n fieldConfig: { customData: customData(messageType, false) },\n key: field.localName,\n required: false,\n schema: [\n parsedScalar(\n messageType,\n \"key\",\n field.K,\n true,\n scalarDefault(field.K),\n false\n ),\n parsedMapValue(messageType, field.V, ancestors),\n ],\n type: \"map\",\n };\n }\n if (field.repeated) {\n return {\n default: [],\n fieldConfig: { customData: customData(messageType, false) },\n key: field.localName,\n required: false,\n schema: [\n parseSingularField(messageType, field, \"value\", ancestors, false),\n ],\n type: \"array\",\n };\n }\n return parseSingularField(messageType, field, field.localName, ancestors);\n}\n\nfunction parseOneof(\n messageType: MessageType,\n oneof: OneofInfo,\n ancestors: ReadonlySet\n): ParsedField {\n return {\n default: { case: undefined, value: undefined },\n fieldConfig: { customData: customData(messageType, true) },\n hints: { supportsUnset: true },\n key: oneof.localName,\n required: false,\n schema: oneof.fields.map((field) =>\n parseSingularField(messageType, field, field.localName, ancestors, false)\n ),\n type: \"oneof\",\n };\n}\n\nfunction parseMessageTypeInternal(\n messageType: MessageType,\n ancestors: ReadonlySet\n): ParsedSchema {\n getSyntax(messageType);\n const nextAncestors = new Set([...ancestors, messageType.typeName]);\n return {\n fields: messageType.fields\n .byMember()\n .map((member) =>\n member.kind === \"oneof\"\n ? parseOneof(messageType, member, nextAncestors)\n : parseField(messageType, member, nextAncestors)\n ),\n };\n}\n\nfunction parseMessageType>(\n messageType: MessageType\n): ParsedSchema {\n return parseMessageTypeInternal(messageType, new Set());\n}\n\nfunction normalizeScalarValue(\n scalar: ScalarType,\n longType: LongType,\n value: unknown\n): unknown {\n if (value === undefined || value === null) {\n return;\n }\n if (scalar === ScalarType.STRING) {\n return typeof value === \"string\" ? value : String(value);\n }\n if (scalar === ScalarType.BOOL) {\n return normalizeBooleanValue(value);\n }\n if (scalar === ScalarType.BYTES) {\n return normalizeBytesValue(value);\n }\n if (is64BitScalar(scalar)) {\n return normalizeLongValue(value, longType);\n }\n return normalizeNumberValue(value);\n}\n\nfunction normalizeBooleanValue(value: unknown): boolean | undefined {\n if (typeof value === \"boolean\") {\n return value;\n }\n if (value === \"true\") {\n return true;\n }\n if (value === \"false\") {\n return false;\n }\n return value === \"\" ? undefined : Boolean(value);\n}\n\nfunction normalizeBytesValue(value: unknown): Uint8Array | undefined {\n if (value instanceof Uint8Array) {\n return value;\n }\n return typeof value === \"string\" && value !== \"\"\n ? protoBase64.dec(value)\n : undefined;\n}\n\nfunction normalizeLongValue(\n value: unknown,\n longType: LongType\n): bigint | string | undefined {\n if (value === \"\") {\n return;\n }\n if (longType === LongType.STRING) {\n return String(value);\n }\n return typeof value === \"bigint\" ? value : BigInt(String(value));\n}\n\nfunction normalizeNumberValue(value: unknown): number | undefined {\n if (value === \"\") {\n return;\n }\n const numberValue = Number(value);\n return Number.isNaN(numberValue) ? undefined : numberValue;\n}\n\nfunction normalizeMapValue(valueType: MapValue, value: unknown): unknown {\n if (valueType.kind === \"scalar\") {\n return normalizeScalarValue(valueType.T, LongType.BIGINT, value);\n }\n if (valueType.kind === \"enum\") {\n return value === undefined || value === \"\" ? undefined : Number(value);\n }\n return isRecord(value)\n ? new valueType.T(messageInit(valueType.T, value))\n : undefined;\n}\n\nfunction normalizeSingularField(field: FieldInfo, value: unknown): unknown {\n if (field.kind === \"scalar\") {\n return normalizeScalarValue(field.T, field.L, value);\n }\n if (field.kind === \"enum\") {\n return value === undefined || value === \"\" ? undefined : Number(value);\n }\n if (field.kind === \"message\") {\n return isRecord(value)\n ? new field.T(messageInit(field.T, value))\n : undefined;\n }\n if (!Array.isArray(value)) {\n return {};\n }\n return Object.fromEntries(\n value.flatMap((entry) => {\n if (!isRecord(entry)) {\n return [];\n }\n const { key } = entry;\n if (key === undefined || key === null || key === \"\") {\n return [];\n }\n return [[String(key), normalizeMapValue(field.V, entry.value)] as const];\n })\n );\n}\n\nfunction normalizeField(field: FieldInfo, value: unknown): unknown {\n if (field.kind === \"map\") {\n return normalizeSingularField(field, value);\n }\n if (field.repeated) {\n return Array.isArray(value)\n ? value.map((entry) => normalizeSingularField(field, entry))\n : [];\n }\n return normalizeSingularField(field, value);\n}\n\nfunction messageInit>(\n messageType: MessageType,\n values: Record\n): PartialMessage;\nfunction messageInit(\n messageType: MessageType,\n values: Record\n): PartialMessage;\nfunction messageInit(\n messageType: MessageType,\n values: Record\n): PartialMessage {\n const init: Record = {};\n for (const member of messageType.fields.byMember()) {\n if (member.kind === \"oneof\") {\n const oneofValue = values[member.localName];\n if (!(isRecord(oneofValue) && typeof oneofValue.case === \"string\")) {\n continue;\n }\n const activeField = member.findField(oneofValue.case);\n if (!activeField) {\n continue;\n }\n init[member.localName] = {\n case: activeField.localName,\n value: normalizeSingularField(activeField, oneofValue.value),\n };\n continue;\n }\n const value = normalizeField(member, values[member.localName]);\n if (value !== undefined) {\n init[member.localName] = value;\n }\n }\n return init as PartialMessage;\n}\n\nfunction scalarToFormValue(scalar: ScalarType, value: unknown): unknown {\n if (scalar === ScalarType.BYTES) {\n return value instanceof Uint8Array ? protoBase64.enc(value) : undefined;\n }\n if (is64BitScalar(scalar)) {\n return typeof value === \"bigint\" ? value.toString() : value;\n }\n return value;\n}\n\nfunction mapValueToFormValue(valueType: MapValue, value: unknown): unknown {\n if (valueType.kind === \"scalar\") {\n return scalarToFormValue(valueType.T, value);\n }\n if (valueType.kind === \"message\" && isRecord(value)) {\n return messageToFormValues(valueType.T, value);\n }\n return value;\n}\n\nfunction singularFieldToFormValue(field: FieldInfo, value: unknown): unknown {\n if (field.kind === \"scalar\") {\n return scalarToFormValue(field.T, value);\n }\n if (field.kind === \"enum\") {\n return value;\n }\n if (field.kind === \"message\") {\n return isRecord(value) ? messageToFormValues(field.T, value) : undefined;\n }\n if (!isRecord(value)) {\n return [];\n }\n return Object.entries(value).map(([key, entryValue]) => ({\n key,\n value: mapValueToFormValue(field.V, entryValue),\n }));\n}\n\nfunction fieldToFormValue(field: FieldInfo, value: unknown): unknown {\n if (field.kind === \"map\") {\n return singularFieldToFormValue(field, value);\n }\n if (field.repeated) {\n return Array.isArray(value)\n ? value.map((entry) => singularFieldToFormValue(field, entry))\n : [];\n }\n return singularFieldToFormValue(field, value);\n}\n\nfunction oneofToFormValue(\n oneof: OneofInfo,\n value: unknown\n): { case: string | undefined; value?: unknown } {\n if (!(isRecord(value) && typeof value.case === \"string\")) {\n return { case: undefined };\n }\n const activeField = oneof.findField(value.case);\n if (!activeField) {\n return { case: undefined };\n }\n return {\n case: activeField.localName,\n value: singularFieldToFormValue(activeField, value.value),\n };\n}\n\nfunction messageToFormValues(\n messageType: MessageType,\n message: Record\n): FormValues {\n const syntax = getSyntax(messageType);\n return Object.fromEntries(\n messageType.fields.byMember().map((member) => {\n if (member.kind === \"oneof\") {\n return [\n member.localName,\n oneofToFormValue(member, message[member.localName]),\n ];\n }\n const value = message[member.localName];\n return [\n member.localName,\n syntax === \"proto2\" && member.req && value === undefined\n ? fieldDeclaredDefault(member)\n : fieldToFormValue(member, value),\n ];\n })\n );\n}\n\nconst SIGNED_32_SCALARS = new Set([\n ScalarType.INT32,\n ScalarType.SINT32,\n ScalarType.SFIXED32,\n]);\nconst UNSIGNED_32_SCALARS = new Set([ScalarType.UINT32, ScalarType.FIXED32]);\nconst SIGNED_64_SCALARS = new Set([\n ScalarType.INT64,\n ScalarType.SINT64,\n ScalarType.SFIXED64,\n]);\nconst UNSIGNED_64_SCALARS = new Set([ScalarType.UINT64, ScalarType.FIXED64]);\nconst SIGNED_32_MIN = -2_147_483_648;\nconst SIGNED_32_MAX = 2_147_483_647;\nconst UNSIGNED_32_MAX = 4_294_967_295;\nconst SIGNED_64_MIN = -9_223_372_036_854_775_808n;\nconst SIGNED_64_MAX = 9_223_372_036_854_775_807n;\nconst UNSIGNED_64_MAX = 18_446_744_073_709_551_615n;\n\nfunction isEmpty(value: unknown): boolean {\n return value === undefined || value === null || value === \"\";\n}\n\nfunction scalarConversionIssue(\n scalar: ScalarType,\n value: unknown\n): string | undefined {\n if (isEmpty(value) || scalar === ScalarType.STRING) {\n return;\n }\n if (scalar === ScalarType.BOOL) {\n return booleanConversionIssue(value);\n }\n if (scalar === ScalarType.BYTES) {\n return bytesConversionIssue(value);\n }\n if (is64BitScalar(scalar)) {\n return longConversionIssue(scalar, value);\n }\n return numberConversionIssue(scalar, value);\n}\n\nfunction booleanConversionIssue(value: unknown): string | undefined {\n return typeof value === \"boolean\" || value === \"true\" || value === \"false\"\n ? undefined\n : \"Choose true or false.\";\n}\n\nfunction bytesConversionIssue(value: unknown): string | undefined {\n if (value instanceof Uint8Array) {\n return;\n }\n if (typeof value !== \"string\") {\n return \"Enter valid base64 data.\";\n }\n try {\n protoBase64.dec(value);\n return;\n } catch {\n return \"Enter valid base64 data.\";\n }\n}\n\nfunction longConversionIssue(\n scalar: ScalarType,\n value: unknown\n): string | undefined {\n let integer: bigint;\n try {\n integer = typeof value === \"bigint\" ? value : BigInt(String(value));\n } catch {\n return \"Enter a valid 64-bit integer.\";\n }\n const outsideSignedRange =\n SIGNED_64_SCALARS.has(scalar) &&\n (integer < SIGNED_64_MIN || integer > SIGNED_64_MAX);\n const outsideUnsignedRange =\n UNSIGNED_64_SCALARS.has(scalar) &&\n (integer < 0n || integer > UNSIGNED_64_MAX);\n return outsideSignedRange || outsideUnsignedRange\n ? \"Enter a 64-bit integer within the protobuf range.\"\n : undefined;\n}\n\nfunction numberConversionIssue(\n scalar: ScalarType,\n value: unknown\n): string | undefined {\n const numberValue = Number(value);\n if (!Number.isFinite(numberValue)) {\n return \"Enter a valid number.\";\n }\n if (\n (SIGNED_32_SCALARS.has(scalar) || UNSIGNED_32_SCALARS.has(scalar)) &&\n !Number.isInteger(numberValue)\n ) {\n return \"Enter a whole number.\";\n }\n if (\n (SIGNED_32_SCALARS.has(scalar) &&\n (numberValue < SIGNED_32_MIN || numberValue > SIGNED_32_MAX)) ||\n (UNSIGNED_32_SCALARS.has(scalar) &&\n (numberValue < 0 || numberValue > UNSIGNED_32_MAX))\n ) {\n return \"Enter a number within the protobuf range.\";\n }\n return;\n}\n\nfunction singularConversionErrors(\n messageType: MessageType,\n field: FieldInfo,\n value: unknown,\n path: (string | number)[]\n): SchemaValidationError[] {\n if (field.kind === \"scalar\") {\n const message = scalarConversionIssue(field.T, value);\n return message ? [{ message, path }] : [];\n }\n if (field.kind === \"enum\") {\n if (isEmpty(value)) {\n return [];\n }\n const numberValue = Number(value);\n if (!Number.isInteger(numberValue)) {\n return [{ message: \"Choose a valid enum value.\", path }];\n }\n if (\n getSyntax(messageType) === \"proto2\" &&\n !field.T.values.some((candidate) => candidate.no === numberValue)\n ) {\n return [{ message: \"Choose a known enum value.\", path }];\n }\n return [];\n }\n if (field.kind === \"message\") {\n if (isEmpty(value)) {\n return [];\n }\n return isRecord(value)\n ? messageConversionErrors(field.T, value, path)\n : [{ message: \"Enter an object value.\", path }];\n }\n return mapConversionErrors(messageType, field, value, path);\n}\n\nfunction mapValueConversionErrors(\n messageType: MessageType,\n valueType: MapValue,\n value: unknown,\n path: (string | number)[]\n): SchemaValidationError[] {\n if (valueType.kind === \"scalar\") {\n const message = scalarConversionIssue(valueType.T, value);\n return message ? [{ message, path }] : [];\n }\n if (valueType.kind === \"enum\") {\n if (isEmpty(value)) {\n return [];\n }\n const numberValue = Number(value);\n if (!Number.isInteger(numberValue)) {\n return [{ message: \"Choose a valid enum value.\", path }];\n }\n if (\n getSyntax(messageType) === \"proto2\" &&\n !valueType.T.values.some((candidate) => candidate.no === numberValue)\n ) {\n return [{ message: \"Choose a known enum value.\", path }];\n }\n return [];\n }\n if (isEmpty(value)) {\n return [];\n }\n return isRecord(value)\n ? messageConversionErrors(valueType.T, value, path)\n : [{ message: \"Enter an object value.\", path }];\n}\n\nfunction mapConversionErrors(\n messageType: MessageType,\n field: MapField,\n value: unknown,\n path: (string | number)[]\n): SchemaValidationError[] {\n if (isEmpty(value)) {\n return [];\n }\n if (!Array.isArray(value)) {\n return [{ message: \"Enter map entries as key-value pairs.\", path }];\n }\n const errors: SchemaValidationError[] = [];\n const seenKeys = new Set();\n value.forEach((entry, index) => {\n if (!isRecord(entry)) {\n errors.push({\n message: \"Enter a key-value pair.\",\n path: [...path, index],\n });\n return;\n }\n const { key } = entry;\n if (isEmpty(key)) {\n return;\n }\n const keyString = String(key);\n if (seenKeys.has(keyString)) {\n errors.push({ message: \"Map keys must be unique.\", path });\n } else {\n seenKeys.add(keyString);\n }\n errors.push(\n ...mapValueConversionErrors(messageType, field.V, entry.value, [\n ...path,\n index,\n \"value\",\n ])\n );\n });\n return errors;\n}\n\nfunction fieldConversionErrors(\n messageType: MessageType,\n field: FieldInfo,\n value: unknown,\n path: (string | number)[]\n): SchemaValidationError[] {\n if (field.kind === \"map\") {\n return mapConversionErrors(messageType, field, value, path);\n }\n if (field.repeated) {\n if (isEmpty(value)) {\n return [];\n }\n if (!Array.isArray(value)) {\n return [{ message: \"Enter a list of values.\", path }];\n }\n return value.flatMap((entry, index) =>\n singularConversionErrors(messageType, field, entry, [...path, index])\n );\n }\n return singularConversionErrors(messageType, field, value, path);\n}\n\nfunction messageConversionErrors(\n messageType: MessageType,\n values: Record,\n path: (string | number)[] = []\n): SchemaValidationError[] {\n return messageType.fields.byMember().flatMap((member) => {\n if (member.kind === \"oneof\") {\n const oneofValue = values[member.localName];\n if (isEmpty(oneofValue)) {\n return [];\n }\n if (!isRecord(oneofValue)) {\n return [\n {\n message: \"Choose a valid oneof field.\",\n path: [...path, member.localName],\n },\n ];\n }\n if (oneofValue.case === undefined) {\n return [];\n }\n if (typeof oneofValue.case !== \"string\") {\n return [\n {\n message: \"Choose a valid oneof field.\",\n path: [...path, member.localName],\n },\n ];\n }\n const activeField = member.findField(oneofValue.case);\n return activeField\n ? singularConversionErrors(messageType, activeField, oneofValue.value, [\n ...path,\n member.localName,\n \"value\",\n ])\n : [\n {\n message: \"Choose a known oneof field.\",\n path: [...path, member.localName],\n },\n ];\n }\n const value = values[member.localName];\n const requiredError =\n member.req && isEmpty(value)\n ? [\n {\n message: \"This field is required.\",\n path: [...path, member.localName],\n },\n ]\n : [];\n return [\n ...requiredError,\n ...fieldConversionErrors(messageType, member, value, [\n ...path,\n member.localName,\n ]),\n ];\n });\n}\n\nclass ProtobufV1ProviderImpl>\n implements ProtobufV1Provider\n{\n readonly #messageType: MessageType;\n readonly #parsedSchema: ParsedSchema;\n\n constructor(messageType: MessageType) {\n this.#messageType = messageType;\n this.#parsedSchema = parseMessageType(messageType);\n }\n\n createMessage(values: Record): T {\n return new this.#messageType(messageInit(this.#messageType, values));\n }\n\n getDefaultValues(): FormValues {\n const message = new this.#messageType() as unknown as Record<\n string,\n unknown\n >;\n return messageToFormValues(this.#messageType, message);\n }\n\n getMessageType(): MessageType {\n return this.#messageType;\n }\n\n parseSchema(): ParsedSchema {\n return this.#parsedSchema;\n }\n\n validateSchema(\n values: Record,\n context?: SchemaValidationContext\n ): ProtobufV1SchemaValidation {\n if (context?.signal.aborted) {\n return {\n errors: [{ message: \"Validation was cancelled.\", path: [] }],\n success: false,\n };\n }\n const errors = messageConversionErrors(this.#messageType, values);\n if (errors.length > 0) {\n return { errors, success: false };\n }\n try {\n return { data: this.createMessage(values), success: true };\n } catch (error) {\n return {\n errors: [\n {\n message:\n error instanceof Error\n ? error.message\n : \"Failed to create a Protobuf-ES v1 message.\",\n path: [],\n },\n ],\n success: false,\n };\n }\n }\n}\n\nexport function createProtobufV1Provider>(\n messageType: MessageType\n): ProtobufV1Provider {\n return new ProtobufV1ProviderImpl(messageType);\n}\n", "type": "registry:lib" } ], "type": "registry:lib" }