Adjust European short trip heuristic from >3 days to >1 day to correctly detect when user has returned home from European trips. This fixes the April 29-30, 2023 case where the location incorrectly showed "Sankt Georg, Hamburg" instead of "Bristol" when the user was free (no events scheduled) after the foss-north trip ended on April 27. The previous logic required more than 3 days to pass before assuming return home from European countries, but for short European trips by rail/ferry, users typically return within 1-2 days. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
136 lines
4.3 KiB
TypeScript
136 lines
4.3 KiB
TypeScript
import type {AnySchema} from "../../types"
|
|
import type {SchemaObjCxt} from ".."
|
|
import {_, str, getProperty, Code, Name} from "../codegen"
|
|
import {escapeFragment, getErrorPath, Type} from "../util"
|
|
import type {JSONType} from "../rules"
|
|
|
|
export interface SubschemaContext {
|
|
// TODO use Optional? align with SchemCxt property types
|
|
schema: AnySchema
|
|
schemaPath: Code
|
|
errSchemaPath: string
|
|
topSchemaRef?: Code
|
|
errorPath?: Code
|
|
dataLevel?: number
|
|
dataTypes?: JSONType[]
|
|
data?: Name
|
|
parentData?: Name
|
|
parentDataProperty?: Code | number
|
|
dataNames?: Name[]
|
|
dataPathArr?: (Code | number)[]
|
|
propertyName?: Name
|
|
jtdDiscriminator?: string
|
|
jtdMetadata?: boolean
|
|
compositeRule?: true
|
|
createErrors?: boolean
|
|
allErrors?: boolean
|
|
}
|
|
|
|
export type SubschemaArgs = Partial<{
|
|
keyword: string
|
|
schemaProp: string | number
|
|
schema: AnySchema
|
|
schemaPath: Code
|
|
errSchemaPath: string
|
|
topSchemaRef: Code
|
|
data: Name | Code
|
|
dataProp: Code | string | number
|
|
dataTypes: JSONType[]
|
|
definedProperties: Set<string>
|
|
propertyName: Name
|
|
dataPropType: Type
|
|
jtdDiscriminator: string
|
|
jtdMetadata: boolean
|
|
compositeRule: true
|
|
createErrors: boolean
|
|
allErrors: boolean
|
|
}>
|
|
|
|
export function getSubschema(
|
|
it: SchemaObjCxt,
|
|
{keyword, schemaProp, schema, schemaPath, errSchemaPath, topSchemaRef}: SubschemaArgs
|
|
): SubschemaContext {
|
|
if (keyword !== undefined && schema !== undefined) {
|
|
throw new Error('both "keyword" and "schema" passed, only one allowed')
|
|
}
|
|
|
|
if (keyword !== undefined) {
|
|
const sch = it.schema[keyword]
|
|
return schemaProp === undefined
|
|
? {
|
|
schema: sch,
|
|
schemaPath: _`${it.schemaPath}${getProperty(keyword)}`,
|
|
errSchemaPath: `${it.errSchemaPath}/${keyword}`,
|
|
}
|
|
: {
|
|
schema: sch[schemaProp],
|
|
schemaPath: _`${it.schemaPath}${getProperty(keyword)}${getProperty(schemaProp)}`,
|
|
errSchemaPath: `${it.errSchemaPath}/${keyword}/${escapeFragment(schemaProp)}`,
|
|
}
|
|
}
|
|
|
|
if (schema !== undefined) {
|
|
if (schemaPath === undefined || errSchemaPath === undefined || topSchemaRef === undefined) {
|
|
throw new Error('"schemaPath", "errSchemaPath" and "topSchemaRef" are required with "schema"')
|
|
}
|
|
return {
|
|
schema,
|
|
schemaPath,
|
|
topSchemaRef,
|
|
errSchemaPath,
|
|
}
|
|
}
|
|
|
|
throw new Error('either "keyword" or "schema" must be passed')
|
|
}
|
|
|
|
export function extendSubschemaData(
|
|
subschema: SubschemaContext,
|
|
it: SchemaObjCxt,
|
|
{dataProp, dataPropType: dpType, data, dataTypes, propertyName}: SubschemaArgs
|
|
): void {
|
|
if (data !== undefined && dataProp !== undefined) {
|
|
throw new Error('both "data" and "dataProp" passed, only one allowed')
|
|
}
|
|
|
|
const {gen} = it
|
|
|
|
if (dataProp !== undefined) {
|
|
const {errorPath, dataPathArr, opts} = it
|
|
const nextData = gen.let("data", _`${it.data}${getProperty(dataProp)}`, true)
|
|
dataContextProps(nextData)
|
|
subschema.errorPath = str`${errorPath}${getErrorPath(dataProp, dpType, opts.jsPropertySyntax)}`
|
|
subschema.parentDataProperty = _`${dataProp}`
|
|
subschema.dataPathArr = [...dataPathArr, subschema.parentDataProperty]
|
|
}
|
|
|
|
if (data !== undefined) {
|
|
const nextData = data instanceof Name ? data : gen.let("data", data, true) // replaceable if used once?
|
|
dataContextProps(nextData)
|
|
if (propertyName !== undefined) subschema.propertyName = propertyName
|
|
// TODO something is possibly wrong here with not changing parentDataProperty and not appending dataPathArr
|
|
}
|
|
|
|
if (dataTypes) subschema.dataTypes = dataTypes
|
|
|
|
function dataContextProps(_nextData: Name): void {
|
|
subschema.data = _nextData
|
|
subschema.dataLevel = it.dataLevel + 1
|
|
subschema.dataTypes = []
|
|
it.definedProperties = new Set<string>()
|
|
subschema.parentData = it.data
|
|
subschema.dataNames = [...it.dataNames, _nextData]
|
|
}
|
|
}
|
|
|
|
export function extendSubschemaMode(
|
|
subschema: SubschemaContext,
|
|
{jtdDiscriminator, jtdMetadata, compositeRule, createErrors, allErrors}: SubschemaArgs
|
|
): void {
|
|
if (compositeRule !== undefined) subschema.compositeRule = compositeRule
|
|
if (createErrors !== undefined) subschema.createErrors = createErrors
|
|
if (allErrors !== undefined) subschema.allErrors = allErrors
|
|
subschema.jtdDiscriminator = jtdDiscriminator // not inherited
|
|
subschema.jtdMetadata = jtdMetadata // not inherited
|
|
}
|