Skip to content

Commit b44976d

Browse files
authored
chore: remove aux fields (unused since a few release ago) (#662)
1 parent 522df7a commit b44976d

File tree

22 files changed

+37
-455
lines changed

22 files changed

+37
-455
lines changed

packages/plugins/openapi/src/rest-generator.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import type { DMMF } from '@prisma/generator-helper';
44
import {
5-
AUXILIARY_FIELDS,
65
analyzePolicies,
76
getDataModels,
87
hasAttribute,
@@ -829,7 +828,7 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase {
829828
}
830829

831830
private generateModelEntity(model: DataModel, mode: 'read' | 'create' | 'update'): OAPI.SchemaObject {
832-
const fields = model.fields.filter((f) => !AUXILIARY_FIELDS.includes(f.name) && !isIdField(f));
831+
const fields = model.fields.filter((f) => !isIdField(f));
833832

834833
const attributes: Record<string, OAPI.SchemaObject> = {};
835834
const relationships: Record<string, OAPI.ReferenceObject> = {};

packages/plugins/openapi/src/rpc-generator.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Inspired by: https://github.com/omar-dulaimi/prisma-trpc-generator
22

33
import type { DMMF } from '@prisma/generator-helper';
4-
import { analyzePolicies, AUXILIARY_FIELDS, PluginError, requireOption, resolvePath } from '@zenstackhq/sdk';
4+
import { analyzePolicies, PluginError, requireOption, resolvePath } from '@zenstackhq/sdk';
55
import { DataModel, isDataModel } from '@zenstackhq/sdk/ast';
66
import {
77
addMissingInputObjectTypesForAggregate,
@@ -681,17 +681,16 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase {
681681
private generateEnumComponent(_enum: DMMF.SchemaEnum): OAPI.SchemaObject {
682682
const schema: OAPI.SchemaObject = {
683683
type: 'string',
684-
enum: _enum.values.filter((f) => !AUXILIARY_FIELDS.includes(f)),
684+
enum: _enum.values,
685685
};
686686
return schema;
687687
}
688688

689689
private generateEntityComponent(model: DMMF.Model): OAPI.SchemaObject {
690690
const properties: Record<string, OAPI.ReferenceObject | OAPI.SchemaObject> = {};
691691

692-
const fields = model.fields.filter((f) => !AUXILIARY_FIELDS.includes(f.name));
693692
const required: string[] = [];
694-
for (const field of fields) {
693+
for (const field of model.fields) {
695694
properties[field.name] = this.generateField(field);
696695
if (field.isRequired && !(field.relationName && field.isList)) {
697696
required.push(field.name);
@@ -721,8 +720,7 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase {
721720

722721
private generateInputComponent(input: DMMF.InputType): OAPI.SchemaObject {
723722
const properties: Record<string, OAPI.ReferenceObject | OAPI.SchemaObject> = {};
724-
const fields = input.fields.filter((f) => !AUXILIARY_FIELDS.includes(f.name));
725-
for (const field of fields) {
723+
for (const field of input.fields) {
726724
const options = field.inputTypes
727725
.filter(
728726
(f) =>
@@ -737,14 +735,13 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase {
737735
}
738736

739737
const result: OAPI.SchemaObject = { type: 'object', properties };
740-
this.setInputRequired(fields, result);
738+
this.setInputRequired(input.fields, result);
741739
return result;
742740
}
743741

744742
private generateOutputComponent(output: DMMF.OutputType): OAPI.SchemaObject {
745743
const properties: Record<string, OAPI.ReferenceObject | OAPI.SchemaObject> = {};
746-
const fields = output.fields.filter((f) => !AUXILIARY_FIELDS.includes(f.name));
747-
for (const field of fields) {
744+
for (const field of output.fields) {
748745
let outputType: OAPI.ReferenceObject | OAPI.SchemaObject;
749746
switch (field.outputType.location) {
750747
case 'scalar':
@@ -762,7 +759,7 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase {
762759
}
763760

764761
const result: OAPI.SchemaObject = { type: 'object', properties };
765-
this.setOutputRequired(fields, result);
762+
this.setOutputRequired(output.fields, result);
766763
return result;
767764
}
768765

packages/runtime/src/constants.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,6 @@
33
*/
44
export const DEFAULT_PASSWORD_SALT_LENGTH = 12;
55

6-
/**
7-
* Auxiliary database field for supporting policy check for nested writes
8-
*/
9-
export const TRANSACTION_FIELD_NAME = 'zenstack_transaction';
10-
11-
/**
12-
* Auxiliary database field for building up policy check queries
13-
*/
14-
export const GUARD_FIELD_NAME = 'zenstack_guard';
15-
16-
/**
17-
* All Auxiliary fields.
18-
*/
19-
export const AUXILIARY_FIELDS = [TRANSACTION_FIELD_NAME, GUARD_FIELD_NAME];
20-
216
/**
227
* Reasons for a CRUD operation to fail
238
*/

packages/runtime/src/enhancements/policy/policy-utils.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { lowerCaseFirst } from 'lower-case-first';
55
import { upperCaseFirst } from 'upper-case-first';
66
import { fromZodError } from 'zod-validation-error';
77
import {
8-
AUXILIARY_FIELDS,
98
CrudFailureReason,
109
FIELD_LEVEL_READ_CHECKER_PREFIX,
1110
FIELD_LEVEL_READ_CHECKER_SELECTOR,
@@ -952,13 +951,6 @@ export class PolicyUtil {
952951
return;
953952
}
954953

955-
// strip auxiliary fields
956-
for (const auxField of AUXILIARY_FIELDS) {
957-
if (auxField in entityData) {
958-
delete entityData[auxField];
959-
}
960-
}
961-
962954
for (const [field, fieldData] of Object.entries(entityData)) {
963955
if (fieldData === undefined) {
964956
continue;

packages/runtime/src/enhancements/utils.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@
33
import { lowerCaseFirst } from 'lower-case-first';
44
import path from 'path';
55
import * as util from 'util';
6-
import { AUXILIARY_FIELDS } from '../constants';
76
import { DbClientContract } from '../types';
87
import { ModelMeta } from './types';
98

109
/**
1110
* Gets field names in a data model entity, filtering out internal fields.
1211
*/
1312
export function getModelFields(data: object) {
14-
return data ? Object.keys(data).filter((f) => !AUXILIARY_FIELDS.includes(f)) : [];
13+
return data ? Object.keys(data) : [];
1514
}
1615

1716
/**

packages/schema/src/cli/config.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1-
import { GUARD_FIELD_NAME, TRANSACTION_FIELD_NAME } from '@zenstackhq/sdk';
21
import fs from 'fs';
32
import z, { ZodError } from 'zod';
43
import { fromZodError } from 'zod-validation-error';
54
import { CliError } from './cli-error';
65

7-
const schema = z
8-
.object({
9-
guardFieldName: z.string().default(GUARD_FIELD_NAME),
10-
transactionFieldName: z.string().default(TRANSACTION_FIELD_NAME),
11-
})
12-
.strict();
6+
// TODO: future use
7+
const schema = z.object({});
138

149
export type ConfigType = z.infer<typeof schema>;
1510

packages/schema/src/plugins/access-policy/expression-writer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ export class ExpressionWriter {
559559
// TODO: do we need short-circuit for logical operators?
560560

561561
if (operator === '&&') {
562-
// // && short-circuit: left && right -> left ? right : { zenstack_guard: false }
562+
// // && short-circuit: left && right -> left ? right : FALSE
563563
// if (!this.hasFieldAccess(expr.left)) {
564564
// this.plain(expr.left);
565565
// this.writer.write(' ? ');
@@ -573,7 +573,7 @@ export class ExpressionWriter {
573573
});
574574
// }
575575
} else {
576-
// // || short-circuit: left || right -> left ? { zenstack_guard: true } : right
576+
// // || short-circuit: left || right -> left ? TRUE : right
577577
// if (!this.hasFieldAccess(expr.left)) {
578578
// this.plain(expr.left);
579579
// this.writer.write(' ? ');

packages/schema/src/plugins/prisma/prisma-builder.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { AUXILIARY_FIELDS } from '@zenstackhq/sdk';
21
import indentString from './indent-string';
32

43
/**
@@ -155,19 +154,16 @@ export class Model extends ContainerDeclaration {
155154
}
156155

157156
toString(): string {
158-
const auxiliaryFields = this.fields.filter((f) => AUXILIARY_FIELDS.includes(f.name));
159157
// eslint-disable-next-line @typescript-eslint/no-explicit-any
160-
const result: any[] = this.fields.filter((f) => !AUXILIARY_FIELDS.includes(f.name));
161-
162-
if (auxiliaryFields.length > 0) {
163-
// Add a blank line before the auxiliary fields
164-
result.push('', ...auxiliaryFields);
165-
if (this.attributes.length > 0) {
166-
// Add a blank line before the attributes
167-
result.push('');
168-
}
158+
const result: any[] = [...this.fields];
159+
160+
if (this.attributes.length > 0) {
161+
// Add a blank line before the attributes
162+
result.push('');
169163
}
164+
170165
result.push(...this.attributes);
166+
171167
return (
172168
super.toString() +
173169
`${this.isView ? 'view' : 'model'} ${this.name} {\n` +

packages/schema/src/plugins/prisma/schema-generator.ts

Lines changed: 3 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,14 @@ import { match } from 'ts-pattern';
2727

2828
import { PRISMA_MINIMUM_VERSION } from '@zenstackhq/runtime';
2929
import {
30-
analyzePolicies,
31-
getDataModels,
3230
getDMMF,
3331
getLiteral,
3432
getLiteralArray,
3533
getPrismaVersion,
36-
GUARD_FIELD_NAME,
3734
PluginError,
3835
PluginOptions,
3936
resolved,
4037
resolvePath,
41-
TRANSACTION_FIELD_NAME,
4238
} from '@zenstackhq/sdk';
4339
import fs from 'fs';
4440
import { writeFile } from 'fs/promises';
@@ -85,7 +81,7 @@ export default class PrismaSchemaGenerator {
8581
8682
`;
8783

88-
async generate(model: Model, options: PluginOptions, config?: Record<string, string>) {
84+
async generate(model: Model, options: PluginOptions, _config?: Record<string, string>) {
8985
const warnings: string[] = [];
9086

9187
const prismaVersion = getPrismaVersion();
@@ -108,7 +104,7 @@ export default class PrismaSchemaGenerator {
108104
break;
109105

110106
case DataModel:
111-
this.generateModel(prisma, decl as DataModel, config);
107+
this.generateModel(prisma, decl as DataModel);
112108
break;
113109

114110
case GeneratorDecl:
@@ -296,53 +292,12 @@ export default class PrismaSchemaGenerator {
296292
}
297293
}
298294

299-
private generateModel(prisma: PrismaModel, decl: DataModel, config?: Record<string, string>) {
295+
private generateModel(prisma: PrismaModel, decl: DataModel) {
300296
const model = decl.isView ? prisma.addView(decl.name) : prisma.addModel(decl.name);
301297
for (const field of decl.fields) {
302298
this.generateModelField(model, field);
303299
}
304300

305-
if (this.shouldGenerateAuxFields(decl)) {
306-
// generate auxiliary fields for policy check
307-
308-
// add an "zenstack_guard" field for dealing with boolean conditions
309-
const guardField = model.addField(GUARD_FIELD_NAME, 'Boolean', [
310-
new PrismaFieldAttribute('@default', [
311-
new PrismaAttributeArg(undefined, new PrismaAttributeArgValue('Boolean', true)),
312-
]),
313-
]);
314-
315-
if (config?.guardFieldName && config?.guardFieldName !== GUARD_FIELD_NAME) {
316-
// generate a @map to rename field in the database
317-
guardField.addAttribute('@map', [
318-
new PrismaAttributeArg(undefined, new PrismaAttributeArgValue('String', config.guardFieldName)),
319-
]);
320-
}
321-
322-
// add an "zenstack_transaction" field for tracking records created/updated with nested writes
323-
const transactionField = model.addField(TRANSACTION_FIELD_NAME, 'String?');
324-
325-
// create an index for "zenstack_transaction" field
326-
model.addAttribute('@@index', [
327-
new PrismaAttributeArg(
328-
undefined,
329-
new PrismaAttributeArgValue('Array', [
330-
new PrismaAttributeArgValue('FieldReference', TRANSACTION_FIELD_NAME),
331-
])
332-
),
333-
]);
334-
335-
if (config?.transactionFieldName && config?.transactionFieldName !== TRANSACTION_FIELD_NAME) {
336-
// generate a @map to rename field in the database
337-
transactionField.addAttribute('@map', [
338-
new PrismaAttributeArg(
339-
undefined,
340-
new PrismaAttributeArgValue('String', config.transactionFieldName)
341-
),
342-
]);
343-
}
344-
}
345-
346301
for (const attr of decl.attributes.filter((attr) => this.isPrismaAttribute(attr))) {
347302
this.generateContainerAttribute(model, attr);
348303
}
@@ -355,44 +310,6 @@ export default class PrismaSchemaGenerator {
355310
decl.comments.forEach((c) => model.addComment(c));
356311
}
357312

358-
private shouldGenerateAuxFields(decl: DataModel) {
359-
if (decl.isView) {
360-
return false;
361-
}
362-
363-
const { allowAll, denyAll, hasFieldValidation } = analyzePolicies(decl);
364-
365-
if (!allowAll && !denyAll) {
366-
// has policy conditions
367-
return true;
368-
}
369-
370-
if (hasFieldValidation) {
371-
return true;
372-
}
373-
374-
// check if the model is related by other models, if so
375-
// aux fields are needed for nested queries
376-
const root = decl.$container;
377-
for (const model of getDataModels(root)) {
378-
if (model === decl) {
379-
continue;
380-
}
381-
for (const field of model.fields) {
382-
if (field.type.reference?.ref === decl) {
383-
// found a relation with policies
384-
const otherPolicies = analyzePolicies(model);
385-
if ((!otherPolicies.allowAll && !otherPolicies.denyAll) || otherPolicies.hasFieldValidation) {
386-
// the relating side has policies
387-
return true;
388-
}
389-
}
390-
}
391-
}
392-
393-
return false;
394-
}
395-
396313
private isPrismaAttribute(attr: DataModelAttribute | DataModelFieldAttribute) {
397314
if (!attr.decl.ref) {
398315
return false;

packages/schema/src/plugins/zod/generator.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { ConnectorType, DMMF } from '@prisma/generator-helper';
22
import {
3-
AUXILIARY_FIELDS,
43
PluginOptions,
54
createProject,
65
emitProject,
@@ -120,18 +119,6 @@ async function generateCommonSchemas(project: Project, output: string) {
120119
`
121120
import { z } from 'zod';
122121
export const DecimalSchema = z.union([z.number(), z.string(), z.object({d: z.number().array(), e: z.number(), s: z.number()}).passthrough()]);
123-
124-
// https://stackoverflow.com/a/54487392/20415796
125-
type OmitDistributive<T, K extends PropertyKey> = T extends any ? (T extends object ? OmitRecursively<T, K> : T) : never;
126-
type OmitRecursively<T extends any, K extends PropertyKey> = Omit<
127-
{ [P in keyof T]: OmitDistributive<T[P], K> },
128-
K
129-
>;
130-
131-
/**
132-
* Strips auxiliary fields recursively
133-
*/
134-
export type Purge<T> = OmitRecursively<T, ${AUXILIARY_FIELDS.map((f) => "'" + f + "'").join('|')}>;
135122
`,
136123
{ overwrite: true }
137124
);
@@ -197,10 +184,8 @@ async function generateModelSchema(model: DataModel, project: Project, output: s
197184
sf.replaceWithText((writer) => {
198185
const fields = model.fields.filter(
199186
(field) =>
200-
!AUXILIARY_FIELDS.includes(field.name) &&
201187
// scalar fields only
202-
!isDataModel(field.type.reference?.ref) &&
203-
!isForeignKeyField(field)
188+
!isDataModel(field.type.reference?.ref) && !isForeignKeyField(field)
204189
);
205190

206191
writer.writeLine('/* eslint-disable */');

0 commit comments

Comments
 (0)