-
-
Notifications
You must be signed in to change notification settings - Fork 17
externalIdMapping: optionally allow using mapped unique index names #612
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
Conversation
📝 WalkthroughWalkthroughUpdates ID resolution so single-field external-id mappings return the external ID field name (e.g., Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ce745ac to
4391157
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/server/src/api/rest/index.ts`:
- Around line 1343-1356: The single-field unique mapping branch uses
infoTyped.type (which is the field type, not the field name) when calling
requireField, causing lookups like requireField(model, infoTyped.type) to fail;
change that call to use the unique key name (the loop variable name) i.e. call
requireField(model, name) for the single-field case in the block that checks
typeof infoTyped.type === 'string' (symbols: externalIdMapping, modelLower,
modelDef.uniqueFields, infoTyped.type, requireField).
🧹 Nitpick comments (1)
packages/server/test/api/rest.test.ts (1)
3094-3211: Add regression test for string mapping to a single unique field.Current cases cover compound key names and array-based mappings, but not
{ User: 'email_with_underscore' }(string), which is expected behavior. Adding that case will prevent regressions.✅ Suggested test addition
+ it('works with id mapping (single column as string)', async () => { + client = await createTestClient(schema); + const _handler = new RestApiHandler({ + schema: client.$schema, + endpoint: 'http://localhost/api', + externalIdMapping: { + User: 'email_with_underscore', + }, + }); + handler = (args) => _handler.handleRequest({ ...args, url: new URL(`http://localhost/${args.path}`) }); + + await client.user.create({ + data: { id: 4, name: 'User4', source: 'd', email_with_underscore: 'e4' }, + }); + + const r = await handler({ + method: 'get', + path: '/user/e4', + query: {}, + client, + }); + expect(r.status).toBe(200); + expect(r.body.data.attributes.email_with_underscore).toBe('e4'); + });
4391157 to
cd7a0cf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/server/src/api/rest/index.ts`:
- Around line 1339-1369: The externalIdMapping resolution currently returns
fields (in the string fallback and Array paths) without ensuring they form a
unique or id constraint, which can cause downstream findUnique to fail; update
the logic in the externalIdMapping handling (the branches that return via
this.requireField(model, ...) and the Array.isArray(externalId) branch) to
validate that the resolved FieldDef names are either all part of
modelDef.idFields or match one of modelDef.uniqueFields compound keys (use
modelDef.uniqueFields entries and modelDef.idFields to check uniqueness), and if
they do not form a unique constraint throw a clear Error indicating the mapping
is not a unique/id key for the model (keep the existing unique-name handling
unchanged but add this validation before returning).
cd7a0cf to
a73882f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/server/src/api/rest/index.ts (1)
1336-1385: Uniqueness validation is order‑sensitive for array mappings.
If a caller provides['source', 'name']for a valid unique set defined as[name, source], this rejects it even though it’s still unique. Consider comparing sets (or document the required order).✅ Possible fix (order‑insensitive uniqueness check)
- const resolvedNames = resolved.map((f) => f.name); + const resolvedNames = resolved.map((f) => f.name); + const resolvedSet = new Set(resolvedNames); + if (resolvedSet.size !== resolvedNames.length) { + throw new Error(`Model ${model} externalIdMapping cannot contain duplicate fields`); + } const uniqueSets = this.getUniqueFieldSets(model); const isUnique = - uniqueSets.some( - (set) => set.length === resolvedNames.length && set.every((f, i) => f === resolvedNames[i]), - ) || - (modelDef.idFields.length === resolvedNames.length && - modelDef.idFields.every((f, i) => f === resolvedNames[i])); + uniqueSets.some( + (set) => set.length === resolvedSet.size && set.every((f) => resolvedSet.has(f)), + ) || + (modelDef.idFields.length === resolvedSet.size && + modelDef.idFields.every((f) => resolvedSet.has(f)));
🧹 Nitpick comments (2)
packages/server/src/api/rest/index.ts (1)
63-69: Remove the outdated externalIdMapping doc line.
Two consecutive doc blocks describe different semantics; the first still says “unique field name,” which is now misleading. Keep only the updated description.packages/server/test/api/rest.test.ts (1)
3086-3211: Add coverage for the string form of single‑field underscore IDs.
The original bug also hitsexternalIdMapping: { User: 'email_with_underscore' }. The current test uses the array form (already covered by the compound‑array test). Consider switching this case (or adding a new one) to the string form.🧪 Minimal test tweak
- const _handler = new RestApiHandler({ + const _handler = new RestApiHandler({ schema: client.$schema, endpoint: 'http://localhost/api', externalIdMapping: { - User: ['email_with_underscore'], + User: 'email_with_underscore', }, });
a73882f to
4490ead
Compare
|
I will double check what is going wrong here. |
ad75af4 to
68642ba
Compare
ymc9
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @lsmith77 , thanks for working on this. I've left a few comments.
68642ba to
ec7c5f3
Compare
ec7c5f3 to
2371d8f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/server/src/api/rest/index.ts`:
- Around line 1341-1374: The @@unique(map: ...) handling currently only
processes compound keys (fieldsArg.value.items.length > 1) and ignores
single-field mapped uniques; update the branch that inspects uniqueAttr and
fieldsArg so that when fieldsArg.value.items.length === 1 you extract the single
field name using the same logic used for compound items (inspect item.field or
item.value.name, validate against modelDef.fields, throw the same Invalid unique
field mapping error on failure) and then return this.requireField(model,
fieldName); ensure you reuse the same symbols (externalIdName, uniqueAttr,
fieldsArg, modelDef, requireField, model) and keep the error behavior consistent
with the existing compound-path.
🧹 Nitpick comments (1)
packages/server/test/api/rest.test.ts (1)
3296-3305: Test name implies array input, but the mapping is a string.Consider renaming to reflect the mapped compound unique name to avoid confusion.
✏️ Suggested rename
- it('works with externalIdMapping as array of fields (compound unique index)', async () => { + it('works with externalIdMapping using mapped compound unique name', async () => {
2371d8f to
d231a54
Compare
are the tests currently flaky? BTW: I tried a different approach that felt cleaner than allowing both strings and arrays by adding support for mapped unique index names. It is a lot of code though as |
d231a54 to
3828b75
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/server/src/api/rest/index.ts`:
- Around line 1343-1371: The leading comment "// 1. Model-level @@unique(map:
...) (compound keys only)" is now inaccurate because the code checks
fieldsArg.value.items.length >= 1 and thus supports single-field unique
mappings; update that comment near the block handling modelDef.attributes (the
uniqueAttr/fieldsArg logic) to indicate it supports single-field and compound
keys (e.g., "Model-level @@unique(map: ...) (single-field or compound keys)") so
future readers of the uniqueAttr / fieldsArg / requireField handling for model
and externalIdName see the correct behavior.
🧹 Nitpick comments (1)
packages/server/test/api/rest.test.ts (1)
3203-3222: Make the single‑field mapped‑name coverage explicit.
Becauseshort_titleis both the field name and the map name, this test would still pass without the new map‑resolution logic. Consider using a distinct map name so the test proves the new behavior.🧪 Suggested tweak
- short_title String `@unique`(map: "short_title") + short_title String `@unique`(map: "image_short_title") @@ - Image: 'short_title', + Image: 'image_short_title',
3828b75 to
88c3ded
Compare
|
@ymc9 could you have another look at this PR? |
cd6bce6 to
8d161a2
Compare
ymc9
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @lsmith77 , sorry for the delay. Please check my additional comments.
9b90b4b to
aa381ab
Compare
aa381ab to
06b561e
Compare
|
@ymc9 I have reduced the scope of the PR to just the most obvious bug fix. |
Awesome! Merging it and will release v3.3 shortly. |
so the actual bug is more trivial and somehow my brain totally misfired in the initial analysis.
fixes #611
Summary by CodeRabbit
New Features
Bug Fixes
Tests
✏️ Tip: You can customize this high-level summary in your review settings.