From bf809c42dd86e907d9fa9495afb1119e7b969bda Mon Sep 17 00:00:00 2001 From: kiddyu <58631254@qq.com> Date: Thu, 16 Oct 2025 04:08:56 +0800 Subject: [PATCH] fix: Safari compatible --- src/browser/concerns/has-relations.js | 33 +++++++++++++++++++++++---- types/browser/index.d.ts | 12 ++++++---- types/index.d.ts | 12 ++++++---- 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/src/browser/concerns/has-relations.js b/src/browser/concerns/has-relations.js index 9aa9f24..3e382b2 100644 --- a/src/browser/concerns/has-relations.js +++ b/src/browser/concerns/has-relations.js @@ -61,11 +61,34 @@ const HasRelations = (Model) => { } guessBelongsToRelation() { - let e = new Error(); - let frame = e.stack.split("\n")[2]; - // let lineNumber = frame.split(":").reverse()[1]; - let functionName = frame.split(" ")[5]; - return getRelationName(functionName); + const e = new Error(); + const stack = e.stack || e.stackTrace; + + if (!stack) { + return getRelationName('unknown'); + } + + const frames = stack.split('\n'); + const frame = frames[2] || frames[1] || frames[0]; + + let functionName = 'anonymous'; + + if (frame.includes('@')) { + // Safari: functionName@file:line:column + functionName = frame.split('@')[0].trim(); + } else if (frame.includes('at ')) { + // Chrome: at functionName (file:line:column) + const match = frame.match(/at\s+([^(]+)\s*\(/); + functionName = match ? match[1].trim() : 'anonymous'; + + if (functionName.includes('.')) { + functionName = functionName.split('.').pop(); + } + } + + functionName = functionName.replace(/^$/, '').trim(); + + return getRelationName(functionName || 'anonymous'); } joiningTable(related, instance = null) { diff --git a/types/browser/index.d.ts b/types/browser/index.d.ts index 98323e7..ef97dae 100644 --- a/types/browser/index.d.ts +++ b/types/browser/index.d.ts @@ -75,7 +75,10 @@ declare module 'sutando' { fill(attributes: any): this; setAppends(appends: string[]): this; append(key: string | string[]): this; - getRelation(relation: string): T | Collection | null | undefined; + getRelation< + T extends Model, + IsCollection extends boolean = false + >(relation: string): IsCollection extends true ? Collection | undefined : T | null | undefined; setRelation(relation: string, value: T | Collection | null): this; unsetRelation(relation: string): this; relationLoaded(relation: string): boolean; @@ -161,9 +164,10 @@ declare module 'sutando' { export class RelationNotFoundError extends Error {} export class InvalidArgumentError extends Error {} - export function make Model>(modelClass: T, attributes: Record[]): Collection; - export function makeCollection Model>(modelClass: T, attributes: Record[]): Collection; - export function makePaginator Model>(modelClass: T, attributes: Record[]): Paginator; + export function make(modelClass: new (...args: any[]) => T, attributes: Record): T; + export function make(modelClass: new (...args: any[]) => T, attributes: Record[]): Collection; + export function makeCollection(modelClass: new (...args: any[]) => T, attributes: Record[]): Collection; + export function makePaginator(modelClass: new (...args: any[]) => T, attributes: Record[]): Paginator; export function HasUniqueIds Model>(Base: T): T & { new (...args: ConstructorParameters): { diff --git a/types/index.d.ts b/types/index.d.ts index 98bd10b..cdead29 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -402,7 +402,10 @@ declare module 'sutando' { fill(attributes: any): this; setAppends(appends: string[]): this; append(key: string | string[]): this; - getRelation(relation: string): T | Collection | null | undefined; + getRelation< + T extends Model, + IsCollection extends boolean = false + >(relation: string): IsCollection extends true ? Collection | undefined : T | null | undefined; setRelation(relation: string, value: T | Collection | null): this; unsetRelation(relation: string): this; relationLoaded(relation: string): boolean; @@ -802,9 +805,10 @@ declare module 'sutando' { export function getScopeMethod(name: string): string; export const compose: MixinFunction; - export function make Model>(modelClass: T, attributes: Record[]): Collection; - export function makeCollection Model>(modelClass: T, attributes: Record[]): Collection; - export function makePaginator Model>(modelClass: T, attributes: Record[]): Paginator; + export function make(modelClass: new (...args: any[]) => T, attributes: Record): T; + export function make(modelClass: new (...args: any[]) => T, attributes: Record[]): Collection; + export function makeCollection(modelClass: new (...args: any[]) => T, attributes: Record[]): Collection; + export function makePaginator(modelClass: new (...args: any[]) => T, attributes: Record[]): Paginator; export interface Plugin { (modelClass: M): M;