-
Notifications
You must be signed in to change notification settings - Fork 47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: Convert RecordId from Class to JSON-object while maintaining JSON-structure #301
Comments
Heya! You should be able to simply obtain the id part by selecting the |
I also have this problem with SvelteKit. Only POJOs can be returned from load functions. Would be great if the SDK would have a function that converts the record ID to a POJO. In the meantime here is a workaround: function convertRecordIds<T>(obj: T): T {
if (obj instanceof RecordId) {
return { tb: obj.tb, id: obj.id } as T;
} else if (Array.isArray(obj)) {
return obj.map(convertRecordIds) as unknown as T;
} else if (typeof obj === 'object' && obj !== null) {
return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, convertRecordIds(value)])) as T;
} else {
return obj;
}
} And a function which converts it back: export function convertToRecordId<T>(obj: T): T {
if (typeof obj === 'object' && obj !== null && 'tb' in obj && 'id' in obj) {
return new RecordId(obj.tb as string, obj.id as RecordIdValue) as T;
} else if (Array.isArray(obj)) {
return obj.map(convertToRecordId) as unknown as T;
} else if (typeof obj === 'object' && obj !== null) {
return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, convertToRecordId(value)])) as T;
} else {
return obj;
}
} Types could be optimized, but it will do the job for now. |
One thought regarding the jsonify({
rid: new RecordId("person", "tobie"),
foo: {
bar: new Duration("1d2h"),
baz: [
new Uuid("92b84bde-39c8-4b4b-92f7-626096d6c4d9"),
new Uuid("da3f72a2-261b-468a-b3f6-374cbcbb15b6")
]
}
}, '__register'); {
rid: "person:tobie",
foo: {
bar: "1d2h",
baz: [
"92b84bde-39c8-4b4b-92f7-626096d6c4d9",
"da3f72a2-261b-468a-b3f6-374cbcbb15b6"
]
},
__register: {
"rid": "RecordId",
"foo.bar": "Duration",
"foo.baz[0]": "Uuid",
"foo.baz[1]": "Uuid",
}
} And then the surrealify({
rid: "person:tobie",
foo: {
bar: "1d2h",
baz: [
"92b84bde-39c8-4b4b-92f7-626096d6c4d9",
"da3f72a2-261b-468a-b3f6-374cbcbb15b6"
]
},
__register: {
"rid": "RecordId",
"foo.bar": "Duration",
"foo.baz[0]": "Uuid",
"foo.baz[1]": "Uuid",
}
}, '__register'); to create
|
I wrote my own Surreal wrapper to convert record IDs into non-class form. I also use this for SvelteKit. import {
RecordId as BaseRecordId, Surreal as BaseSurreal, type Prettify, type QueryParameters, type RecordIdValue
} from "surrealdb"
export interface RecordId<Tb extends string = string> {
tb: Tb
id: string
}
export function new_record<Tb extends string>(tb: Tb, id: string): RecordId<Tb> {
return {
tb,
id
}
}
export class Surreal extends BaseSurreal {
async query<T extends unknown[]>(...args: QueryParameters): Promise<Prettify<T>> {
if (args[1] instanceof Array) return this.convert_to_record_id(await super.query(...args)) as unknown as Promise<Prettify<T>>
if (args[1]) args[1] = this.convert_to_record_id_class(args[1]) as Record<string, unknown>
return this.convert_to_record_id(await super.query(...args)) as unknown as Promise<Prettify<T>>
}
private convert_to_record_id(value: unknown): unknown {
if (value instanceof BaseRecordId) {
return {
tb: value.tb,
id: this.convert_to_record_id(value.id),
}
}
// if (Array.isArray(value)) return value.map(this.convert_to_record_id)
if (value instanceof Date) return value
if (typeof value === "object" && value !== null) {
for (const [key, val] of Object.entries(value)) {
(value as Record<string, unknown>)[key] = this.convert_to_record_id(val)
}
return value
}
return value
}
private convert_to_record_id_class(value: unknown): unknown {
if (value instanceof BaseRecordId) return value
if (Array.isArray(value)) return value.map(this.convert_to_record_id_class)
if (value instanceof Date) return value
if (typeof value === "object" && value !== null ) {
if (is_record_id(value)) return new BaseRecordId(value.tb, this.convert_to_record_id(value.id) as RecordIdValue)
const obj: Record<string, unknown> = {}
for (const [key, val] of Object.entries(value)) {
obj[key] = this.convert_to_record_id_class(val)
}
return obj
}
return value
}
}
function is_record_id_value(id: unknown): id is RecordIdValue {
if (typeof id === "string") return true
if (typeof id === "number") return true
if (typeof id === "boolean") return true
if (typeof id === "bigint") return true
if (Array.isArray(id)) return true
if (typeof id === "object" && id !== null) return true
return false
}
function is_record_id(value: unknown): value is RecordId<string> {
if (
typeof value === "object"
&& value !== null
&& "tb" in value
&& typeof value.tb === "string"
&& "id" in value
&& is_record_id_value(value.id)
) {
return true
}
return false
} |
Is your feature request related to a problem?
I have a problem regarding using surrealdb.js on the server and having to send data from the server to the client. I want to send the RecordId of an record to the client in a JSON format instead of a
tb:id
-string. Though when trying to do this, i stumble upon the following problems:jsonify
, the RecordId is converted into a string of the formtb:id
.Therefore, i have no simple way of returning data from the server to the client while maintaining the JSON-object in the recordId.
Describe the solution
It would be nice to have a utility function or a method implemented on the class that could convert the recordId class into JSON and maintain the JSON-structure:
Alternative methods
Write my own utility function, or also store the data elsewhere than in the recordId.
SurrealDB version
surreal 1.5.3
SurrealDB.js version
1.0.0-beta-12
Contact Details
[email protected]
Is there an existing issue for this?
Code of Conduct
The text was updated successfully, but these errors were encountered: