Fix European trip return heuristic for weekend location tracking
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>
This commit is contained in:
parent
663dc479c2
commit
ea4980a5d7
6407 changed files with 1072847 additions and 18 deletions
120
node_modules/ajv/lib/vocabularies/format/format.ts
generated
vendored
Normal file
120
node_modules/ajv/lib/vocabularies/format/format.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
import type {
|
||||
AddedFormat,
|
||||
FormatValidator,
|
||||
AsyncFormatValidator,
|
||||
CodeKeywordDefinition,
|
||||
KeywordErrorDefinition,
|
||||
ErrorObject,
|
||||
} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, str, nil, or, Code, getProperty, regexpCode} from "../../compile/codegen"
|
||||
|
||||
type FormatValidate =
|
||||
| FormatValidator<string>
|
||||
| FormatValidator<number>
|
||||
| AsyncFormatValidator<string>
|
||||
| AsyncFormatValidator<number>
|
||||
| RegExp
|
||||
| string
|
||||
| true
|
||||
|
||||
export type FormatError = ErrorObject<"format", {format: string}, string | {$data: string}>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: ({schemaCode}) => str`must match format "${schemaCode}"`,
|
||||
params: ({schemaCode}) => _`{format: ${schemaCode}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "format",
|
||||
type: ["number", "string"],
|
||||
schemaType: "string",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt: KeywordCxt, ruleType?: string) {
|
||||
const {gen, data, $data, schema, schemaCode, it} = cxt
|
||||
const {opts, errSchemaPath, schemaEnv, self} = it
|
||||
if (!opts.validateFormats) return
|
||||
|
||||
if ($data) validate$DataFormat()
|
||||
else validateFormat()
|
||||
|
||||
function validate$DataFormat(): void {
|
||||
const fmts = gen.scopeValue("formats", {
|
||||
ref: self.formats,
|
||||
code: opts.code.formats,
|
||||
})
|
||||
const fDef = gen.const("fDef", _`${fmts}[${schemaCode}]`)
|
||||
const fType = gen.let("fType")
|
||||
const format = gen.let("format")
|
||||
// TODO simplify
|
||||
gen.if(
|
||||
_`typeof ${fDef} == "object" && !(${fDef} instanceof RegExp)`,
|
||||
() => gen.assign(fType, _`${fDef}.type || "string"`).assign(format, _`${fDef}.validate`),
|
||||
() => gen.assign(fType, _`"string"`).assign(format, fDef)
|
||||
)
|
||||
cxt.fail$data(or(unknownFmt(), invalidFmt()))
|
||||
|
||||
function unknownFmt(): Code {
|
||||
if (opts.strictSchema === false) return nil
|
||||
return _`${schemaCode} && !${format}`
|
||||
}
|
||||
|
||||
function invalidFmt(): Code {
|
||||
const callFormat = schemaEnv.$async
|
||||
? _`(${fDef}.async ? await ${format}(${data}) : ${format}(${data}))`
|
||||
: _`${format}(${data})`
|
||||
const validData = _`(typeof ${format} == "function" ? ${callFormat} : ${format}.test(${data}))`
|
||||
return _`${format} && ${format} !== true && ${fType} === ${ruleType} && !${validData}`
|
||||
}
|
||||
}
|
||||
|
||||
function validateFormat(): void {
|
||||
const formatDef: AddedFormat | undefined = self.formats[schema]
|
||||
if (!formatDef) {
|
||||
unknownFormat()
|
||||
return
|
||||
}
|
||||
if (formatDef === true) return
|
||||
const [fmtType, format, fmtRef] = getFormat(formatDef)
|
||||
if (fmtType === ruleType) cxt.pass(validCondition())
|
||||
|
||||
function unknownFormat(): void {
|
||||
if (opts.strictSchema === false) {
|
||||
self.logger.warn(unknownMsg())
|
||||
return
|
||||
}
|
||||
throw new Error(unknownMsg())
|
||||
|
||||
function unknownMsg(): string {
|
||||
return `unknown format "${schema as string}" ignored in schema at path "${errSchemaPath}"`
|
||||
}
|
||||
}
|
||||
|
||||
function getFormat(fmtDef: AddedFormat): [string, FormatValidate, Code] {
|
||||
const code =
|
||||
fmtDef instanceof RegExp
|
||||
? regexpCode(fmtDef)
|
||||
: opts.code.formats
|
||||
? _`${opts.code.formats}${getProperty(schema)}`
|
||||
: undefined
|
||||
const fmt = gen.scopeValue("formats", {key: schema, ref: fmtDef, code})
|
||||
if (typeof fmtDef == "object" && !(fmtDef instanceof RegExp)) {
|
||||
return [fmtDef.type || "string", fmtDef.validate, _`${fmt}.validate`]
|
||||
}
|
||||
|
||||
return ["string", fmtDef, fmt]
|
||||
}
|
||||
|
||||
function validCondition(): Code {
|
||||
if (typeof formatDef == "object" && !(formatDef instanceof RegExp) && formatDef.async) {
|
||||
if (!schemaEnv.$async) throw new Error("async format in sync schema")
|
||||
return _`await ${fmtRef}(${data})`
|
||||
}
|
||||
return typeof format == "function" ? _`${fmtRef}(${data})` : _`${fmtRef}.test(${data})`
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
||||
6
node_modules/ajv/lib/vocabularies/format/index.ts
generated
vendored
Normal file
6
node_modules/ajv/lib/vocabularies/format/index.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import type {Vocabulary} from "../../types"
|
||||
import formatKeyword from "./format"
|
||||
|
||||
const format: Vocabulary = [formatKeyword]
|
||||
|
||||
export default format
|
||||
Loading…
Add table
Add a link
Reference in a new issue