Skip to content

Commit 6ce2e89

Browse files
committed
framework&ui: add serialize guard
1 parent 3d70cf3 commit 6ce2e89

File tree

2 files changed

+11
-7
lines changed

2 files changed

+11
-7
lines changed

framework/framework/api.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,22 @@ type Projection<T, S> = S extends ProjectionSchemaId
7575
[K in keyof T & keyof S]: K extends keyof AsKeys<S> ? Projection<T[K], AsKeys<S>[K]> : never
7676
};
7777

78-
export const projection = <T, S extends ProjectionSchema<T>>(input: T, schema: S): Projection<T, S> => {
78+
export const projection = <T, S extends ProjectionSchema<T>>(input: T, schema: S, serializeCtx?: any): Projection<T, S> => {
7979
if (typeof input !== 'object' || input === null) throw new Error('Input must be an object.');
8080
type R = Projection<T, S>;
81+
if ('serialize' in input && typeof (input as any).serialize === 'function') {
82+
input = (input as any).serialize(serializeCtx);
83+
}
8184
if (Array.isArray(schema)) schema = Object.fromEntries(schema.map((s) => [s, 1])) as S;
8285
if (Array.isArray(input)) {
83-
return input.map((item) => projection(item, schema)) as R;
86+
return input.map((item) => projection(item, schema, serializeCtx)) as R;
8487
}
8588
const result = {} as R;
8689
for (const key of Reflect.ownKeys(input)) {
8790
const schemaIt = schema[key];
8891
if (!schemaIt) continue;
8992
if (schemaIt === 1 || !input[key]) result[key] = input[key];
90-
else result[key] = projection(input[key], schemaIt);
93+
else result[key] = projection(input[key], schemaIt, serializeCtx);
9194
}
9295
return result;
9396
};
@@ -174,7 +177,7 @@ export class ApiService extends Service {
174177
}
175178
}
176179
}
177-
return (project && typeof result === 'object' && result !== null) ? projection(result, project) : result;
180+
return (project && typeof result === 'object' && result !== null) ? projection(result, project, context) : result;
178181
}
179182
}
180183

packages/ui-default/backendlib/template.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ let { template } = argv.options;
1818
if (!template || typeof template !== 'string') template = findFileSync('@hydrooj/ui-default/templates');
1919
else template = findFileSync(template);
2020

21-
const replacer = (k, v) => {
21+
const replacer = (s) => (k, v) => {
2222
if (k.startsWith('_') && k !== '_id') return undefined;
2323
if (typeof v === 'bigint') return `BigInt::${v.toString()}`;
24+
if (v && typeof v === 'object' && 'serialize' in v && typeof v.serialize === 'function') return v.serialize(s);
2425
return v;
2526
};
2627

@@ -68,7 +69,7 @@ class Nunjucks extends nunjucks.Environment {
6869
callback(error);
6970
}
7071
}, true);
71-
this.addFilter('json', (self) => (self ? JSON.stringify(self, replacer) : ''));
72+
this.addFilter('json', (self, s) => (self ? JSON.stringify(self, replacer(s)) : ''));
7273
this.addFilter('parseYaml', (self) => yaml.load(self));
7374
this.addFilter('dumpYaml', (self) => yaml.dump(self));
7475
this.addFilter('assign', (self, data) => Object.assign(self, data));
@@ -79,7 +80,7 @@ class Nunjucks extends nunjucks.Environment {
7980
this.addFilter('base64_decode', (s) => Buffer.from(s, 'base64').toString());
8081
this.addFilter('jsesc', (self) => jsesc(self, { isScriptContext: true }));
8182
this.addFilter('bitand', (self, val) => self & val);
82-
this.addFilter('toString', (self) => (typeof self === 'string' ? self : JSON.stringify(self, replacer)));
83+
this.addFilter('toString', (self, s) => (typeof self === 'string' ? self : JSON.stringify(self, replacer(s))));
8384
this.addFilter('content', (content, language, html) => {
8485
let s: any = '';
8586
try {

0 commit comments

Comments
 (0)