Skip to content

Commit 7c5940b

Browse files
committed
a few fixes:
- Update test to use postgres db - Changes url pattern option from `segmentNameCharset` to `segmentValueCharset` - Made sure ID key sent to Prisma is always joined with '_' instead of user-configured divider. I've renamed methods for clarity.
1 parent e127e04 commit 7c5940b

File tree

2 files changed

+45
-25
lines changed

2 files changed

+45
-25
lines changed

packages/server/src/api/rest/index.ts

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ class RequestHandler extends APIHandlerBase {
213213
}
214214

215215
buildUrlPatterns(idDivider: string) {
216-
const options = { segmentNameCharset: `a-zA-Z0-9-_~ %${idDivider}` };
216+
const options = { segmentValueCharset: `a-zA-Z0-9-_~ %${idDivider}` };
217217
return {
218218
// collection operations
219219
collection: new UrlPattern('/:type', options),
@@ -403,7 +403,7 @@ class RequestHandler extends APIHandlerBase {
403403
return this.makeUnsupportedModelError(type);
404404
}
405405

406-
const args: any = { where: this.makeIdFilter(typeInfo.idFields, resourceId) };
406+
const args: any = { where: this.makePrismaIdFilter(typeInfo.idFields, resourceId) };
407407

408408
// include IDs of relation fields so that they can be serialized
409409
this.includeRelationshipIds(type, args, 'include');
@@ -468,7 +468,7 @@ class RequestHandler extends APIHandlerBase {
468468

469469
select = select ?? { [relationship]: true };
470470
const args: any = {
471-
where: this.makeIdFilter(typeInfo.idFields, resourceId),
471+
where: this.makePrismaIdFilter(typeInfo.idFields, resourceId),
472472
select,
473473
};
474474

@@ -526,7 +526,7 @@ class RequestHandler extends APIHandlerBase {
526526
}
527527

528528
const args: any = {
529-
where: this.makeIdFilter(typeInfo.idFields, resourceId),
529+
where: this.makePrismaIdFilter(typeInfo.idFields, resourceId),
530530
select: this.makeIdSelect(typeInfo.idFields),
531531
};
532532

@@ -765,7 +765,7 @@ class RequestHandler extends APIHandlerBase {
765765
if (relationInfo.isCollection) {
766766
createPayload.data[key] = {
767767
connect: enumerate(data.data).map((item: any) => ({
768-
[this.makeIdKey(relationInfo.idFields)]: item.id,
768+
[this.makePrismaIdKey(relationInfo.idFields)]: item.id,
769769
})),
770770
};
771771
} else {
@@ -774,15 +774,15 @@ class RequestHandler extends APIHandlerBase {
774774
}
775775
createPayload.data[key] = {
776776
connect: {
777-
[this.makeIdKey(relationInfo.idFields)]: data.data.id,
777+
[this.makePrismaIdKey(relationInfo.idFields)]: data.data.id,
778778
},
779779
};
780780
}
781781

782782
// make sure ID fields are included for result serialization
783783
createPayload.include = {
784784
...createPayload.include,
785-
[key]: { select: { [this.makeIdKey(relationInfo.idFields)]: true } },
785+
[key]: { select: { [this.makePrismaIdKey(relationInfo.idFields)]: true } },
786786
};
787787
}
788788
}
@@ -819,7 +819,7 @@ class RequestHandler extends APIHandlerBase {
819819
}
820820

821821
const updateArgs: any = {
822-
where: this.makeIdFilter(typeInfo.idFields, resourceId),
822+
where: this.makePrismaIdFilter(typeInfo.idFields, resourceId),
823823
select: {
824824
...typeInfo.idFields.reduce((acc, field) => ({ ...acc, [field.name]: true }), {}),
825825
[relationship]: { select: this.makeIdSelect(relationInfo.idFields) },
@@ -854,7 +854,7 @@ class RequestHandler extends APIHandlerBase {
854854
updateArgs.data = {
855855
[relationship]: {
856856
connect: {
857-
[this.makeIdKey(relationInfo.idFields)]: parsed.data.data.id,
857+
[this.makePrismaIdKey(relationInfo.idFields)]: parsed.data.data.id,
858858
},
859859
},
860860
};
@@ -878,7 +878,7 @@ class RequestHandler extends APIHandlerBase {
878878
updateArgs.data = {
879879
[relationship]: {
880880
[relationVerb]: enumerate(parsed.data.data).map((item: any) =>
881-
this.makeIdFilter(relationInfo.idFields, item.id)
881+
this.makePrismaIdFilter(relationInfo.idFields, item.id)
882882
),
883883
},
884884
};
@@ -919,7 +919,7 @@ class RequestHandler extends APIHandlerBase {
919919
}
920920

921921
const updatePayload: any = {
922-
where: this.makeIdFilter(typeInfo.idFields, resourceId),
922+
where: this.makePrismaIdFilter(typeInfo.idFields, resourceId),
923923
data: { ...attributes },
924924
};
925925

@@ -938,7 +938,7 @@ class RequestHandler extends APIHandlerBase {
938938
if (relationInfo.isCollection) {
939939
updatePayload.data[key] = {
940940
set: enumerate(data.data).map((item: any) => ({
941-
[this.makeIdKey(relationInfo.idFields)]: item.id,
941+
[this.makePrismaIdKey(relationInfo.idFields)]: item.id,
942942
})),
943943
};
944944
} else {
@@ -947,13 +947,13 @@ class RequestHandler extends APIHandlerBase {
947947
}
948948
updatePayload.data[key] = {
949949
set: {
950-
[this.makeIdKey(relationInfo.idFields)]: data.data.id,
950+
[this.makePrismaIdKey(relationInfo.idFields)]: data.data.id,
951951
},
952952
};
953953
}
954954
updatePayload.include = {
955955
...updatePayload.include,
956-
[key]: { select: { [this.makeIdKey(relationInfo.idFields)]: true } },
956+
[key]: { select: { [this.makePrismaIdKey(relationInfo.idFields)]: true } },
957957
};
958958
}
959959
}
@@ -972,7 +972,7 @@ class RequestHandler extends APIHandlerBase {
972972
}
973973

974974
await prisma[type].delete({
975-
where: this.makeIdFilter(typeInfo.idFields, resourceId),
975+
where: this.makePrismaIdFilter(typeInfo.idFields, resourceId),
976976
});
977977
return {
978978
status: 204,
@@ -1218,12 +1218,13 @@ class RequestHandler extends APIHandlerBase {
12181218
return r.toString();
12191219
}
12201220

1221-
private makeIdFilter(idFields: FieldInfo[], resourceId: string) {
1221+
private makePrismaIdFilter(idFields: FieldInfo[], resourceId: string) {
12221222
if (idFields.length === 1) {
12231223
return { [idFields[0].name]: this.coerce(idFields[0].type, resourceId) };
12241224
} else {
12251225
return {
1226-
[idFields.map((idf) => idf.name).join(this.idDivider)]: idFields.reduce(
1226+
// TODO: support `@@id` with custom name
1227+
[idFields.map((idf) => idf.name).join('_')]: idFields.reduce(
12271228
(acc, curr, idx) => ({
12281229
...acc,
12291230
[curr.name]: this.coerce(curr.type, resourceId.split(this.idDivider)[idx]),
@@ -1245,6 +1246,11 @@ class RequestHandler extends APIHandlerBase {
12451246
return idFields.map((idf) => idf.name).join(this.idDivider);
12461247
}
12471248

1249+
private makePrismaIdKey(idFields: FieldInfo[]) {
1250+
// TODO: support `@@id` with custom name
1251+
return idFields.map((idf) => idf.name).join('_');
1252+
}
1253+
12481254
private makeCompoundId(idFields: FieldInfo[], item: any) {
12491255
return idFields.map((idf) => item[idf.name]).join(this.idDivider);
12501256
}
@@ -1569,11 +1575,11 @@ class RequestHandler extends APIHandlerBase {
15691575
const values = value.split(',').filter((i) => i);
15701576
const filterValue =
15711577
values.length > 1
1572-
? { OR: values.map((v) => this.makeIdFilter(info.idFields, v)) }
1573-
: this.makeIdFilter(info.idFields, value);
1578+
? { OR: values.map((v) => this.makePrismaIdFilter(info.idFields, v)) }
1579+
: this.makePrismaIdFilter(info.idFields, value);
15741580
return { some: filterValue };
15751581
} else {
1576-
return { is: this.makeIdFilter(info.idFields, value) };
1582+
return { is: this.makePrismaIdFilter(info.idFields, value) };
15771583
}
15781584
} else {
15791585
const coerced = this.coerce(fieldInfo.type, value);

packages/server/tests/api/rest.test.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/// <reference types="@types/jest" />
33

44
import { CrudFailureReason, type ModelMeta } from '@zenstackhq/runtime';
5-
import { loadSchema, run } from '@zenstackhq/testtools';
5+
import { createPostgresDb, dropPostgresDb, loadSchema, run } from '@zenstackhq/testtools';
66
import { Decimal } from 'decimal.js';
77
import SuperJSON from 'superjson';
88
import makeHandler from '../../src/api/rest';
@@ -2537,11 +2537,15 @@ describe('REST server tests', () => {
25372537
}
25382538
`;
25392539
const idDivider = ':';
2540+
const dbName = 'restful-compound-id-custom-separator';
25402541

25412542
beforeAll(async () => {
2542-
const params = await loadSchema(schema);
2543+
const params = await loadSchema(schema, {
2544+
provider: 'postgresql',
2545+
dbUrl: await createPostgresDb(dbName),
2546+
});
25432547

2544-
prisma = params.enhanceRaw(params.prisma, params);
2548+
prisma = params.prisma;
25452549
zodSchemas = params.zodSchemas;
25462550
modelMeta = params.modelMeta;
25472551

@@ -2550,6 +2554,10 @@ describe('REST server tests', () => {
25502554
_handler({ ...args, zodSchemas, modelMeta, url: new URL(`http://localhost/${args.path}`) });
25512555
});
25522556

2557+
afterAll(async () => {
2558+
dropPostgresDb(dbName);
2559+
});
2560+
25532561
it('POST', async () => {
25542562
const r = await handler({
25552563
method: 'post',
@@ -2590,7 +2598,7 @@ describe('REST server tests', () => {
25902598

25912599
const r = await handler({
25922600
method: 'get',
2593-
path: '/user/user1@abc.om:COMMON_USER',
2601+
path: '/user/user1@abc.com:COMMON_USER',
25942602
query: {},
25952603
prisma,
25962604
});
@@ -2606,8 +2614,14 @@ describe('REST server tests', () => {
26062614

26072615
const r = await handler({
26082616
method: 'put',
2609-
path: '/user/user1@abc.om:COMMON_USER',
2617+
path: '/user/user1@abc.com:COMMON_USER',
26102618
query: {},
2619+
requestBody: {
2620+
data: {
2621+
type: 'user',
2622+
attributes: { role: 'ADMIN_USER' },
2623+
},
2624+
},
26112625
prisma,
26122626
});
26132627

0 commit comments

Comments
 (0)