Skip to content

feat: Deprecation DEPPS7: Remove deprecated Cloud Code file trigger syntax #8855

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DEPRECATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The following is a list of deprecations, according to the [Deprecation Policy](h
| DEPPS4 | Remove convenience method for http request `Parse.Cloud.httpRequest` | [#7589](https://github.com/parse-community/parse-server/pull/7589) | 5.0.0 (2022) | 6.0.0 (2023) | removed | - |
| DEPPS5 | Config option `allowClientClassCreation` defaults to `false` | [#7925](https://github.com/parse-community/parse-server/pull/7925) | 5.3.0 (2022) | 7.0.0 (2024) | deprecated | - |
| DEPPS6 | Auth providers disabled by default | [#7953](https://github.com/parse-community/parse-server/pull/7953) | 5.3.0 (2022) | 7.0.0 (2024) | deprecated | - |
| DEPPS7 | Remove file trigger syntax `Parse.Cloud.beforeSaveFile((request) => {})` | [#7966](https://github.com/parse-community/parse-server/pull/7966) | 5.3.0 (2022) | 7.0.0 (2024) | deprecated | - |
| DEPPS7 | Remove file trigger syntax `Parse.Cloud.beforeSaveFile((request) => {})` | [#7966](https://github.com/parse-community/parse-server/pull/7966) | 5.3.0 (2022) | 7.0.0 (2024) | removed | - |
| DEPPS8 | Login with expired 3rd party authentication token defaults to `false` | [#7079](https://github.com/parse-community/parse-server/pull/7079) | 5.3.0 (2022) | 7.0.0 (2024) | deprecated | - |
| DEPPS9 | Rename LiveQuery `fields` option to `keys` | [#8389](https://github.com/parse-community/parse-server/issues/8389) | 6.0.0 (2023) | 7.0.0 (2024) | deprecated | - |
| DEPPS10 | Config option `encodeParseObjectInCloudFunction` defaults to `true` | [#8634](https://github.com/parse-community/parse-server/issues/8634) | 6.2.0 (2023) | 8.0.0 (2025) | deprecated | - |
Expand Down
81 changes: 16 additions & 65 deletions spec/CloudCode.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3635,7 +3635,7 @@ describe('afterLogin hook', () => {
});

describe('saveFile hooks', () => {
it('beforeSaveFile should return file that is already saved and not save anything to files adapter', async () => {
it('beforeSave(Parse.File) should return file that is already saved and not save anything to files adapter', async () => {
await reconfigureServer({ filesAdapter: mockAdapter });
const createFileSpy = spyOn(mockAdapter, 'createFile').and.callThrough();
Parse.Cloud.beforeSave(Parse.File, () => {
Expand All @@ -3651,7 +3651,7 @@ describe('saveFile hooks', () => {
expect(createFileSpy).not.toHaveBeenCalled();
});

it('beforeSaveFile should throw error', async () => {
it('beforeSave(Parse.File) should throw error', async () => {
await reconfigureServer({ filesAdapter: mockAdapter });
Parse.Cloud.beforeSave(Parse.File, () => {
throw new Parse.Error(400, 'some-error-message');
Expand All @@ -3664,7 +3664,7 @@ describe('saveFile hooks', () => {
}
});

it('beforeSaveFile should change values of uploaded file by editing fileObject directly', async () => {
it('beforeSave(Parse.File) should change values of uploaded file by editing fileObject directly', async () => {
await reconfigureServer({ filesAdapter: mockAdapter });
const createFileSpy = spyOn(mockAdapter, 'createFile').and.callThrough();
Parse.Cloud.beforeSave(Parse.File, async req => {
Expand Down Expand Up @@ -3693,7 +3693,7 @@ describe('saveFile hooks', () => {
);
});

it('beforeSaveFile should change values by returning new fileObject', async () => {
it('beforeSave(Parse.File) should change values by returning new fileObject', async () => {
await reconfigureServer({ filesAdapter: mockAdapter });
const createFileSpy = spyOn(mockAdapter, 'createFile').and.callThrough();
Parse.Cloud.beforeSave(Parse.File, async req => {
Expand Down Expand Up @@ -3727,7 +3727,7 @@ describe('saveFile hooks', () => {
expect(file._name.indexOf(expectedFileName)).toBe(file._name.length - expectedFileName.length);
});

it('beforeSaveFile should contain metadata and tags saved from client', async () => {
it('beforeSave(Parse.File) should contain metadata and tags saved from client', async () => {
await reconfigureServer({ filesAdapter: mockAdapter });
const createFileSpy = spyOn(mockAdapter, 'createFile').and.callThrough();
Parse.Cloud.beforeSave(Parse.File, async req => {
Expand Down Expand Up @@ -3755,7 +3755,7 @@ describe('saveFile hooks', () => {
);
});

it('beforeSaveFile should return same file data with new file name', async () => {
it('beforeSave(Parse.File) should return same file data with new file name', async () => {
await reconfigureServer({ filesAdapter: mockAdapter });
const config = Config.get('test');
config.filesController.options.preserveFileName = true;
Expand All @@ -3770,7 +3770,7 @@ describe('saveFile hooks', () => {
expect(result.name()).toBe('2020-04-01.txt');
});

it('afterSaveFile should set fileSize to null if beforeSave returns an already saved file', async () => {
it('afterSave(Parse.File) should set fileSize to null if beforeSave returns an already saved file', async () => {
await reconfigureServer({ filesAdapter: mockAdapter });
const createFileSpy = spyOn(mockAdapter, 'createFile').and.callThrough();
Parse.Cloud.beforeSave(Parse.File, req => {
Expand All @@ -3790,7 +3790,7 @@ describe('saveFile hooks', () => {
expect(createFileSpy).not.toHaveBeenCalled();
});

it('afterSaveFile should throw error', async () => {
it('afterSave(Parse.File) should throw error', async () => {
await reconfigureServer({ filesAdapter: mockAdapter });
Parse.Cloud.afterSave(Parse.File, async () => {
throw new Parse.Error(400, 'some-error-message');
Expand All @@ -3804,7 +3804,7 @@ describe('saveFile hooks', () => {
}
});

it('afterSaveFile should call with fileObject', async done => {
it('afterSave(Parse.File) should call with fileObject', async done => {
await reconfigureServer({ filesAdapter: mockAdapter });
Parse.Cloud.beforeSave(Parse.File, async req => {
req.file.setTags({ tagA: 'some-tag' });
Expand All @@ -3820,7 +3820,7 @@ describe('saveFile hooks', () => {
await file.save({ useMasterKey: true });
});

it('afterSaveFile should change fileSize when file data changes', async done => {
it('afterSave(Parse.File) should change fileSize when file data changes', async done => {
await reconfigureServer({ filesAdapter: mockAdapter });
Parse.Cloud.beforeSave(Parse.File, async req => {
expect(req.fileSize).toBe(3);
Expand All @@ -3837,7 +3837,7 @@ describe('saveFile hooks', () => {
await file.save({ useMasterKey: true });
});

it('beforeDeleteFile should call with fileObject', async () => {
it('beforeDelete(Parse.File) should call with fileObject', async () => {
await reconfigureServer({ filesAdapter: mockAdapter });
Parse.Cloud.beforeDelete(Parse.File, req => {
expect(req.file).toBeInstanceOf(Parse.File);
Expand All @@ -3849,7 +3849,7 @@ describe('saveFile hooks', () => {
await file.destroy({ useMasterKey: true });
});

it('beforeDeleteFile should throw error', async done => {
it('beforeDelete(Parse.File) should throw error', async done => {
await reconfigureServer({ filesAdapter: mockAdapter });
Parse.Cloud.beforeDelete(Parse.File, () => {
throw new Error('some error message');
Expand All @@ -3863,7 +3863,7 @@ describe('saveFile hooks', () => {
}
});

it('afterDeleteFile should call with fileObject', async done => {
it('afterDelete(Parse.File) should call with fileObject', async done => {
await reconfigureServer({ filesAdapter: mockAdapter });
Parse.Cloud.beforeDelete(Parse.File, req => {
expect(req.file).toBeInstanceOf(Parse.File);
Expand All @@ -3880,7 +3880,7 @@ describe('saveFile hooks', () => {
await file.destroy({ useMasterKey: true });
});

it('beforeSaveFile should not change file if nothing is returned', async () => {
it('beforeSave(Parse.File) should not change file if nothing is returned', async () => {
await reconfigureServer({ filesAdapter: mockAdapter });
Parse.Cloud.beforeSave(Parse.File, () => {
return;
Expand All @@ -3890,7 +3890,7 @@ describe('saveFile hooks', () => {
expect(result).toBe(file);
});

it('throw custom error from beforeSaveFile', async done => {
it('throw custom error from beforeSave(Parse.File) ', async done => {
Parse.Cloud.beforeSave(Parse.File, () => {
throw new Parse.Error(Parse.Error.SCRIPT_FAILED, 'It should fail');
});
Expand All @@ -3904,7 +3904,7 @@ describe('saveFile hooks', () => {
}
});

it('throw empty error from beforeSaveFile', async done => {
it('throw empty error from beforeSave(Parse.File)', async done => {
Parse.Cloud.beforeSave(Parse.File, () => {
throw null;
});
Expand All @@ -3917,55 +3917,6 @@ describe('saveFile hooks', () => {
done();
}
});

it('legacy hooks', async () => {
await reconfigureServer({ filesAdapter: mockAdapter });
const logger = require('../lib/logger').logger;
const logSpy = spyOn(logger, 'warn').and.callFake(() => {});
const triggers = {
beforeSaveFile(req) {
req.file.setTags({ tagA: 'some-tag' });
req.file.setMetadata({ foo: 'bar' });
expect(req.triggerName).toEqual('beforeSave');
expect(req.master).toBe(true);
},
afterSaveFile(req) {
expect(req.master).toBe(true);
expect(req.file._tags).toEqual({ tagA: 'some-tag' });
expect(req.file._metadata).toEqual({ foo: 'bar' });
},
beforeDeleteFile(req) {
expect(req.file).toBeInstanceOf(Parse.File);
expect(req.file._name).toEqual('popeye.txt');
expect(req.file._url).toEqual('http://www.somewhere.com/popeye.txt');
expect(req.fileSize).toBe(null);
},
afterDeleteFile(req) {
expect(req.file).toBeInstanceOf(Parse.File);
expect(req.file._name).toEqual('popeye.txt');
expect(req.file._url).toEqual('http://www.somewhere.com/popeye.txt');
},
};

for (const key in triggers) {
spyOn(triggers, key).and.callThrough();
Parse.Cloud[key](triggers[key]);
}

const file = new Parse.File('popeye.txt', [1, 2, 3], 'text/plain');
await file.save({ useMasterKey: true });
await new Parse.File('popeye.txt', [1, 2, 3], 'text/plain').destroy({ useMasterKey: true });
await new Promise(resolve => setTimeout(resolve, 100));
for (const key in triggers) {
expect(triggers[key]).toHaveBeenCalled();
expect(logSpy).toHaveBeenCalledWith(
`DeprecationWarning: Parse.Cloud.${key} is deprecated and will be removed in a future version. Use Parse.Cloud.${key.replace(
'File',
''
)}(Parse.File, (request) => {})`
);
}
});
});

describe('sendEmail', () => {
Expand Down
6 changes: 3 additions & 3 deletions src/Options/Definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -1063,19 +1063,19 @@ module.exports.LogLevels = {
triggerAfter: {
env: 'PARSE_SERVER_LOG_LEVELS_TRIGGER_AFTER',
help:
'Log level used by the Cloud Code Triggers `afterSave`, `afterDelete`, `afterSaveFile`, `afterDeleteFile`, `afterFind`, `afterLogout`. Default is `info`.',
'Log level used by the Cloud Code Triggers `afterSave`, `afterDelete`, `afterFind`, `afterLogout`. Default is `info`.',
default: 'info',
},
triggerBeforeError: {
env: 'PARSE_SERVER_LOG_LEVELS_TRIGGER_BEFORE_ERROR',
help:
'Log level used by the Cloud Code Triggers `beforeSave`, `beforeSaveFile`, `beforeDeleteFile`, `beforeFind`, `beforeLogin` on error. Default is `error `.',
'Log level used by the Cloud Code Triggers `beforeSave`, `beforeDelete`, `beforeFind`, `beforeLogin` on error. Default is `error`.',
default: 'error',
},
triggerBeforeSuccess: {
env: 'PARSE_SERVER_LOG_LEVELS_TRIGGER_BEFORE_SUCCESS',
help:
'Log level used by the Cloud Code Triggers `beforeSave`, `beforeSaveFile`, `beforeDeleteFile`, `beforeFind`, `beforeLogin` on success. Default is `info`.',
'Log level used by the Cloud Code Triggers `beforeSave`, `beforeDelete`, `beforeFind`, `beforeLogin` on success. Default is `info`.',
default: 'info',
},
};
6 changes: 3 additions & 3 deletions src/Options/docs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions src/Options/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -607,15 +607,15 @@ export interface AuthAdapter {
}

export interface LogLevels {
/* Log level used by the Cloud Code Triggers `afterSave`, `afterDelete`, `afterSaveFile`, `afterDeleteFile`, `afterFind`, `afterLogout`. Default is `info`.
/* Log level used by the Cloud Code Triggers `afterSave`, `afterDelete`, `afterFind`, `afterLogout`. Default is `info`.
:DEFAULT: info
*/
triggerAfter: ?string;
/* Log level used by the Cloud Code Triggers `beforeSave`, `beforeSaveFile`, `beforeDeleteFile`, `beforeFind`, `beforeLogin` on success. Default is `info`.
/* Log level used by the Cloud Code Triggers `beforeSave`, `beforeDelete`, `beforeFind`, `beforeLogin` on success. Default is `info`.
:DEFAULT: info
*/
triggerBeforeSuccess: ?string;
/* Log level used by the Cloud Code Triggers `beforeSave`, `beforeSaveFile`, `beforeDeleteFile`, `beforeFind`, `beforeLogin` on error. Default is `error `.
/* Log level used by the Cloud Code Triggers `beforeSave`, `beforeDelete`, `beforeFind`, `beforeLogin` on error. Default is `error`.
:DEFAULT: error
*/
triggerBeforeError: ?string;
Expand Down
Loading