Skip to content

Commit 74c4bda

Browse files
committed
Merge branch 'alpha' of github.com:parse-community/parse-server into moumouls/allow-to-skip-verify-server-url
# Conflicts: # src/ParseServer.ts
2 parents 32b27db + 8006a9e commit 74c4bda

File tree

12 files changed

+129
-19
lines changed

12 files changed

+129
-19
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,6 @@ lib/
6161

6262
# Redis Dump
6363
dump.rdb
64+
65+
# AI agents
66+
.claude

changelogs/CHANGELOG_alpha.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
1+
# [8.3.0-alpha.10](https://github.com/parse-community/parse-server/compare/8.3.0-alpha.9...8.3.0-alpha.10) (2025-10-22)
2+
3+
4+
### Bug Fixes
5+
6+
* Error in `afterSave` trigger for `Parse.Role` due to `name` field ([#9883](https://github.com/parse-community/parse-server/issues/9883)) ([eb052d8](https://github.com/parse-community/parse-server/commit/eb052d8e6abe1ae32505fd068d5445eaf950a770))
7+
8+
# [8.3.0-alpha.9](https://github.com/parse-community/parse-server/compare/8.3.0-alpha.8...8.3.0-alpha.9) (2025-10-19)
9+
10+
11+
### Bug Fixes
12+
13+
* Server URL verification before server is ready ([#9882](https://github.com/parse-community/parse-server/issues/9882)) ([178bd5c](https://github.com/parse-community/parse-server/commit/178bd5c5e258d9501c9ac4d35a3a105ab64be67e))
14+
15+
# [8.3.0-alpha.8](https://github.com/parse-community/parse-server/compare/8.3.0-alpha.7...8.3.0-alpha.8) (2025-10-16)
16+
17+
18+
### Bug Fixes
19+
20+
* Warning logged when setting option `databaseOptions.disableIndexFieldValidation` ([#9880](https://github.com/parse-community/parse-server/issues/9880)) ([1815b01](https://github.com/parse-community/parse-server/commit/1815b019b52565d2bc87be2596a49aea7600aeba))
21+
122
# [8.3.0-alpha.7](https://github.com/parse-community/parse-server/compare/8.3.0-alpha.6...8.3.0-alpha.7) (2025-10-15)
223

324

package-lock.json

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

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "parse-server",
3-
"version": "8.3.0-alpha.7",
3+
"version": "8.3.0-alpha.10",
44
"description": "An express module providing a Parse-compatible API server",
55
"main": "lib/index.js",
66
"repository": {

spec/CloudCodeLogger.spec.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe('Cloud Code Logger', () => {
2525
})
2626
.then(() => {
2727
return Parse.User.signUp('tester', 'abc')
28-
.catch(() => {})
28+
.catch(() => { })
2929
.then(loggedInUser => (user = loggedInUser))
3030
.then(() => Parse.User.logIn(user.get('username'), 'abc'));
3131
})
@@ -139,7 +139,7 @@ describe('Cloud Code Logger', () => {
139139
});
140140

141141
it_id('9857e15d-bb18-478d-8a67-fdaad3e89565')(it)('should log an afterSave', done => {
142-
Parse.Cloud.afterSave('MyObject', () => {});
142+
Parse.Cloud.afterSave('MyObject', () => { });
143143
new Parse.Object('MyObject')
144144
.save()
145145
.then(() => {
@@ -271,7 +271,7 @@ describe('Cloud Code Logger', () => {
271271
});
272272

273273
Parse.Cloud.run('aFunction', { foo: 'bar' })
274-
.catch(() => {})
274+
.catch(() => { })
275275
.then(() => {
276276
const logs = spy.calls.all().reverse();
277277
expect(logs[0].args[1]).toBe('Parse error: ');
@@ -384,8 +384,8 @@ describe('Cloud Code Logger', () => {
384384
Parse.Cloud.beforeSave('TestClassError', () => {
385385
throw new Error('Failed');
386386
});
387-
Parse.Cloud.beforeSave('TestClass', () => {});
388-
Parse.Cloud.afterSave('TestClass', () => {});
387+
Parse.Cloud.beforeSave('TestClass', () => { });
388+
Parse.Cloud.afterSave('TestClass', () => { });
389389

390390
spy = spyOn(Config.get('test').loggerController.adapter, 'log').and.callThrough();
391391

spec/ParseConfigKey.spec.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ describe('Config Keys', () => {
8181
connectTimeoutMS: 5000,
8282
socketTimeoutMS: 5000,
8383
autoSelectFamily: true,
84-
autoSelectFamilyAttemptTimeout: 3000
84+
autoSelectFamilyAttemptTimeout: 3000,
85+
disableIndexFieldValidation: true
8586
},
8687
})).toBeResolved();
8788
expect(loggerErrorSpy.calls.all().reduce((s, call) => s += call.args[0], '')).not.toMatch(invalidKeyErrorMessage);

spec/ParseRole.spec.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,4 +601,78 @@ describe('Parse Role testing', () => {
601601
});
602602
});
603603
});
604+
605+
it('should trigger afterSave hook when using Parse.Role', async () => {
606+
const afterSavePromise = new Promise(resolve => {
607+
Parse.Cloud.afterSave(Parse.Role, req => {
608+
expect(req.object).toBeDefined();
609+
expect(req.object.get('name')).toBe('AnotherTestRole');
610+
resolve();
611+
});
612+
});
613+
614+
const acl = new Parse.ACL();
615+
acl.setPublicReadAccess(true);
616+
const role = new Parse.Role('AnotherTestRole', acl);
617+
618+
const savedRole = await role.save({}, { useMasterKey: true });
619+
expect(savedRole.id).toBeDefined();
620+
621+
await afterSavePromise;
622+
});
623+
624+
it('should trigger beforeSave hook and allow modifying role in beforeSave', async () => {
625+
Parse.Cloud.beforeSave(Parse.Role, req => {
626+
// Add a custom field in beforeSave
627+
req.object.set('customField', 'addedInBeforeSave');
628+
});
629+
630+
const acl = new Parse.ACL();
631+
acl.setPublicReadAccess(true);
632+
const role = new Parse.Role('ModifiedRole', acl);
633+
634+
const savedRole = await role.save({}, { useMasterKey: true });
635+
expect(savedRole.id).toBeDefined();
636+
expect(savedRole.get('customField')).toBe('addedInBeforeSave');
637+
});
638+
639+
it('should trigger beforeSave hook using Parse.Role', async () => {
640+
let beforeSaveCalled = false;
641+
642+
Parse.Cloud.beforeSave(Parse.Role, req => {
643+
beforeSaveCalled = true;
644+
expect(req.object).toBeDefined();
645+
expect(req.object.get('name')).toBe('BeforeSaveWithClassRef');
646+
});
647+
648+
const acl = new Parse.ACL();
649+
acl.setPublicReadAccess(true);
650+
const role = new Parse.Role('BeforeSaveWithClassRef', acl);
651+
652+
const savedRole = await role.save({}, { useMasterKey: true });
653+
expect(savedRole.id).toBeDefined();
654+
expect(beforeSaveCalled).toBe(true);
655+
});
656+
657+
it('should allow modifying role name in beforeSave hook', async () => {
658+
Parse.Cloud.beforeSave(Parse.Role, req => {
659+
// Modify the role name in beforeSave
660+
if (req.object.get('name') === 'OriginalName') {
661+
req.object.set('name', 'ModifiedName');
662+
}
663+
});
664+
665+
const acl = new Parse.ACL();
666+
acl.setPublicReadAccess(true);
667+
const role = new Parse.Role('OriginalName', acl);
668+
669+
const savedRole = await role.save({}, { useMasterKey: true });
670+
expect(savedRole.id).toBeDefined();
671+
expect(savedRole.get('name')).toBe('ModifiedName');
672+
673+
// Verify the name was actually saved to the database
674+
const query = new Parse.Query(Parse.Role);
675+
const fetchedRole = await query.get(savedRole.id, { useMasterKey: true });
676+
expect(fetchedRole.get('name')).toBe('ModifiedName');
677+
});
604678
});

src/Options/Definitions.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,12 @@ module.exports.DatabaseOptions = {
10991099
'The MongoDB driver option to specify the amount of time, in milliseconds, to wait to establish a single TCP socket connection to the server before raising an error. Specifying 0 disables the connection timeout.',
11001100
action: parsers.numberParser('connectTimeoutMS'),
11011101
},
1102+
disableIndexFieldValidation: {
1103+
env: 'PARSE_SERVER_DATABASE_DISABLE_INDEX_FIELD_VALIDATION',
1104+
help:
1105+
'Set to `true` to disable validation of index fields. When disabled, indexes can be created even if the fields do not exist in the schema. This can be useful when creating indexes on fields that will be added later.',
1106+
action: parsers.booleanParser,
1107+
},
11021108
enableSchemaHooks: {
11031109
env: 'PARSE_SERVER_DATABASE_ENABLE_SCHEMA_HOOKS',
11041110
help:

src/Options/docs.js

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

src/Options/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ export interface ParseServerOptions {
348348
:DEFAULT: [] */
349349
rateLimit: ?(RateLimitOptions[]);
350350
/* Options to customize the request context using inversion of control/dependency injection.*/
351-
requestContextMiddleware: ?((req: any, res: any, next: any) => void);
351+
requestContextMiddleware: ?(req: any, res: any, next: any) => void;
352352
}
353353

354354
export interface RateLimitOptions {
@@ -634,6 +634,8 @@ export interface DatabaseOptions {
634634
autoSelectFamily: ?boolean;
635635
/* The MongoDB driver option to specify the amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the autoSelectFamily option. If set to a positive integer less than 10, the value 10 is used instead. */
636636
autoSelectFamilyAttemptTimeout: ?number;
637+
/* Set to `true` to disable validation of index fields. When disabled, indexes can be created even if the fields do not exist in the schema. This can be useful when creating indexes on fields that will be added later. */
638+
disableIndexFieldValidation: ?boolean;
637639
}
638640

639641
export interface AuthAdapter {

0 commit comments

Comments
 (0)