Skip to content

Commit 3067766

Browse files
committed
Fixed class handling for transport feature.
1 parent 6e59fd8 commit 3067766

File tree

10 files changed

+79
-10
lines changed

10 files changed

+79
-10
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ Headlines: Added, Changed, Deprecated, Removed, Fixed, Security
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [Unreleased]
9+
10+
### Fixed
11+
12+
- The [transport feature](https://superforms.rocks/concepts/nested-data#arbitrary-types-in-the-form) released in 2.22.0 didn't fully handle classes. It should work better now, but the classes must be very simple to work. Let me know if you have any problems with a certain class.
13+
814
## [2.22.0] - 2024-12-15
915

1016
### Added

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,6 @@
174174
},
175175
"dependencies": {
176176
"devalue": "^5.1.1",
177-
"just-clone": "^6.2.0",
178177
"memoize-weak": "^1.0.2",
179178
"ts-deepmerge": "^7.0.2"
180179
},

pnpm-lock.yaml

Lines changed: 0 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/hooks.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import type { Transport } from '@sveltejs/kit';
22
import { Decimal } from 'decimal.js';
3+
import { RecordId } from './routes/RecordId.js';
34

45
export const transport: Transport = {
56
Decimal: {
67
encode: (value) => value instanceof Decimal && value.toString(),
78
decode: (str) => new Decimal(str)
9+
},
10+
RecordId: {
11+
encode: (record) => record instanceof RecordId && [record.id, record.tb],
12+
decode: ([id, tb]) => new RecordId(id, tb)
813
}
914
};

src/lib/justClone.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
Deep clones all properties except functions
3+
4+
var arr = [1, 2, 3];
5+
var subObj = {aa: 1};
6+
var obj = {a: 3, b: 5, c: arr, d: subObj};
7+
var objClone = clone(obj);
8+
arr.push(4);
9+
subObj.bb = 2;
10+
obj; // {a: 3, b: 5, c: [1, 2, 3, 4], d: {aa: 1}}
11+
objClone; // {a: 3, b: 5, c: [1, 2, 3], d: {aa: 1, bb: 2}}
12+
*/
13+
14+
export function clone<T>(obj: T): T {
15+
const type = {}.toString.call(obj).slice(8, -1);
16+
if (type == 'Set') {
17+
// @ts-expect-error Known type
18+
return new Set([...obj].map((value) => clone(value)));
19+
}
20+
if (type == 'Map') {
21+
// @ts-expect-error Known type
22+
return new Map([...obj].map((kv) => [clone(kv[0]), clone(kv[1])]));
23+
}
24+
if (type == 'Date') {
25+
// @ts-expect-error Known type
26+
return new Date(obj.getTime());
27+
}
28+
if (type == 'RegExp') {
29+
// @ts-expect-error Known type
30+
return RegExp(obj.source, (obj as RegExp).flags);
31+
}
32+
if (type == 'Array') {
33+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
34+
const result = [] as any;
35+
for (const key in obj) {
36+
result[key] = clone(obj[key]);
37+
}
38+
return result;
39+
}
40+
if (type == 'Object') {
41+
return Object.assign(Object.create(Object.getPrototypeOf(obj)), obj);
42+
}
43+
44+
// primitives and non-supported objects (e.g. functions) land here
45+
return obj;
46+
}

src/lib/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { JSONSchema7Definition } from 'json-schema';
22
import type { JSONSchema } from './jsonSchema/index.js';
3-
import justClone from 'just-clone';
3+
import { clone as justClone } from './justClone.js';
44
import { SchemaError } from './errors.js';
55

66
// export type DeepPartial<T> = T extends object

src/routes/(v2)/v2/transport/+page.server.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { zod } from '$lib/adapters/zod.js';
22
import { message, superValidate } from '$lib/server/index.js';
33
import { transport } from '../../../../hooks.js';
4+
import { RecordId } from '../../../RecordId.js';
45
import { schema } from './schema.js';
56
import { fail } from '@sveltejs/kit';
67

@@ -20,6 +21,7 @@ export const actions = {
2021
if (!form.valid) return fail(400, { form });
2122

2223
form.data.luckyNumber = form.data.luckyNumber.mul(2);
24+
form.data.id = new RecordId(form.data.id.id * 2, form.data.id.tb);
2325

2426
return message(form, 'Your lucky number times 2 is ' + form.data.luckyNumber);
2527
}

src/routes/(v2)/v2/transport/+page.svelte

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929

3030
{#if $message}<h4>{$message}</h4>{/if}
3131

32+
<p id="record">$form.id: {$form.id}</p>
33+
3234
<form method="POST" use:enhance>
3335
<label>
3436
Name: <input

src/routes/(v2)/v2/transport/schema.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { Decimal } from 'decimal.js';
22
import { z } from 'zod';
3+
import { RecordId } from '../../../RecordId.js';
34

45
export const schema = z.object({
6+
id: z.instanceof(RecordId).default(new RecordId(123, 'test')),
57
name: z.string().min(2),
68
luckyNumber: z
79
.instanceof(Decimal)

src/routes/RecordId.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export class RecordId {
2+
public readonly id: number;
3+
public readonly tb: string;
4+
5+
constructor(id: number, tb: string) {
6+
if (!id) throw new Error('id is required');
7+
if (!tb) throw new Error('tb is required');
8+
this.id = id;
9+
this.tb = tb;
10+
}
11+
12+
public toString() {
13+
return `${this.id} for table ${this.tb}`;
14+
}
15+
}

0 commit comments

Comments
 (0)