-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
feat(repository-json-schema): add an option to make properties optional #3309
Conversation
48efa13
to
e11e73a
Compare
} | ||
|
||
it('makes one property optional when the option "optional" includes one property', () => { | ||
const originalSchema = getJsonSchema(Product); |
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.
@nabdelgadir A question for the generic type T
in this PR: if you don't specify the type when calling getJsonSchema(ModelCtor)
, then where is it provided?
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.
I think TS 3.5.x defaults to unknown
.
let suffix = ''; | ||
if (options.partial) { | ||
suffix += 'Partial'; | ||
} | ||
if (options.optional && options.optional.length) { | ||
suffix += 'Optional[' + options.optional + ']'; | ||
} | ||
if (options.includeRelations) { | ||
suffix += 'WithRelations'; | ||
} |
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.
Would it be simpler to have the title as:
<originalModelName>:<stringified-json-for-options>
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.
Please note the suffix is used in JSON/OpenAPI Schema titles. These titles are later used by code generators like swagger-codegen to emit interface or class names in TypeScript/Java/C#/etc.
While it may be easier for us to build the prefix as stringified json, I believe it will provide suboptimal experience for our users and anybody consuming OpenAPI spec generated by LB4 applications.
@@ -232,13 +232,27 @@ describe('build-schema', () => { | |||
expect(key).to.equal('modelPartial'); | |||
}); | |||
|
|||
it('returns concatenated option names otherwise', () => { | |||
it('returns "optional[id,_rev]" when a single option "optional" is set', () => { |
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.
The test name is misleading, you are setting two properties as optional.
it('returns "optional[id,_rev]" when a single option "optional" is set', () => { | |
it('returns "optional[id,_rev]" when "optional" is set with two items', () => { |
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.
So this is supposed to mean only the optional
option is set (similar to the partial
test above it: returns "partial" when a single option "partial" is set'
), but I'll reword this one.
const key = buildModelCacheKey({ | ||
// important: object keys are defined in reverse order |
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.
Please preserve this comment in the test it('returns concatenated option names otherwise', () => {
it('returns concatenated option names otherwise', () => { | ||
const key = buildModelCacheKey({ | ||
partial: true, | ||
optional: ['id', '_rev'], |
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.
When partial
is set to true
, the optional
config is effectively ignored, because all properties are optional.
Should we tell the user that they are may be doing something wrong? Personally, I would throw an error if both partial
and optional
are set.
Regardless of the solution we choose, please add a test to verify what happens when both partial
and optional
are set.
On Slack, we discussed an alternative solution: instead of adding optional?: (keyof T)[];
, we can modify partial
to accept boolean | keyof T)[]
. This removes the edge case where both optional and partial are set. My concern was that this solution may be more difficult to understand for our users.
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.
The reason I opted to use optional
is because I felt the name partial
might be confusing. If you set partial
to [prop1, prop2]
then it might make it seem like these are the only two properties required and the rest are optional. What do you think?
I'll modify the test based on the approach.
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.
I agree with @nabdelgadir that partial: ['a', 'b']
can be misleading.
IMO, partial: true
becomes a shortcut of optional
to mark all properties optional. My intuitive interpretation is the more specific one wins, i.e., optional: ['a', 'b']
should override partial: true
. WDYT?
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.
I agree. I think optional
should override partial
as well.
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.
I agree. I think
optional
should overridepartial
as well.
Makes sense 👍
I feel it's important to describe this rule in (API) docs and have a test to verify the behavior.
d83d9e6
to
4cbaafd
Compare
"@types/json-schema": "^7.0.3" | ||
"@types/json-schema": "^7.0.3", | ||
"debug": "^4.1.1", | ||
"@types/debug": "^4.1.4" |
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.
Nitpick: it's good enough to be a dev dep.
); | ||
}); | ||
|
||
it('doesn\'t make properties optional when the option "optional" includes no properties', () => { |
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.
Nitpick: we can use ` to quote the string to avoid escaping, such as:
`doesn't make properties optional when the option "optional" includes no properties`
4cbaafd
to
d28bb56
Compare
Add a new option `optional: []` so that `getJsonSchema` and related helpers can request a model schema that marks specified properties as optional
d28bb56
to
0e383fc
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.
I agree. I think
optional
should overridepartial
as well.Makes sense 👍
I feel it's important to describe this rule in (API) docs and have a test to verify the behavior.
@nabdelgadir I see that you have included the test, that's great!
Can you please update the API docs to describe the precedence rule for partial
and optional
too? I think it would be best to mention it in API docs for both options.
expect(optionalNothingSchema.title).to.equal('Product'); | ||
}); | ||
|
||
it('overrides "partial" option when "optional" options is set', () => { |
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.
👍
Add a new option
optional: []
so thatgetJsonSchema
and related helpers can request a model schema that marks specified properties as optionalConnect to #2653
Checklist
👉 Read and sign the CLA (Contributor License Agreement) 👈
npm test
passes on your machinepackages/cli
were updatedexamples/*
were updated👉 Check out how to submit a PR 👈