Skip to content

Commit b9e1413

Browse files
pubkeyclaude
andauthored
fix(rx-schema): clean up indexes in getJsonSchemaWithoutMeta() (#8325)
getJsonSchemaWithoutMeta() removed internal meta properties (_deleted, _rev, _meta, _attachments) from properties and required but left their references in the indexes array, producing an internally inconsistent schema. Now also filters _-prefixed fields from indexes and removes empty indexes. https://claude.ai/code/session_01JzvzrsJQH7Yp3BYqWRSQHf Co-authored-by: Claude <noreply@anthropic.com>
1 parent 32d2a69 commit b9e1413

3 files changed

Lines changed: 43 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- FIX `getJsonSchemaWithoutMeta()` not removing internal meta field references (`_deleted`, `_meta.lwt`) from indexes, while correctly removing them from properties and required, causing the returned schema to be internally inconsistent

src/rx-schema.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ export class RxSchema<RxDocType = any> {
8686
jsonSchema.required = jsonSchema.required.filter((r: string) => !r.startsWith('_'));
8787
}
8888

89+
// remove internal meta fields from indexes, consistent with properties and required cleanup
90+
if (jsonSchema.indexes) {
91+
jsonSchema.indexes = jsonSchema.indexes
92+
.map((index: string | string[]) => {
93+
const arr: string[] = isMaybeReadonlyArray(index) ? [...index] : [index];
94+
return arr.filter((field: string) => !field.startsWith('_'));
95+
})
96+
.filter((index: string[]) => index.length > 0);
97+
}
98+
8999
return jsonSchema as RxJsonSchema<RxDocumentData<RxDocType>>;
90100
}
91101

test/unit/rx-schema.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,6 +1477,38 @@ describeParallel('rx-schema.test.ts', () => {
14771477
assert.ok(propertyKeys.includes('passportId'));
14781478
assert.ok(propertyKeys.includes('age'));
14791479

1480+
await db.close();
1481+
});
1482+
it('indexes should not reference internal meta fields that are removed from properties', async () => {
1483+
const db = await createRxDatabase({
1484+
name: randomToken(10),
1485+
storage: config.storage.getStorage()
1486+
});
1487+
const collections = await db.addCollections({
1488+
humans: {
1489+
schema: schemas.human
1490+
}
1491+
});
1492+
const schemaWithoutMeta = collections.humans.schema.getJsonSchemaWithoutMeta();
1493+
const propertyKeys = Object.keys(schemaWithoutMeta.properties);
1494+
1495+
// every field referenced in an index must exist in properties
1496+
const indexes = schemaWithoutMeta.indexes as string[][];
1497+
for (const index of indexes) {
1498+
const fields = Array.isArray(index) ? index : [index];
1499+
for (const field of fields) {
1500+
const topLevelField = field.split('.')[0];
1501+
assert.ok(
1502+
propertyKeys.includes(topLevelField),
1503+
'index field "' + field + '" references property "' + topLevelField + '" which does not exist in the schema returned by getJsonSchemaWithoutMeta()'
1504+
);
1505+
}
1506+
}
1507+
1508+
// user-defined index fields should still be present
1509+
const allIndexFields = indexes.flat();
1510+
assert.ok(allIndexFields.includes('firstName'), 'user-defined index field "firstName" should be present');
1511+
14801512
await db.close();
14811513
});
14821514
});

0 commit comments

Comments
 (0)