Skip to content

Commit

Permalink
Fix flow errors
Browse files Browse the repository at this point in the history
  • Loading branch information
sadortun committed Nov 1, 2021
1 parent cd6fb50 commit 63422fc
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 33 deletions.
76 changes: 48 additions & 28 deletions src/SchemaMigrations/DefinedSchemas.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// @flow
// @flow-disable-next Cannot resolve module `parse/node`.
const Parse = require('parse/node');
import { logger } from '../logger';
import Config from '../Config';
Expand All @@ -13,6 +14,7 @@ export class DefinedSchemas {
localSchemas: Migrations.JSONSchema[];
retries: number;
maxRetries: number;
allCloudSchemas: Parse.Schema[];

constructor(schemaOptions: Migrations.SchemaOptions, config: ParseServerOptions) {
this.localSchemas = [];
Expand Down Expand Up @@ -63,13 +65,13 @@ export class DefinedSchemas {
async execute() {
try {
logger.info('Running Migrations');
if (this.schemaOptions?.beforeMigration) {
if (this.schemaOptions && this.schemaOptions.beforeMigration) {
await Promise.resolve(this.schemaOptions.beforeMigration());
}

await this.executeMigrations();

if (this.schemaOptions?.afterMigration) {
if (this.schemaOptions && this.schemaOptions.afterMigration) {
await Promise.resolve(this.schemaOptions.afterMigration());
}

Expand Down Expand Up @@ -148,11 +150,11 @@ export class DefinedSchemas {
}

// Required for testing purpose
wait(time) {
return new Promise(resolve => setTimeout(resolve, time));
wait(time: number) {
return new Promise<void>(resolve => setTimeout(resolve, time));
}

async enforceCLPForNonProvidedClass(): void {
async enforceCLPForNonProvidedClass(): Promise<void> {
const nonProvidedClasses = this.allCloudSchemas.filter(
cloudSchema =>
!this.localSchemas.some(localSchema => localSchema.className === cloudSchema.className)
Expand Down Expand Up @@ -198,14 +200,16 @@ export class DefinedSchemas {
Object.keys(localSchema.fields)
.filter(fieldName => !this.isProtectedFields(localSchema.className, fieldName))
.forEach(fieldName => {
const field = localSchema.fields[fieldName];
this.handleFields(newLocalSchema, fieldName, field);
if (localSchema.fields) {
const field = localSchema.fields[fieldName];
this.handleFields(newLocalSchema, fieldName, field);
}
});
}
// Handle indexes
if (localSchema.indexes) {
Object.keys(localSchema.indexes).forEach(indexName => {
if (!this.isProtectedIndex(localSchema.className, indexName)) {
if (localSchema.indexes && !this.isProtectedIndex(localSchema.className, indexName)) {
newLocalSchema.addIndex(indexName, localSchema.indexes[indexName]);
}
});
Expand All @@ -225,16 +229,19 @@ export class DefinedSchemas {
Object.keys(localSchema.fields)
.filter(fieldName => !this.isProtectedFields(localSchema.className, fieldName))
.forEach(fieldName => {
// @flow-disable-next
const field = localSchema.fields[fieldName];
if (!cloudSchema.fields[fieldName]) this.handleFields(newLocalSchema, fieldName, field);
if (!cloudSchema.fields[fieldName]) {
this.handleFields(newLocalSchema, fieldName, field);
}
});
}

const fieldsToDelete: string[] = [];
const fieldsToRecreate: {
fieldName: string,
from: { type: string, targetClass: string },
to: { type: string, targetClass: string },
from: { type: string, targetClass?: string },
to: { type: string, targetClass?: string },
}[] = [];
const fieldsWithChangedParams: string[] = [];

Expand Down Expand Up @@ -294,8 +301,10 @@ export class DefinedSchemas {
await this.updateSchemaToDB(newLocalSchema);

fieldsToRecreate.forEach(fieldInfo => {
const field = localSchema.fields[fieldInfo.fieldName];
this.handleFields(newLocalSchema, fieldInfo.fieldName, field);
if (localSchema.fields) {
const field = localSchema.fields[fieldInfo.fieldName];
this.handleFields(newLocalSchema, fieldInfo.fieldName, field);
}
});
} else if (this.schemaOptions.strict === true && fieldsToRecreate.length) {
fieldsToRecreate.forEach(field => {
Expand All @@ -310,8 +319,10 @@ export class DefinedSchemas {
}

fieldsWithChangedParams.forEach(fieldName => {
const field = localSchema.fields[fieldName];
this.handleFields(newLocalSchema, fieldName, field);
if (localSchema.fields) {
const field = localSchema.fields[fieldName];
this.handleFields(newLocalSchema, fieldName, field);
}
});

// Handle Indexes
Expand All @@ -321,8 +332,11 @@ export class DefinedSchemas {
if (
(!cloudSchema.indexes || !cloudSchema.indexes[indexName]) &&
!this.isProtectedIndex(localSchema.className, indexName)
)
newLocalSchema.addIndex(indexName, localSchema.indexes[indexName]);
) {
if (localSchema.indexes) {
newLocalSchema.addIndex(indexName, localSchema.indexes[indexName]);
}
}
});
}

Expand All @@ -338,10 +352,12 @@ export class DefinedSchemas {
!this.paramsAreEquals(localSchema.indexes[indexName], cloudSchema.indexes[indexName])
) {
newLocalSchema.deleteIndex(indexName);
indexesToAdd.push({
indexName,
index: localSchema.indexes[indexName],
});
if (localSchema.indexes) {
indexesToAdd.push({
indexName,
index: localSchema.indexes[indexName],
});
}
}
}
});
Expand All @@ -360,25 +376,29 @@ export class DefinedSchemas {
}
}

handleCLP(localSchema: Migrations.JSONSchema, newLocalSchema: Parse.Schema, cloudSchema) {
handleCLP(
localSchema: Migrations.JSONSchema,
newLocalSchema: Parse.Schema,
cloudSchema: Parse.Schema
) {
if (!localSchema.classLevelPermissions && !cloudSchema) {
logger.warn(`classLevelPermissions not provided for ${localSchema.className}.`);
}
// Use spread to avoid read only issue (encountered by Moumouls using directAccess)
const clp = { ...localSchema.classLevelPermissions } || {};
const clp = ({ ...localSchema.classLevelPermissions } || {}: Parse.CLP.PermissionsMap);
// To avoid inconsistency we need to remove all rights on addField
clp.addField = {};
newLocalSchema.setCLP(clp);
}

isProtectedFields(className, fieldName) {
isProtectedFields(className: string, fieldName: string) {
return (
!!defaultColumns._Default[fieldName] ||
!!(defaultColumns[className] && defaultColumns[className][fieldName])
);
}

isProtectedIndex(className, indexName) {
isProtectedIndex(className: string, indexName: string) {
let indexes = ['_id_'];
if (className === '_User') {
indexes = [
Expand All @@ -393,9 +413,9 @@ export class DefinedSchemas {
return indexes.indexOf(indexName) !== -1;
}

paramsAreEquals<T>(objA: T, objB: T) {
const keysA = Object.keys(objA);
const keysB = Object.keys(objB);
paramsAreEquals<T: { [key: string]: any }>(objA: T, objB: T) {
const keysA: string[] = Object.keys(objA);
const keysB: string[] = Object.keys(objB);

// Check key name
if (keysA.length !== keysB.length) return false;
Expand Down
9 changes: 4 additions & 5 deletions src/SchemaMigrations/Migrations.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,11 @@ export interface JSONSchema {
}

export class CLP {
static allow(perms: CLPData): CLPInterface {
static allow(perms: { [key: string]: CLPData }): CLPInterface {
const out = {};

for (const [perm, ops] of Object.entries(perms)) {
// @flow-disable-next Property `@@iterator` is missing in mixed [1] but exists in `$Iterable` [2].
for (const op of ops) {
out[op] = out[op] || {};
out[op][perm] = true;
Expand All @@ -88,9 +89,7 @@ export function makeSchema(className: ClassNameType, schema: JSONSchema): JSONSc
// This function solve two things:
// 1. It provides auto-completion to the users who are implementing schemas
// 2. It allows forward-compatible point in order to allow future changes to the internal structure of JSONSchema without affecting all the users
schema.className = className;

return {
className,
...schema,
};
return schema;
}

0 comments on commit 63422fc

Please sign in to comment.