Skip to content

Commit

Permalink
[ENG-1489] Fix uploadLocal page not populating list with 1 element (#421
Browse files Browse the repository at this point in the history
)

* Fix empty array if saved form values include empty object

* fix NPE

* add requestBodyParameter as parameter to set of parameters in generating inital form values
  • Loading branch information
dphuang2 authored Dec 19, 2023
1 parent a3fbc4f commit 99ffbca
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 66 deletions.
73 changes: 73 additions & 0 deletions generator/konfig-docs/static/konfig-yaml.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,10 @@
"outputDirectory": {
"type": "string"
},
"mockServerPort": {
"type": "number",
"description": "To configure the port of the mock server for generated tests. This will ensure that the SDK client is configured to point to the correct port on the local machine (e.g. http://127.0.0.1:{mockServerPort})."
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -800,6 +804,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -871,6 +878,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -944,6 +954,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -1125,6 +1138,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -1271,6 +1287,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -1349,6 +1368,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -1431,6 +1453,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -1499,6 +1524,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -1571,6 +1599,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -1640,6 +1671,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -1708,6 +1742,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -1802,6 +1839,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -1893,6 +1933,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -1968,6 +2011,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -2040,6 +2086,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -2176,6 +2225,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -2290,6 +2342,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -2369,6 +2424,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -2450,6 +2508,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -2522,6 +2583,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -2591,6 +2655,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -2662,6 +2729,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down Expand Up @@ -2733,6 +2803,9 @@
"outputDirectory": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/outputDirectory"
},
"mockServerPort": {
"$ref": "#/definitions/konfigYaml/properties/generators/properties/java/properties/mockServerPort"
},
"defaultChangesetBumpType": {
"$ref": "#/definitions/konfigYaml/properties/defaultChangesetBumpType"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ export function OperationReferenceMain({
requestBodyProperties,
requestBodyRequired,
}),
// Also include the request body parameter if it exists so that generating
// initial form values can leverage the request body parameter's schema.
// This was particularly helpful when I needed to implememnt initialization
// of single element in request body array type schemas
...(requestBodyParameter != null ? [requestBodyParameter] : []),
]

const theme = useMantineTheme()
Expand Down
5 changes: 2 additions & 3 deletions generator/konfig-next-app/src/utils/code-generator-python.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
API_KEY_NAME_PROPERTY,
SECURITY_TYPE_PROPERTY,
} from './generate-initial-operation-form-values'
import { recursivelyRemoveEmptyValues } from './recursively-remove-empty-values'

export class CodeGeneratorPython extends CodeGenerator {
protected async format(code: string): Promise<string> {
Expand Down Expand Up @@ -120,9 +121,7 @@ from ${this.packageName} import ${this.clientName}`

get args(): string {
if (this.isArrayRequestBody()) {
const arrayValue = this.recursivelyRemoveEmptyValues(
this.requestBodyValue()
)
const arrayValue = recursivelyRemoveEmptyValues(this.requestBodyValue())
if (Array.isArray(arrayValue)) {
return `[${arrayValue
.map((v) => this.toPythonLiteralString(v))
Expand Down
67 changes: 5 additions & 62 deletions generator/konfig-next-app/src/utils/code-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
} from './generate-initial-operation-form-values'
import { ReferencePageProps } from './generate-props-for-reference-page'
import { HttpMethods } from 'konfig-lib'
import { isNonEmpty } from './is-non-empty'
import { recursivelyRemoveEmptyValues } from './recursively-remove-empty-values'

type GitConfig = {
owner: string
Expand Down Expand Up @@ -199,7 +201,7 @@ export abstract class CodeGenerator {
* is passed as a separate argument.
*/
requestBodyValue(): FormInputValue {
return this.recursivelyRemoveEmptyValues(
return recursivelyRemoveEmptyValues(
this._formData[REQUEST_BODY_FORM_NAME_PREFIX]
)
}
Expand All @@ -217,12 +219,12 @@ export abstract class CodeGenerator {
return this.isInThisOperation(name)
})
.filter(([_name, value]) => {
return this.isNonEmpty(value)
return isNonEmpty(value)
})
.map(([name, value]) => {
return [
{ name, parameter: this.parameterStrict(name) },
this.recursivelyRemoveEmptyValues(value),
recursivelyRemoveEmptyValues(value),
]
})
}
Expand All @@ -242,65 +244,6 @@ export abstract class CodeGenerator {
return this.parameter(name) !== undefined
}

/**
* Useful for pruning tree of argument values to only those that are
* significant when constructing the SDK method call
* @param object The object to recursively remove empty values from
* @returns The object with empty values removed
*/
recursivelyRemoveEmptyValues(
object: FormInputValues[string]
): FormInputValues[string] {
if (typeof object !== 'object') return object

if (Array.isArray(object)) {
// remove all empty values from array and return
const filtered = (object as any)
.filter((p: any) => this.isNonEmpty(p))
.map((p: any) => this.recursivelyRemoveEmptyValues(p))
return filtered
}

if (object instanceof File) return object

const clone = { ...object }
Object.entries(object).forEach(([key, value]) => {
if (typeof value === 'object') {
clone[key] = this.recursivelyRemoveEmptyValues(value)
if (!this.isNonEmpty(clone[key])) delete clone[key]
} else if (!this.isNonEmpty(value)) {
delete clone[key]
}
})
return clone
}

/**
* Returns whether or not the parameter is non-empty (i.e. not undefined, not an empty string, not an empty array).
* Recursively checks if the parameter is an object and checks if any of the values are non-empty
* @param parameter The parameter to check
* @returns boolean
*/
isNonEmpty(parameter: FormInputValues[string]): boolean {
if (parameter === undefined) return false
if (!Array.isArray(parameter)) {
if (parameter instanceof File) return true
if (typeof parameter === 'object') {
return (
Object.values(parameter).filter((p) => this.isNonEmpty(p)).length > 0
)
}
return parameter !== ''
}
// filter parameter for non-empty filters
const filtered: FormInputValues[string][] = []
for (const p of parameter) {
if (this.isNonEmpty(p)) filtered.push(p)
}

return filtered.length > 0
}

nonEmptySecurityMasked(): NonEmptySecurity {
return clone(this.nonEmptySecurity()).map(([name, security]) => {
if (security.type === 'apiKey') {
Expand Down
Loading

0 comments on commit 99ffbca

Please sign in to comment.