fix(prettier): Properly handle lint-stage files (#6970)

Now handles top level files and recursive files in folders.

Set max line length to be 100
This commit is contained in:
Diamond Lewis
2020-10-25 15:06:58 -05:00
committed by GitHub
parent c2f2281e6d
commit e6ac3b6932
178 changed files with 5585 additions and 10688 deletions

View File

@@ -52,27 +52,20 @@ export class AdaptableController {
}
// Makes sure the prototype matches
const mismatches = Object.getOwnPropertyNames(Type.prototype).reduce(
(obj, key) => {
const adapterType = typeof adapter[key];
const expectedType = typeof Type.prototype[key];
if (adapterType !== expectedType) {
obj[key] = {
expected: expectedType,
actual: adapterType,
};
}
return obj;
},
{}
);
const mismatches = Object.getOwnPropertyNames(Type.prototype).reduce((obj, key) => {
const adapterType = typeof adapter[key];
const expectedType = typeof Type.prototype[key];
if (adapterType !== expectedType) {
obj[key] = {
expected: expectedType,
actual: adapterType,
};
}
return obj;
}, {});
if (Object.keys(mismatches).length > 0) {
throw new Error(
"Adapter prototype don't match expected prototype",
adapter,
mismatches
);
throw new Error("Adapter prototype don't match expected prototype", adapter, mismatches);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -31,14 +31,12 @@ export class FilesController extends AdaptableController {
}
const location = this.adapter.getFileLocation(config, filename);
return this.adapter
.createFile(filename, data, contentType, options)
.then(() => {
return Promise.resolve({
url: location,
name: filename,
});
return this.adapter.createFile(filename, data, contentType, options).then(() => {
return Promise.resolve({
url: location,
name: filename,
});
});
}
deleteFile(config, filename) {
@@ -80,16 +78,10 @@ export class FilesController extends AdaptableController {
} else {
if (filename.indexOf('tfss-') === 0) {
fileObject['url'] =
'http://files.parsetfss.com/' +
config.fileKey +
'/' +
encodeURIComponent(filename);
'http://files.parsetfss.com/' + config.fileKey + '/' + encodeURIComponent(filename);
} else if (legacyFilesRegex.test(filename)) {
fileObject['url'] =
'http://files.parse.com/' +
config.fileKey +
'/' +
encodeURIComponent(filename);
'http://files.parse.com/' + config.fileKey + '/' + encodeURIComponent(filename);
} else {
fileObject['url'] = this.adapter.getFileLocation(config, filename);
}

View File

@@ -36,9 +36,7 @@ export class HooksController {
}
getFunction(functionName) {
return this._getHooks({ functionName: functionName }).then(
results => results[0]
);
return this._getHooks({ functionName: functionName }).then(results => results[0]);
}
getFunctions() {
@@ -73,14 +71,12 @@ export class HooksController {
}
_getHooks(query = {}) {
return this.database
.find(DefaultHooksCollectionName, query)
.then(results => {
return results.map(result => {
delete result.objectId;
return result;
});
return this.database.find(DefaultHooksCollectionName, query).then(results => {
return results.map(result => {
delete result.objectId;
return result;
});
});
}
_removeHooks(query) {
@@ -109,19 +105,9 @@ export class HooksController {
var wrappedFunction = wrapToHTTPRequest(hook, this._webhookKey);
wrappedFunction.url = hook.url;
if (hook.className) {
triggers.addTrigger(
hook.triggerName,
hook.className,
wrappedFunction,
this._applicationId
);
triggers.addTrigger(hook.triggerName, hook.className, wrappedFunction, this._applicationId);
} else {
triggers.addFunction(
hook.functionName,
wrappedFunction,
null,
this._applicationId
);
triggers.addFunction(hook.functionName, wrappedFunction, null, this._applicationId);
}
}
@@ -158,26 +144,21 @@ export class HooksController {
if (aHook.functionName) {
return this.getFunction(aHook.functionName).then(result => {
if (result) {
throw new Parse.Error(
143,
`function name: ${aHook.functionName} already exits`
);
throw new Parse.Error(143, `function name: ${aHook.functionName} already exits`);
} else {
return this.createOrUpdateHook(aHook);
}
});
} else if (aHook.className && aHook.triggerName) {
return this.getTrigger(aHook.className, aHook.triggerName).then(
result => {
if (result) {
throw new Parse.Error(
143,
`class ${aHook.className} already has trigger ${aHook.triggerName}`
);
}
return this.createOrUpdateHook(aHook);
return this.getTrigger(aHook.className, aHook.triggerName).then(result => {
if (result) {
throw new Parse.Error(
143,
`class ${aHook.className} already has trigger ${aHook.triggerName}`
);
}
);
return this.createOrUpdateHook(aHook);
});
}
throw new Parse.Error(143, 'invalid hook declaration');
@@ -189,20 +170,15 @@ export class HooksController {
if (result) {
return this.createOrUpdateHook(aHook);
}
throw new Parse.Error(
143,
`no function named: ${aHook.functionName} is defined`
);
throw new Parse.Error(143, `no function named: ${aHook.functionName} is defined`);
});
} else if (aHook.className && aHook.triggerName) {
return this.getTrigger(aHook.className, aHook.triggerName).then(
result => {
if (result) {
return this.createOrUpdateHook(aHook);
}
throw new Parse.Error(143, `class ${aHook.className} does not exist`);
return this.getTrigger(aHook.className, aHook.triggerName).then(result => {
if (result) {
return this.createOrUpdateHook(aHook);
}
);
throw new Parse.Error(143, `class ${aHook.className} does not exist`);
});
}
throw new Parse.Error(143, 'invalid hook declaration');
}
@@ -231,17 +207,13 @@ function wrapToHTTPRequest(hook, key) {
method: 'POST',
};
const agent = hook.url.startsWith('https')
? HTTPAgents['https']
: HTTPAgents['http'];
const agent = hook.url.startsWith('https') ? HTTPAgents['https'] : HTTPAgents['http'];
jsonRequest.agent = agent;
if (key) {
jsonRequest.headers['X-Parse-Webhook-Key'] = key;
} else {
logger.warn(
'Making outgoing webhook request without webhookKey being set!'
);
logger.warn('Making outgoing webhook request without webhookKey being set!');
}
return request(jsonRequest).then(response => {
let err;

View File

@@ -25,11 +25,7 @@ export class LiveQueryController {
if (!this.hasLiveQuery(className)) {
return;
}
const req = this._makePublisherRequest(
currentObject,
originalObject,
classLevelPermissions
);
const req = this._makePublisherRequest(currentObject, originalObject, classLevelPermissions);
this.liveQueryPublisher.onCloudCodeAfterSave(req);
}
@@ -42,11 +38,7 @@ export class LiveQueryController {
if (!this.hasLiveQuery(className)) {
return;
}
const req = this._makePublisherRequest(
currentObject,
originalObject,
classLevelPermissions
);
const req = this._makePublisherRequest(currentObject, originalObject, classLevelPermissions);
this.liveQueryPublisher.onCloudCodeAfterDelete(req);
}
@@ -54,11 +46,7 @@ export class LiveQueryController {
return this.classNames.has(className);
}
_makePublisherRequest(
currentObject: any,
originalObject: any,
classLevelPermissions: ?any
): any {
_makePublisherRequest(currentObject: any, originalObject: any, classLevelPermissions: ?any): any {
const req = {
object: currentObject,
};

View File

@@ -189,8 +189,7 @@ export class LoggerController extends AdaptableController {
truncateLogMessage(string) {
if (string && string.length > LOG_STRING_TRUNCATE_LENGTH) {
const truncated =
string.substring(0, LOG_STRING_TRUNCATE_LENGTH) + truncationMarker;
const truncated = string.substring(0, LOG_STRING_TRUNCATE_LENGTH) + truncationMarker;
return truncated;
}
@@ -224,10 +223,7 @@ export class LoggerController extends AdaptableController {
// size (optional) Number of rows returned by search. Defaults to 10
getLogs(options = {}) {
if (!this.adapter) {
throw new Parse.Error(
Parse.Error.PUSH_MISCONFIGURED,
'Logger adapter is not available'
);
throw new Parse.Error(Parse.Error.PUSH_MISCONFIGURED, 'Logger adapter is not available');
}
if (typeof this.adapter.query !== 'function') {
throw new Parse.Error(

View File

@@ -57,9 +57,7 @@ class ParseGraphQLController {
return graphQLConfig;
}
async updateGraphQLConfig(
graphQLConfig: ParseGraphQLConfig
): Promise<ParseGraphQLConfig> {
async updateGraphQLConfig(graphQLConfig: ParseGraphQLConfig): Promise<ParseGraphQLConfig> {
// throws if invalid
this._validateGraphQLConfig(
graphQLConfig || requiredParameter('You must provide a graphQLConfig!')
@@ -97,11 +95,7 @@ class ParseGraphQLController {
}
_putCachedGraphQLConfig(graphQLConfig: ParseGraphQLConfig) {
return this.cacheController.graphQL.put(
this.configCacheKey,
graphQLConfig,
60000
);
return this.cacheController.graphQL.put(this.configCacheKey, graphQLConfig, 60000);
}
_validateGraphQLConfig(graphQLConfig: ?ParseGraphQLConfig): void {
@@ -119,20 +113,12 @@ class ParseGraphQLController {
} = graphQLConfig;
if (Object.keys(invalidKeys).length) {
errorMessages.push(
`encountered invalid keys: [${Object.keys(invalidKeys)}]`
);
errorMessages.push(`encountered invalid keys: [${Object.keys(invalidKeys)}]`);
}
if (
enabledForClasses !== null &&
!isValidStringArray(enabledForClasses)
) {
if (enabledForClasses !== null && !isValidStringArray(enabledForClasses)) {
errorMessages.push(`"enabledForClasses" is not a valid array`);
}
if (
disabledForClasses !== null &&
!isValidStringArray(disabledForClasses)
) {
if (disabledForClasses !== null && !isValidStringArray(disabledForClasses)) {
errorMessages.push(`"disabledForClasses" is not a valid array`);
}
if (classConfigs !== null) {
@@ -159,17 +145,9 @@ class ParseGraphQLController {
if (!isValidSimpleObject(classConfig)) {
return 'it must be a valid object';
} else {
const {
className,
type = null,
query = null,
mutation = null,
...invalidKeys
} = classConfig;
const { className, type = null, query = null, mutation = null, ...invalidKeys } = classConfig;
if (Object.keys(invalidKeys).length) {
return `"invalidKeys" [${Object.keys(
invalidKeys
)}] should not be present`;
return `"invalidKeys" [${Object.keys(invalidKeys)}] should not be present`;
}
if (typeof className !== 'string' || !className.trim().length) {
// TODO consider checking class exists in schema?
@@ -190,10 +168,7 @@ class ParseGraphQLController {
return `"type" contains invalid keys, [${Object.keys(invalidKeys)}]`;
} else if (outputFields !== null && !isValidStringArray(outputFields)) {
return `"outputFields" must be a valid string array`;
} else if (
constraintFields !== null &&
!isValidStringArray(constraintFields)
) {
} else if (constraintFields !== null && !isValidStringArray(constraintFields)) {
return `"constraintFields" must be a valid string array`;
}
if (sortFields !== null) {
@@ -214,10 +189,7 @@ class ParseGraphQLController {
if (typeof field !== 'string' || field.trim().length === 0) {
errorMessage = `"sortField" at index ${index} did not provide the "field" as a string`;
return false;
} else if (
typeof asc !== 'boolean' ||
typeof desc !== 'boolean'
) {
} else if (typeof asc !== 'boolean' || typeof desc !== 'boolean') {
errorMessage = `"sortField" at index ${index} did not provide "asc" or "desc" as booleans`;
return false;
}
@@ -234,15 +206,9 @@ class ParseGraphQLController {
}
if (inputFields !== null) {
if (isValidSimpleObject(inputFields)) {
const {
create = null,
update = null,
...invalidKeys
} = inputFields;
const { create = null, update = null, ...invalidKeys } = inputFields;
if (Object.keys(invalidKeys).length) {
return `"inputFields" contains invalid keys: [${Object.keys(
invalidKeys
)}]`;
return `"inputFields" contains invalid keys: [${Object.keys(invalidKeys)}]`;
} else {
if (update !== null && !isValidStringArray(update)) {
return `"inputFields.update" must be a valid string array`;
@@ -250,10 +216,7 @@ class ParseGraphQLController {
if (!isValidStringArray(create)) {
return `"inputFields.create" must be a valid string array`;
} else if (className === '_User') {
if (
!create.includes('username') ||
!create.includes('password')
) {
if (!create.includes('username') || !create.includes('password')) {
return `"inputFields.create" must include required fields, username and password`;
}
}
@@ -274,9 +237,7 @@ class ParseGraphQLController {
...invalidKeys
} = query;
if (Object.keys(invalidKeys).length) {
return `"query" contains invalid keys, [${Object.keys(
invalidKeys
)}]`;
return `"query" contains invalid keys, [${Object.keys(invalidKeys)}]`;
} else if (find !== null && typeof find !== 'boolean') {
return `"query.find" must be a boolean`;
} else if (get !== null && typeof get !== 'boolean') {
@@ -302,9 +263,7 @@ class ParseGraphQLController {
...invalidKeys
} = mutation;
if (Object.keys(invalidKeys).length) {
return `"mutation" contains invalid keys, [${Object.keys(
invalidKeys
)}]`;
return `"mutation" contains invalid keys, [${Object.keys(invalidKeys)}]`;
}
if (create !== null && typeof create !== 'boolean') {
return `"mutation.create" must be a boolean`;

View File

@@ -6,19 +6,9 @@ import { pushStatusHandler } from '../StatusHandler';
import { applyDeviceTokenExists } from '../Push/utils';
export class PushController {
sendPush(
body = {},
where = {},
config,
auth,
onPushStatusSaved = () => {},
now = new Date()
) {
sendPush(body = {}, where = {}, config, auth, onPushStatusSaved = () => {}, now = new Date()) {
if (!config.hasPushSupport) {
throw new Parse.Error(
Parse.Error.PUSH_MISCONFIGURED,
'Missing push configuration'
);
throw new Parse.Error(Parse.Error.PUSH_MISCONFIGURED, 'Missing push configuration');
}
// Replace the expiration_time and push_time with a valid Unix epoch milliseconds time
@@ -32,10 +22,7 @@ export class PushController {
}
// Immediate push
if (
body.expiration_interval &&
!Object.prototype.hasOwnProperty.call(body, 'push_time')
) {
if (body.expiration_interval && !Object.prototype.hasOwnProperty.call(body, 'push_time')) {
const ttlMs = body.expiration_interval * 1000;
body.expiration_time = new Date(now.valueOf() + ttlMs).valueOf();
}
@@ -73,12 +60,7 @@ export class PushController {
const updateWhere = applyDeviceTokenExists(where);
badgeUpdate = () => {
// Build a real RestQuery so we can use it in RestWrite
const restQuery = new RestQuery(
config,
master(config),
'_Installation',
updateWhere
);
const restQuery = new RestQuery(config, master(config), '_Installation', updateWhere);
return restQuery.buildRestWhere().then(() => {
const write = new RestWrite(
config,
@@ -129,13 +111,7 @@ export class PushController {
) {
return Promise.resolve();
}
return config.pushControllerQueue.enqueue(
body,
where,
config,
auth,
pushStatus
);
return config.pushControllerQueue.enqueue(body, where, config, auth, pushStatus);
})
.catch(err => {
return pushStatus.fail(err).then(() => {
@@ -150,10 +126,7 @@ export class PushController {
* @returns {Number|undefined} The expiration time if it exists in the request
*/
static getExpirationTime(body = {}) {
var hasExpirationTime = Object.prototype.hasOwnProperty.call(
body,
'expiration_time'
);
var hasExpirationTime = Object.prototype.hasOwnProperty.call(body, 'expiration_time');
if (!hasExpirationTime) {
return;
}
@@ -180,19 +153,13 @@ export class PushController {
}
static getExpirationInterval(body = {}) {
const hasExpirationInterval = Object.prototype.hasOwnProperty.call(
body,
'expiration_interval'
);
const hasExpirationInterval = Object.prototype.hasOwnProperty.call(body, 'expiration_interval');
if (!hasExpirationInterval) {
return;
}
var expirationIntervalParam = body['expiration_interval'];
if (
typeof expirationIntervalParam !== 'number' ||
expirationIntervalParam <= 0
) {
if (typeof expirationIntervalParam !== 'number' || expirationIntervalParam <= 0) {
throw new Parse.Error(
Parse.Error.PUSH_MISCONFIGURED,
`expiration_interval must be a number greater than 0`
@@ -248,8 +215,7 @@ export class PushController {
static pushTimeHasTimezoneComponent(pushTimeParam: string): boolean {
const offsetPattern = /(.+)([+-])\d\d:\d\d$/;
return (
pushTimeParam.indexOf('Z') === pushTimeParam.length - 1 || // 2007-04-05T12:30Z
offsetPattern.test(pushTimeParam)
pushTimeParam.indexOf('Z') === pushTimeParam.length - 1 || offsetPattern.test(pushTimeParam) // 2007-04-05T12:30Z
); // 2007-04-05T12:30.000+02:00, 2007-04-05T12:30.000-02:00
}
@@ -259,13 +225,7 @@ export class PushController {
* @param isLocalTime {boolean}
* @returns {string}
*/
static formatPushTime({
date,
isLocalTime,
}: {
date: Date,
isLocalTime: boolean,
}) {
static formatPushTime({ date, isLocalTime }: { date: Date, isLocalTime: boolean }) {
if (isLocalTime) {
// Strip 'Z'
const isoString = date.toISOString();

View File

@@ -7,11 +7,7 @@ import defaults from '../defaults';
export default class SchemaCache {
cache: Object;
constructor(
cacheController,
ttl = defaults.schemaCacheTTL,
singleCache = false
) {
constructor(cacheController, ttl = defaults.schemaCacheTTL, singleCache = false) {
this.ttl = ttl;
if (typeof ttl == 'string') {
this.ttl = parseInt(ttl);

View File

@@ -260,11 +260,7 @@ const CLPValidKeys = Object.freeze([
]);
// validation before setting class-level permissions on collection
function validateCLP(
perms: ClassLevelPermissions,
fields: SchemaFields,
userIdRegExp: RegExp
) {
function validateCLP(perms: ClassLevelPermissions, fields: SchemaFields, userIdRegExp: RegExp) {
if (!perms) {
return;
}
@@ -282,10 +278,7 @@ function validateCLP(
// throws when root fields are of wrong type
validateCLPjson(operation, operationKey);
if (
operationKey === 'readUserFields' ||
operationKey === 'writeUserFields'
) {
if (operationKey === 'readUserFields' || operationKey === 'writeUserFields') {
// validate grouped pointer permissions
// must be an array with field names
for (const fieldName of operation) {
@@ -397,11 +390,7 @@ function validateCLPjson(operation: any, operationKey: string) {
}
}
function validatePointerPermission(
fieldName: string,
fields: Object,
operation: string
) {
function validatePointerPermission(fieldName: string, fields: Object, operation: string) {
// Uses collection schema to ensure the field is of type:
// - Pointer<_User> (pointers)
// - Array
@@ -412,8 +401,7 @@ function validatePointerPermission(
if (
!(
fields[fieldName] &&
((fields[fieldName].type == 'Pointer' &&
fields[fieldName].targetClass == '_User') ||
((fields[fieldName].type == 'Pointer' && fields[fieldName].targetClass == '_User') ||
fields[fieldName].type == 'Array')
)
) {
@@ -444,10 +432,7 @@ function fieldNameIsValid(fieldName: string): boolean {
}
// Checks that it's not trying to clobber one of the default fields of the class.
function fieldNameIsValidForClass(
fieldName: string,
className: string
): boolean {
function fieldNameIsValidForClass(fieldName: string, className: string): boolean {
if (!fieldNameIsValid(fieldName)) {
return false;
}
@@ -468,10 +453,7 @@ function invalidClassNameMessage(className: string): string {
);
}
const invalidJsonError = new Parse.Error(
Parse.Error.INVALID_JSON,
'invalid JSON'
);
const invalidJsonError = new Parse.Error(Parse.Error.INVALID_JSON, 'invalid JSON');
const validNonRelationOrPointerTypes = [
'Number',
'String',
@@ -492,10 +474,7 @@ const fieldTypeIsInvalid = ({ type, targetClass }) => {
} else if (typeof targetClass !== 'string') {
return invalidJsonError;
} else if (!classNameIsValid(targetClass)) {
return new Parse.Error(
Parse.Error.INVALID_CLASS_NAME,
invalidClassNameMessage(targetClass)
);
return new Parse.Error(Parse.Error.INVALID_CLASS_NAME, invalidClassNameMessage(targetClass));
} else {
return undefined;
}
@@ -504,10 +483,7 @@ const fieldTypeIsInvalid = ({ type, targetClass }) => {
return invalidJsonError;
}
if (validNonRelationOrPointerTypes.indexOf(type) < 0) {
return new Parse.Error(
Parse.Error.INCORRECT_TYPE,
`invalid field type: ${type}`
);
return new Parse.Error(Parse.Error.INCORRECT_TYPE, `invalid field type: ${type}`);
}
return undefined;
};
@@ -563,18 +539,14 @@ class SchemaData {
data.classLevelPermissions = deepcopy(schema.classLevelPermissions);
data.indexes = schema.indexes;
const classProtectedFields = this.__protectedFields[
schema.className
];
const classProtectedFields = this.__protectedFields[schema.className];
if (classProtectedFields) {
for (const key in classProtectedFields) {
const unq = new Set([
...(data.classLevelPermissions.protectedFields[key] || []),
...classProtectedFields[key],
]);
data.classLevelPermissions.protectedFields[key] = Array.from(
unq
);
data.classLevelPermissions.protectedFields[key] = Array.from(unq);
}
}
@@ -608,12 +580,7 @@ class SchemaData {
}
}
const injectDefaultSchema = ({
className,
fields,
classLevelPermissions,
indexes,
}: Schema) => {
const injectDefaultSchema = ({ className, fields, classLevelPermissions, indexes }: Schema) => {
const defaultSchema: Schema = {
className,
fields: {
@@ -684,10 +651,7 @@ const VolatileClassesSchemas = [
_IdempotencySchema,
];
const dbTypeMatchesObjectType = (
dbType: SchemaField | string,
objectType: SchemaField
) => {
const dbTypeMatchesObjectType = (dbType: SchemaField | string, objectType: SchemaField) => {
if (dbType.type !== objectType.type) return false;
if (dbType.targetClass !== objectType.targetClass) return false;
if (dbType === objectType.type) return true;
@@ -749,9 +713,7 @@ export default class SchemaController {
return this.reloadDataPromise;
}
getAllClasses(
options: LoadSchemaOptions = { clearCache: false }
): Promise<Array<Schema>> {
getAllClasses(options: LoadSchemaOptions = { clearCache: false }): Promise<Array<Schema>> {
if (options.clearCache) {
return this.setAllClasses();
}
@@ -771,9 +733,7 @@ export default class SchemaController {
/* eslint-disable no-console */
this._cache
.setAllClasses(allSchemas)
.catch(error =>
console.error('Error saving schema to cache:', error)
);
.catch(error => console.error('Error saving schema to cache:', error));
/* eslint-enable no-console */
return allSchemas;
});
@@ -803,9 +763,7 @@ export default class SchemaController {
return Promise.resolve(cached);
}
return this.setAllClasses().then(allSchemas => {
const oneSchema = allSchemas.find(
schema => schema.className === className
);
const oneSchema = allSchemas.find(schema => schema.className === className);
if (!oneSchema) {
return Promise.reject(undefined);
}
@@ -828,18 +786,12 @@ export default class SchemaController {
classLevelPermissions: any,
indexes: any = {}
): Promise<void | Schema> {
var validationError = this.validateNewClass(
className,
fields,
classLevelPermissions
);
var validationError = this.validateNewClass(className, fields, classLevelPermissions);
if (validationError) {
if (validationError instanceof Parse.Error) {
return Promise.reject(validationError);
} else if (validationError.code && validationError.error) {
return Promise.reject(
new Parse.Error(validationError.code, validationError.error)
);
return Promise.reject(new Parse.Error(validationError.code, validationError.error));
}
return Promise.reject(validationError);
}
@@ -883,21 +835,14 @@ export default class SchemaController {
throw new Parse.Error(255, `Field ${name} exists, cannot update.`);
}
if (!existingFields[name] && field.__op === 'Delete') {
throw new Parse.Error(
255,
`Field ${name} does not exist, cannot delete.`
);
throw new Parse.Error(255, `Field ${name} does not exist, cannot delete.`);
}
});
delete existingFields._rperm;
delete existingFields._wperm;
const newSchema = buildMergedSchemaObject(
existingFields,
submittedFields
);
const defaultFields =
defaultColumns[className] || defaultColumns._Default;
const newSchema = buildMergedSchemaObject(existingFields, submittedFields);
const defaultFields = defaultColumns[className] || defaultColumns._Default;
const fullNewSchema = Object.assign({}, newSchema, defaultFields);
const validationError = this.validateSchemaData(
className,
@@ -938,11 +883,7 @@ export default class SchemaController {
})
.then(results => {
enforceFields = results.filter(result => !!result);
return this.setPermissions(
className,
classLevelPermissions,
newSchema
);
return this.setPermissions(className, classLevelPermissions, newSchema);
})
.then(() =>
this._dbAdapter.setIndexesWithSchemaFormat(
@@ -1004,32 +945,19 @@ export default class SchemaController {
if (this.schemaData[className]) {
return this;
} else {
throw new Parse.Error(
Parse.Error.INVALID_JSON,
`Failed to add ${className}`
);
throw new Parse.Error(Parse.Error.INVALID_JSON, `Failed to add ${className}`);
}
})
.catch(() => {
// The schema still doesn't validate. Give up
throw new Parse.Error(
Parse.Error.INVALID_JSON,
'schema class name does not revalidate'
);
throw new Parse.Error(Parse.Error.INVALID_JSON, 'schema class name does not revalidate');
})
);
}
validateNewClass(
className: string,
fields: SchemaFields = {},
classLevelPermissions: any
): any {
validateNewClass(className: string, fields: SchemaFields = {}, classLevelPermissions: any): any {
if (this.schemaData[className]) {
throw new Parse.Error(
Parse.Error.INVALID_CLASS_NAME,
`Class ${className} already exists.`
);
throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} already exists.`);
}
if (!classNameIsValid(className)) {
return {
@@ -1037,12 +965,7 @@ export default class SchemaController {
error: invalidClassNameMessage(className),
};
}
return this.validateSchemaData(
className,
fields,
classLevelPermissions,
[]
);
return this.validateSchemaData(className, fields, classLevelPermissions, []);
}
validateSchemaData(
@@ -1072,15 +995,10 @@ export default class SchemaController {
let defaultValueType = getType(fieldType.defaultValue);
if (typeof defaultValueType === 'string') {
defaultValueType = { type: defaultValueType };
} else if (
typeof defaultValueType === 'object' &&
fieldType.type === 'Relation'
) {
} else if (typeof defaultValueType === 'object' && fieldType.type === 'Relation') {
return {
code: Parse.Error.INCORRECT_TYPE,
error: `The 'default value' option is not applicable for ${typeToString(
fieldType
)}`,
error: `The 'default value' option is not applicable for ${typeToString(fieldType)}`,
};
}
if (!dbTypeMatchesObjectType(fieldType, defaultValueType)) {
@@ -1095,9 +1013,7 @@ export default class SchemaController {
if (typeof fieldType === 'object' && fieldType.type === 'Relation') {
return {
code: Parse.Error.INCORRECT_TYPE,
error: `The 'required' option is not applicable for ${typeToString(
fieldType
)}`,
error: `The 'required' option is not applicable for ${typeToString(fieldType)}`,
};
}
}
@@ -1138,21 +1054,14 @@ export default class SchemaController {
// object if the provided className-fieldName-type tuple is valid.
// The className must already be validated.
// If 'freeze' is true, refuse to update the schema for this field.
enforceFieldExists(
className: string,
fieldName: string,
type: string | SchemaField
) {
enforceFieldExists(className: string, fieldName: string, type: string | SchemaField) {
if (fieldName.indexOf('.') > 0) {
// subdocument key (x.y) => ok if x is of type 'object'
fieldName = fieldName.split('.')[0];
type = 'Object';
}
if (!fieldNameIsValid(fieldName)) {
throw new Parse.Error(
Parse.Error.INVALID_KEY_NAME,
`Invalid field name: ${fieldName}.`
);
throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, `Invalid field name: ${fieldName}.`);
}
// If someone tries to create a new field with null/undefined as the value, return;
@@ -1222,20 +1131,13 @@ export default class SchemaController {
type = { type: type };
}
if (!expectedType || !dbTypeMatchesObjectType(expectedType, type)) {
throw new Parse.Error(
Parse.Error.INVALID_JSON,
`Could not add field ${fieldName}`
);
throw new Parse.Error(Parse.Error.INVALID_JSON, `Could not add field ${fieldName}`);
}
}
}
// maintain compatibility
deleteField(
fieldName: string,
className: string,
database: DatabaseController
) {
deleteField(fieldName: string, className: string, database: DatabaseController) {
return this.deleteFields([fieldName], className, database);
}
@@ -1246,24 +1148,14 @@ export default class SchemaController {
// Passing the database and prefix is necessary in order to drop relation collections
// and remove fields from objects. Ideally the database would belong to
// a database adapter and this function would close over it or access it via member.
deleteFields(
fieldNames: Array<string>,
className: string,
database: DatabaseController
) {
deleteFields(fieldNames: Array<string>, className: string, database: DatabaseController) {
if (!classNameIsValid(className)) {
throw new Parse.Error(
Parse.Error.INVALID_CLASS_NAME,
invalidClassNameMessage(className)
);
throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, invalidClassNameMessage(className));
}
fieldNames.forEach(fieldName => {
if (!fieldNameIsValid(fieldName)) {
throw new Parse.Error(
Parse.Error.INVALID_KEY_NAME,
`invalid field name: ${fieldName}`
);
throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, `invalid field name: ${fieldName}`);
}
//Don't allow deleting the default fields.
if (!fieldNameIsValidForClass(fieldName, className)) {
@@ -1285,30 +1177,23 @@ export default class SchemaController {
.then(schema => {
fieldNames.forEach(fieldName => {
if (!schema.fields[fieldName]) {
throw new Parse.Error(
255,
`Field ${fieldName} does not exist, cannot delete.`
);
throw new Parse.Error(255, `Field ${fieldName} does not exist, cannot delete.`);
}
});
const schemaFields = { ...schema.fields };
return database.adapter
.deleteFields(className, schema, fieldNames)
.then(() => {
return Promise.all(
fieldNames.map(fieldName => {
const field = schemaFields[fieldName];
if (field && field.type === 'Relation') {
//For relations, drop the _Join table
return database.adapter.deleteClass(
`_Join:${fieldName}:${className}`
);
}
return Promise.resolve();
})
);
});
return database.adapter.deleteFields(className, schema, fieldNames).then(() => {
return Promise.all(
fieldNames.map(fieldName => {
const field = schemaFields[fieldName];
if (field && field.type === 'Relation') {
//For relations, drop the _Join table
return database.adapter.deleteClass(`_Join:${fieldName}:${className}`);
}
return Promise.resolve();
})
);
});
})
.then(() => this._cache.clear());
}
@@ -1380,19 +1265,12 @@ export default class SchemaController {
});
if (missingColumns.length > 0) {
throw new Parse.Error(
Parse.Error.INCORRECT_TYPE,
missingColumns[0] + ' is required.'
);
throw new Parse.Error(Parse.Error.INCORRECT_TYPE, missingColumns[0] + ' is required.');
}
return Promise.resolve(this);
}
testPermissionsForClassName(
className: string,
aclGroup: string[],
operation: string
) {
testPermissionsForClassName(className: string, aclGroup: string[], operation: string) {
return SchemaController.testPermissions(
this.getClassLevelPermissions(className),
aclGroup,
@@ -1401,11 +1279,7 @@ export default class SchemaController {
}
// Tests that the class level permission let pass the operation for a given aclGroup
static testPermissions(
classPermissions: ?any,
aclGroup: string[],
operation: string
): boolean {
static testPermissions(classPermissions: ?any, aclGroup: string[], operation: string): boolean {
if (!classPermissions || !classPermissions[operation]) {
return true;
}
@@ -1432,9 +1306,7 @@ export default class SchemaController {
operation: string,
action?: string
) {
if (
SchemaController.testPermissions(classPermissions, aclGroup, operation)
) {
if (SchemaController.testPermissions(classPermissions, aclGroup, operation)) {
return Promise.resolve();
}
@@ -1465,9 +1337,7 @@ export default class SchemaController {
// No matching CLP, let's check the Pointer permissions
// And handle those later
const permissionField =
['get', 'find', 'count'].indexOf(operation) > -1
? 'readUserFields'
: 'writeUserFields';
['get', 'find', 'count'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields';
// Reject create when write lockdown
if (permissionField == 'writeUserFields' && operation == 'create') {
@@ -1501,12 +1371,7 @@ export default class SchemaController {
}
// Validates an operation passes class-level-permissions set in the schema
validatePermission(
className: string,
aclGroup: string[],
operation: string,
action?: string
) {
validatePermission(className: string, aclGroup: string[], operation: string, action?: string) {
return SchemaController.validatePermission(
this.getClassLevelPermissions(className),
className,
@@ -1517,18 +1382,12 @@ export default class SchemaController {
}
getClassLevelPermissions(className: string): any {
return (
this.schemaData[className] &&
this.schemaData[className].classLevelPermissions
);
return this.schemaData[className] && this.schemaData[className].classLevelPermissions;
}
// Returns the expected type for a className+key combination
// or undefined if the schema is not set
getExpectedType(
className: string,
fieldName: string
): ?(SchemaField | string) {
getExpectedType(className: string, fieldName: string): ?(SchemaField | string) {
if (this.schemaData[className]) {
const expectedType = this.schemaData[className].fields[fieldName];
return expectedType === 'map' ? 'Object' : expectedType;
@@ -1560,10 +1419,7 @@ const load = (
// does not include the default fields, as it is intended to be passed
// to mongoSchemaFromFieldsAndClassName. No validation is done here, it
// is done in mongoSchemaFromFieldsAndClassName.
function buildMergedSchemaObject(
existingFields: SchemaFields,
putRequest: any
): SchemaFields {
function buildMergedSchemaObject(existingFields: SchemaFields, putRequest: any): SchemaFields {
const newSchema = {};
// @flow-disable-next
const sysSchemaField =
@@ -1578,14 +1434,10 @@ function buildMergedSchemaObject(
oldField !== 'createdAt' &&
oldField !== 'objectId'
) {
if (
sysSchemaField.length > 0 &&
sysSchemaField.indexOf(oldField) !== -1
) {
if (sysSchemaField.length > 0 && sysSchemaField.indexOf(oldField) !== -1) {
continue;
}
const fieldIsDeleted =
putRequest[oldField] && putRequest[oldField].__op === 'Delete';
const fieldIsDeleted = putRequest[oldField] && putRequest[oldField].__op === 'Delete';
if (!fieldIsDeleted) {
newSchema[oldField] = existingFields[oldField];
}
@@ -1593,10 +1445,7 @@ function buildMergedSchemaObject(
}
for (const newField in putRequest) {
if (newField !== 'objectId' && putRequest[newField].__op !== 'Delete') {
if (
sysSchemaField.length > 0 &&
sysSchemaField.indexOf(newField) !== -1
) {
if (sysSchemaField.length > 0 && sysSchemaField.indexOf(newField) !== -1) {
continue;
}
newSchema[newField] = putRequest[newField];
@@ -1692,10 +1541,7 @@ function getObjectType(obj): ?(SchemaField | string) {
}
break;
}
throw new Parse.Error(
Parse.Error.INCORRECT_TYPE,
'This is not a valid ' + obj.__type
);
throw new Parse.Error(Parse.Error.INCORRECT_TYPE, 'This is not a valid ' + obj.__type);
}
if (obj['$ne']) {
return getObjectType(obj['$ne']);

View File

@@ -95,16 +95,12 @@ export class UserController extends AdaptableController {
throw 'Failed to reset password: username / email / token is invalid';
}
if (
this.config.passwordPolicy &&
this.config.passwordPolicy.resetTokenValidityDuration
) {
if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) {
let expiresDate = results[0]._perishable_token_expires_at;
if (expiresDate && expiresDate.__type == 'Date') {
expiresDate = new Date(expiresDate.iso);
}
if (expiresDate < new Date())
throw 'The password reset link has expired';
if (expiresDate < new Date()) throw 'The password reset link has expired';
}
return results[0];
@@ -123,12 +119,7 @@ export class UserController extends AdaptableController {
where.email = user.email;
}
var query = new RestQuery(
this.config,
Auth.master(this.config),
'_User',
where
);
var query = new RestQuery(this.config, Auth.master(this.config), '_User', where);
return query.execute().then(function (result) {
if (result.results.length != 1) {
throw undefined;
@@ -146,12 +137,7 @@ export class UserController extends AdaptableController {
this.getUserIfNeeded(user).then(user => {
const username = encodeURIComponent(user.username);
const link = buildEmailLink(
this.config.verifyEmailURL,
username,
token,
this.config
);
const link = buildEmailLink(this.config.verifyEmailURL, username, token, this.config);
const options = {
appName: this.config.appName,
link: link,
@@ -173,11 +159,7 @@ export class UserController extends AdaptableController {
*/
regenerateEmailVerifyToken(user) {
this.setEmailVerifyToken(user);
return this.config.database.update(
'_User',
{ username: user.username },
user
);
return this.config.database.update('_User', { username: user.username }, user);
}
resendVerificationEmail(username) {
@@ -194,10 +176,7 @@ export class UserController extends AdaptableController {
setPasswordResetToken(email) {
const token = { _perishable_token: randomString(25) };
if (
this.config.passwordPolicy &&
this.config.passwordPolicy.resetTokenValidityDuration
) {
if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) {
token._perishable_token_expires_at = Parse._encode(
this.config.generatePasswordResetTokenExpiresAt()
);
@@ -278,9 +257,7 @@ export class UserController extends AdaptableController {
'Hi,\n\n' +
'You requested to reset your password for ' +
appName +
(user.get('username')
? " (your username is '" + user.get('username') + "')"
: '') +
(user.get('username') ? " (your username is '" + user.get('username') + "')" : '') +
'.\n\n' +
'' +
'Click here to reset it:\n' +
@@ -308,10 +285,7 @@ function buildEmailLink(destination, username, token, config) {
const usernameAndToken = `token=${token}&username=${username}`;
if (config.parseFrameURL) {
const destinationWithoutHost = destination.replace(
config.publicServerURL,
''
);
const destinationWithoutHost = destination.replace(config.publicServerURL, '');
return `${config.parseFrameURL}?link=${encodeURIComponent(
destinationWithoutHost

View File

@@ -67,9 +67,7 @@ export function getControllers(options: ParseServerOptions) {
};
}
export function getLoggerController(
options: ParseServerOptions
): LoggerController {
export function getLoggerController(options: ParseServerOptions): LoggerController {
const {
appId,
jsonLogs,
@@ -88,25 +86,12 @@ export function getLoggerController(
silent,
maxLogFiles,
};
const loggerControllerAdapter = loadAdapter(
loggerAdapter,
WinstonLoggerAdapter,
loggerOptions
);
const loggerControllerAdapter = loadAdapter(loggerAdapter, WinstonLoggerAdapter, loggerOptions);
return new LoggerController(loggerControllerAdapter, appId, loggerOptions);
}
export function getFilesController(
options: ParseServerOptions
): FilesController {
const {
appId,
databaseURI,
filesAdapter,
databaseAdapter,
preserveFileName,
fileKey,
} = options;
export function getFilesController(options: ParseServerOptions): FilesController {
const { appId, databaseURI, filesAdapter, databaseAdapter, preserveFileName, fileKey } = options;
if (!filesAdapter && databaseAdapter) {
throw 'When using an explicit database adapter, you must also use an explicit filesAdapter.';
}
@@ -126,15 +111,13 @@ export function getUserController(options: ParseServerOptions): UserController {
});
}
export function getCacheController(
options: ParseServerOptions
): CacheController {
export function getCacheController(options: ParseServerOptions): CacheController {
const { appId, cacheAdapter, cacheTTL, cacheMaxSize } = options;
const cacheControllerAdapter = loadAdapter(
cacheAdapter,
InMemoryCacheAdapter,
{ appId: appId, ttl: cacheTTL, maxSize: cacheMaxSize }
);
const cacheControllerAdapter = loadAdapter(cacheAdapter, InMemoryCacheAdapter, {
appId: appId,
ttl: cacheTTL,
maxSize: cacheMaxSize,
});
return new CacheController(cacheControllerAdapter, appId);
}
@@ -148,20 +131,13 @@ export function getParseGraphQLController(
});
}
export function getAnalyticsController(
options: ParseServerOptions
): AnalyticsController {
export function getAnalyticsController(options: ParseServerOptions): AnalyticsController {
const { analyticsAdapter } = options;
const analyticsControllerAdapter = loadAdapter(
analyticsAdapter,
AnalyticsAdapter
);
const analyticsControllerAdapter = loadAdapter(analyticsAdapter, AnalyticsAdapter);
return new AnalyticsController(analyticsControllerAdapter);
}
export function getLiveQueryController(
options: ParseServerOptions
): LiveQueryController {
export function getLiveQueryController(options: ParseServerOptions): LiveQueryController {
return new LiveQueryController(options.liveQuery);
}
@@ -185,11 +161,7 @@ export function getDatabaseController(
) {
throw 'You cannot specify both a databaseAdapter and a databaseURI/databaseOptions/collectionPrefix.';
} else if (!databaseAdapter) {
databaseAdapter = getDatabaseAdapter(
databaseURI,
collectionPrefix,
databaseOptions
);
databaseAdapter = getDatabaseAdapter(databaseURI, collectionPrefix, databaseOptions);
} else {
databaseAdapter = loadAdapter(databaseAdapter);
}
@@ -214,9 +186,7 @@ interface PushControlling {
pushWorker: PushWorker;
}
export function getPushController(
options: ParseServerOptions
): PushControlling {
export function getPushController(options: ParseServerOptions): PushControlling {
const { scheduledPush, push } = options;
const pushOptions = Object.assign({}, push);
@@ -258,11 +228,7 @@ export function getAuthDataManager(options: ParseServerOptions) {
return authDataManager(auth, enableAnonymousUsers);
}
export function getDatabaseAdapter(
databaseURI,
collectionPrefix,
databaseOptions
) {
export function getDatabaseAdapter(databaseURI, collectionPrefix, databaseOptions) {
let protocol;
try {
const parsedURI = url.parse(databaseURI);