Skip to content

Commit

Permalink
Merge pull request #373 from toddtarsi/handle-sparse-arrays
Browse files Browse the repository at this point in the history
add handling for sparse arrays
  • Loading branch information
mrjono1 authored Oct 13, 2023
2 parents 4b689fe + 768d10e commit 840a017
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 2 deletions.
10 changes: 10 additions & 0 deletions src/__tests__/array/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { existsSync, readFileSync, rmdirSync } from 'fs';
import Joi from 'joi';

import { convertFromDirectory, convertSchema } from '../../index';
import { SparseTestListSchema } from './schemas/OneSparseSchema';

describe('Array types', () => {
const typeOutputDirectory = './src/__tests__/array/interfaces';
Expand Down Expand Up @@ -70,4 +71,13 @@ export type TestList = Test[];
*/
export type TestList = string[];`);
});

test('test to ensure sparse arrays have undefined as a possible type', () => {
const result = convertSchema({ sortPropertiesByName: true }, SparseTestListSchema);
expect(result).not.toBeUndefined;
expect(result?.content).toBe(`/**
* A sparse list of Item object
*/
export type SparseTestList = (Item | undefined)[];`);
});
});
8 changes: 8 additions & 0 deletions src/__tests__/array/schemas/OneSparseSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Joi from 'joi';
import {ItemSchema} from './OneSchema'

export const SparseTestListSchema = Joi.array()
.items(ItemSchema)
.sparse()
.meta({ className: 'SparseTestList' })
.description('A sparse list of Item object');
4 changes: 4 additions & 0 deletions src/joiDescribeTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export interface BaseDescribe extends Joi.Description {
* Default object value
*/
default?: unknown;
/**
* Allow undefined values in array
*/
sparse?: boolean;
/**
* https://joi.dev/api/#objectunknownallow
*/
Expand Down
19 changes: 17 additions & 2 deletions src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ function parseStringSchema(details: StringDescribe, settings: Settings, rootSche

function parseArray(details: ArrayDescribe, settings: Settings): TypeContent | undefined {
const { interfaceOrTypeName, jsDoc } = getCommonDetails(details, settings);
const isSparse = details.flags?.sparse;

if (details.ordered && !details.items) {
const parsedChildren = details.ordered.map(item => parseSchema(item, settings)).filter(Boolean) as TypeContent[];
Expand Down Expand Up @@ -439,7 +440,6 @@ function parseArray(details: ArrayDescribe, settings: Settings): TypeContent | u

// TODO: handle multiple things in the items arr
const item = details.items && !details.ordered ? details.items[0] : ({ type: 'any' } as Describe);

const child = parseSchema(item, settings);
if (!child) {
return undefined;
Expand All @@ -454,6 +454,21 @@ function parseArray(details: ArrayDescribe, settings: Settings): TypeContent | u

return makeTypeContentRoot({ joinOperation: 'union', children: allowedValues, interfaceOrTypeName, jsDoc });
}
if (isSparse) {
return makeTypeContentRoot({
joinOperation: 'list',
children: [
makeTypeContentRoot({
joinOperation: 'union',
children: [child, makeTypeContentChild({ content: 'undefined' })],
interfaceOrTypeName,
jsDoc
})
],
interfaceOrTypeName,
jsDoc
});
}

return makeTypeContentRoot({ joinOperation: 'list', children: [child], interfaceOrTypeName, jsDoc });
}
Expand Down Expand Up @@ -481,7 +496,7 @@ function parseAlternatives(details: AlternativesDescribe, settings: Settings): T
joinOperation: 'union',
children: [...children, ...allowedValues],
interfaceOrTypeName,
jsDoc,
jsDoc
});
}

Expand Down

0 comments on commit 840a017

Please sign in to comment.