{"version":3,"file":"parse-object.mjs","names":[],"sources":["../../../src/common/schema/parse-object.ts"],"sourcesContent":["import type { Type } from './schema'\nimport { arrayMinus, isFunction, valueToBoolean, valueToFloat, valueToInteger, valueToString } from '../data'\n\nexport function schemaCreateObject<T>(schema: Type<T>): Partial<T> | undefined {\n  if (schema._default !== undefined) {\n    return isFunction(schema._default) ? schema._default(schema) : schema._default\n  }\n\n  if (schema._optional) {\n    return undefined as any\n  }\n\n  if (schema._object) {\n    const obj: any = {}\n    for (const key in schema._object) {\n      const propSchema = schema._object[key] as Type<any>\n      const value = schemaCreateObject(propSchema)\n      if (value !== undefined) {\n        obj[key] = value\n      }\n    }\n    return obj\n  }\n\n  // For non-optional, non-object types without defaults, don't return anything\n  // This prevents setting undefined values in the parent object\n  return undefined\n}\n\n/**\n * Message for schema validation results.\n * @category Schema\n */\nexport interface SchemaValidateMessage {\n  path: string\n  message: string\n  type: string\n  valid: boolean\n}\n\nexport function schemaValidateObject<T>(schema: Type<T>, obj?: any, opt?: {\n  path?: string\n  messages?: SchemaValidateMessage[]\n  allowExtra?: boolean\n}): boolean {\n  const messages = opt?.messages || []\n\n  function addMessage(message: string, valid: boolean = false) {\n    messages.push({ path: `.${opt?.path ?? ''}`, message, valid, type: schema.type })\n    return valid\n  }\n\n  if (obj == null && schema._optional) {\n    return addMessage('Optional', true)\n  }\n\n  if (schema._object) {\n    if (opt?.allowExtra !== true) {\n      const schemaKeys = Object.keys(schema._object)\n      const objKeys = Object.keys(obj || {})\n      const missingKeys = arrayMinus(objKeys, schemaKeys)\n      if (missingKeys.length > 0) {\n        return addMessage(`Extra properties: ${missingKeys.join(', ')}`, false)\n      }\n    }\n\n    for (const key in schema._object) {\n      const propSchema = schema._object[key] as any\n      if (!schemaValidateObject(\n        propSchema,\n        obj[key] as any,\n        {\n          ...opt,\n          path: opt?.path ? `${opt.path}.${key}` : key,\n          messages,\n        },\n      )) { return addMessage(`Invalid property '${key}'`, false) }\n    }\n    return addMessage('Object valid', true)\n  }\n\n  if (isFunction(schema._check)) {\n    const checkResult = schema._check(obj)\n    return addMessage('Check', checkResult)\n  }\n\n  return addMessage('Primitive valid', false)\n}\n\nexport function schemaParseObject<T>(schema: Type<T>, obj?: any, opt?: {\n  path?: string\n  messages?: SchemaValidateMessage[]\n\n  /// Whether to allow extra properties not defined in the schema\n  allowExtra?: boolean\n  skipDefault?: boolean\n}): T | undefined {\n  const messages = opt?.messages || []\n\n  function addMessage(message: string, valid: boolean = false) {\n    messages.push({ path: `.${opt?.path ?? ''}`, message, valid, type: schema.type })\n    // console.debug({ path: `.${opt?.path ?? ''}`, message, valid, type: schema.type }, obj)\n    return valid\n  }\n\n  if (obj == null) {\n    if (schema._optional) {\n      addMessage('Optional', true)\n      return undefined\n    }\n    if (schema._default !== undefined && opt?.skipDefault !== true) {\n      addMessage('Default', true)\n      return isFunction(schema._default) ? schema._default(schema) : schema._default\n    }\n    // For non-optional objects without explicit defaults, use empty object\n    if (schema._object) {\n      obj = {}\n    }\n  }\n\n  if (schema._object) {\n    const newObj: any = {}\n    const shape = schema._object\n    for (const key in shape) {\n      const propSchema = shape[key] as any\n      const result = schemaParseObject(propSchema, obj[key] as any, {\n        ...opt,\n        path: opt?.path ? `${opt.path}.${key}` : key,\n        messages,\n      })\n      if (result !== undefined) {\n        newObj[key] = result\n      }\n      else if (propSchema._default !== undefined && opt?.skipDefault !== true) {\n        newObj[key] = isFunction(propSchema._default) ? propSchema._default(propSchema) : propSchema._default\n      }\n      else if (propSchema._optional) {\n        // Only set undefined for optional properties if they were explicitly provided as undefined\n        if (obj && typeof obj === 'object' && key in obj) {\n          newObj[key] = undefined\n        }\n        // Otherwise, don't set the property at all\n      }\n      // For required properties without defaults, don't set undefined - leave them missing\n    }\n\n    // Add extra properties if allowExtra is enabled\n    if (opt?.allowExtra && obj && typeof obj === 'object') {\n      for (const [key, value] of Object.entries(obj)) {\n        if (!(key in shape)) {\n          newObj[key] = value\n        }\n      }\n    }\n\n    return newObj\n  }\n\n  if (obj != null) {\n    if (schema.type === 'string') {\n      obj = valueToString(obj)\n    }\n    else if (schema.type === 'boolean') {\n      obj = valueToBoolean(obj)\n    }\n    else if (schema.type === 'number') {\n      obj = valueToFloat(obj)\n      if (Number.isNaN(obj)) {\n        addMessage(`Invalid number: ${obj}`, false)\n        return undefined\n      }\n    }\n    else if (schema.type === 'int') {\n      obj = valueToInteger(obj)\n      if (Number.isNaN(obj)) {\n        addMessage(`Invalid number: ${obj}`, false)\n        return undefined\n      }\n    }\n  }\n\n  if (isFunction(schema._check)) {\n    const checkResult = schema._check(obj)\n    addMessage('Check', checkResult)\n    return checkResult ? obj : undefined\n  }\n\n  return obj\n}\n"],"mappings":"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"}