Skip to content

Commit bf805f0

Browse files
authored
test: migrate more migration cases, a few minor fixes (#293)
* test: migrate more migration cases, a few minor fixes * update * update * update * update * update * update
1 parent 831cb66 commit bf805f0

33 files changed

+1314
-27
lines changed

packages/language/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"type": "module",
1212
"scripts": {
1313
"build": "pnpm langium:generate && tsc --noEmit && tsup-node",
14+
"watch": "tsup-node --watch",
1415
"lint": "eslint src --ext ts",
1516
"langium:generate": "langium generate",
1617
"langium:generate:production": "langium generate --mode=production",

packages/language/res/stdlib.zmodel

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@ attribute @@allow(_ operation: String @@@completionHint(["'create'", "'read'", "
676676
* @param condition: a boolean expression that controls if the operation should be allowed.
677677
* @param override: a boolean value that controls if the field-level policy should override the model-level policy.
678678
*/
679-
attribute @allow(_ operation: String @@@completionHint(["'create'", "'read'", "'update'", "'delete'", "'all'"]), _ condition: Boolean, _ override: Boolean?)
679+
// attribute @allow(_ operation: String @@@completionHint(["'create'", "'read'", "'update'", "'delete'", "'all'"]), _ condition: Boolean, _ override: Boolean?)
680680

681681
/**
682682
* Defines an access policy that denies a set of operations when the given condition is true.
@@ -692,7 +692,7 @@ attribute @@deny(_ operation: String @@@completionHint(["'create'", "'read'", "'
692692
* @param operation: comma-separated list of "create", "read", "update", "delete". Use "all" to denote all operations.
693693
* @param condition: a boolean expression that controls if the operation should be denied.
694694
*/
695-
attribute @deny(_ operation: String @@@completionHint(["'create'", "'read'", "'update'", "'delete'", "'all'"]), _ condition: Boolean)
695+
// attribute @deny(_ operation: String @@@completionHint(["'create'", "'read'", "'update'", "'delete'", "'all'"]), _ condition: Boolean)
696696

697697
/**
698698
* Checks if the current user can perform the given operation on the given field.

packages/language/src/zmodel-scope.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ import {
3636
getAuthDecl,
3737
getRecursiveBases,
3838
isAuthInvocation,
39-
isCollectionPredicate,
4039
isBeforeInvocation,
40+
isCollectionPredicate,
4141
resolveImportUri,
4242
} from './utils';
4343

@@ -75,7 +75,7 @@ export class ZModelScopeComputation extends DefaultScopeComputation {
7575

7676
override processNode(node: AstNode, document: LangiumDocument<AstNode>, scopes: PrecomputedScopes) {
7777
super.processNode(node, document, scopes);
78-
if (isDataModel(node)) {
78+
if (isDataModel(node) || isTypeDef(node)) {
7979
// add base fields to the scope recursively
8080
const bases = getRecursiveBases(node);
8181
for (const base of bases) {

packages/runtime/src/client/crud/operations/base.ts

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -939,15 +939,18 @@ export abstract class BaseOperationHandler<Schema extends SchemaDef> {
939939
combinedWhere = Object.keys(combinedWhere).length > 0 ? { AND: [parentWhere, combinedWhere] } : parentWhere;
940940
}
941941

942-
// fill in automatically updated fields
943942
const modelDef = this.requireModel(model);
944943
let finalData = data;
944+
945+
// fill in automatically updated fields
946+
const autoUpdatedFields: string[] = [];
945947
for (const [fieldName, fieldDef] of Object.entries(modelDef.fields)) {
946948
if (fieldDef.updatedAt) {
947949
if (finalData === data) {
948950
finalData = clone(data);
949951
}
950952
finalData[fieldName] = this.dialect.transformPrimitive(new Date(), 'DateTime', false);
953+
autoUpdatedFields.push(fieldName);
951954
}
952955
}
953956

@@ -1027,7 +1030,13 @@ export abstract class BaseOperationHandler<Schema extends SchemaDef> {
10271030
}
10281031
}
10291032

1030-
if (Object.keys(updateFields).length === 0) {
1033+
let hasFieldUpdate = Object.keys(updateFields).length > 0;
1034+
if (hasFieldUpdate) {
1035+
// check if only updating auto-updated fields, if so, we can skip the update
1036+
hasFieldUpdate = Object.keys(updateFields).some((f) => !autoUpdatedFields.includes(f));
1037+
}
1038+
1039+
if (!hasFieldUpdate) {
10311040
// nothing to update, return the filter so that the caller can identify the entity
10321041
return combinedWhere;
10331042
} else {
@@ -2073,22 +2082,11 @@ export abstract class BaseOperationHandler<Schema extends SchemaDef> {
20732082
}
20742083
}
20752084

2076-
// Given a unique filter of a model, return the entity ids by trying to
2077-
// reused the filter if it's a complete id filter (without extra fields)
2078-
// otherwise, read the entity by the filter
2085+
// Given a unique filter of a model, load the entity and return its id fields
20792086
private getEntityIds(kysely: ToKysely<Schema>, model: GetModels<Schema>, uniqueFilter: any) {
2080-
const idFields: string[] = requireIdFields(this.schema, model);
2081-
if (
2082-
// all id fields are provided
2083-
idFields.every((f) => f in uniqueFilter && uniqueFilter[f] !== undefined) &&
2084-
// no non-id filter exists
2085-
Object.keys(uniqueFilter).every((k) => idFields.includes(k))
2086-
) {
2087-
return uniqueFilter;
2088-
}
2089-
20902087
return this.readUnique(kysely, model, {
20912088
where: uniqueFilter,
2089+
select: this.makeIdSelect(model),
20922090
});
20932091
}
20942092

packages/runtime/src/client/crud/validator/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -976,9 +976,14 @@ export class InputValidator<Schema extends SchemaDef> {
976976
])
977977
.optional();
978978

979+
let upsertWhere = this.makeWhereSchema(fieldType, true);
980+
if (!fieldDef.array) {
981+
// to-one relation, can upsert without where clause
982+
upsertWhere = upsertWhere.optional();
983+
}
979984
fields['upsert'] = this.orArray(
980985
z.strictObject({
981-
where: this.makeWhereSchema(fieldType, true),
986+
where: upsertWhere,
982987
create: this.makeCreateDataSchema(fieldType, false, withoutFields),
983988
update: this.makeUpdateDataSchema(fieldType, withoutFields),
984989
}),

packages/testtools/src/client.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ export async function createTestClient<Schema extends SchemaDef>(
5858
const provider = options?.provider ?? getTestDbProvider() ?? 'sqlite';
5959

6060
const dbName = options?.dbName ?? getTestDbName(provider);
61-
console.log(`Using provider: ${provider}, db: ${dbName}`);
6261

6362
const dbUrl =
6463
provider === 'sqlite'

pnpm-lock.yaml

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

tests/e2e/orm/client-api/update.test.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ describe('Client update tests', () => {
3838
email: user.email,
3939
name: user.name,
4040
});
41-
expect(updated.updatedAt.getTime()).toBeGreaterThan(user.updatedAt.getTime());
41+
// should not update updatedAt
42+
expect(updated.updatedAt.getTime()).toEqual(user.updatedAt.getTime());
4243

4344
// id as filter
4445
updated = await client.user.update({
@@ -114,6 +115,21 @@ describe('Client update tests', () => {
114115
).resolves.toMatchObject({ id: 'user2' });
115116
});
116117

118+
it('does not update updatedAt if no other scalar fields are updated', async () => {
119+
const user = await createUser(client, '[email protected]');
120+
const originalUpdatedAt = user.updatedAt;
121+
122+
await client.user.update({
123+
where: { id: user.id },
124+
data: {
125+
posts: { create: { title: 'Post1' } },
126+
},
127+
});
128+
129+
const updatedUser = await client.user.findUnique({ where: { id: user.id } });
130+
expect(updatedUser?.updatedAt).toEqual(originalUpdatedAt);
131+
});
132+
117133
it('works with numeric incremental update', async () => {
118134
await createUser(client, '[email protected]', {
119135
profile: { create: { id: '1', bio: 'bio' } },

tests/e2e/orm/policy/crud/read.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ model Bar {
294294

295295
await db.$unuseAll().foo.create({ data: { id: 1 } });
296296
await expect(db.foo.findMany()).resolves.toHaveLength(0);
297-
await db.foo.update({ where: { id: 1 }, data: { bar: { create: { id: 1, y: 0 } } } });
297+
await db.$unuseAll().foo.update({ where: { id: 1 }, data: { bar: { create: { id: 1, y: 0 } } } });
298298
await expect(db.foo.findMany()).resolves.toHaveLength(1);
299299
});
300300

@@ -321,7 +321,7 @@ model Bar {
321321

322322
await db.$unuseAll().foo.create({ data: { id: 1, bars: { create: [{ id: 1, y: 0 }] } } });
323323
await expect(db.foo.findMany()).resolves.toHaveLength(0);
324-
await db.foo.update({ where: { id: 1 }, data: { bars: { create: { id: 2, y: 1 } } } });
324+
await db.$unuseAll().foo.update({ where: { id: 1 }, data: { bars: { create: { id: 2, y: 1 } } } });
325325
await expect(db.foo.findMany()).resolves.toHaveLength(1);
326326
});
327327

tests/e2e/orm/policy/migrated/omit.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ describe('prisma omit', () => {
1010
name String
1111
profile Profile?
1212
age Int
13-
value Int @allow('read', age > 20)
13+
value Int
1414
@@allow('all', age > 18)
1515
}
1616

0 commit comments

Comments
 (0)