From e1ca34319832e03368f6ca3fddcd84f0c2b3ec45 Mon Sep 17 00:00:00 2001 From: JuanGalilea Date: Tue, 24 Mar 2026 16:16:31 +0100 Subject: [PATCH 1/3] fix(generate-schema-types): change optionals to inside actor perspective --- src/lib/schema-transforms.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/lib/schema-transforms.ts b/src/lib/schema-transforms.ts index ec01f2758..7c2e80752 100644 --- a/src/lib/schema-transforms.ts +++ b/src/lib/schema-transforms.ts @@ -1,8 +1,8 @@ import { cloneDeep } from 'es-toolkit'; /** - * Transforms a JSON schema so that all properties without a `default` value are marked as required. - * Properties that have a `default` are left optional, since Apify fills them in at runtime. + * Transforms a JSON schema so that all properties with a `default` value are marked as required, since Apify fills them in at runtime. + * Properties that don't have a `default` are left optional. * Recurses into nested object properties. */ export function makePropertiesRequired(schema: Record): Record { @@ -16,10 +16,11 @@ export function makePropertiesRequired(schema: Record): Record< const requiredSet = new Set(Array.isArray(clone.required) ? (clone.required as string[]) : []); for (const [key, prop] of Object.entries(properties)) { - if (prop.default === undefined) { + if (requiredSet.has(key)) { + continue; + } + if (prop.default !== undefined) { requiredSet.add(key); - } else { - requiredSet.delete(key); } if (prop.type === 'object' && prop.properties) { From 6989fed5f6cea291fa1af523333ee4444112159d Mon Sep 17 00:00:00 2001 From: JuanGalilea Date: Wed, 25 Mar 2026 09:07:49 +0100 Subject: [PATCH 2/3] test(generate-schema-types): switch test logic to match expected behavior --- .../actor/generate-schema-types.test.ts | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/test/local/commands/actor/generate-schema-types.test.ts b/test/local/commands/actor/generate-schema-types.test.ts index f702891d0..51f5fe1d6 100644 --- a/test/local/commands/actor/generate-schema-types.test.ts +++ b/test/local/commands/actor/generate-schema-types.test.ts @@ -214,25 +214,24 @@ describe('apify actor generate-schema-types', () => { const generatedFile = await readFile(joinPath('output-required', 'input.ts'), 'utf-8'); - // startUrls has no default -> required (no ?) + // startUrls has no default but is required -> required (no ?) expect(generatedFile).toMatch(/startUrls:/); expect(generatedFile).not.toMatch(/startUrls\?:/); - // proxyConfig has no default -> required (no ?) - expect(generatedFile).toMatch(/proxyConfig:/); - expect(generatedFile).not.toMatch(/proxyConfig\?:/); + // proxyConfig has no default -> optional (has ?) + expect(generatedFile).toMatch(/proxyConfig\?:/); - // searchQuery is in original required array but has default: "apify" -> optional (has ?) - expect(generatedFile).toMatch(/searchQuery\?:/); + // searchQuery is in original required array but has default: "apify" -> required (no ?) + expect(generatedFile).toMatch(/searchQuery:/); - // maxItems has default: 100 -> optional (has ?) - expect(generatedFile).toMatch(/maxItems\?:/); + // maxItems has default: 100 -> required (no ?) + expect(generatedFile).toMatch(/maxItems:/); - // includeImages has default: false -> optional (has ?) - expect(generatedFile).toMatch(/includeImages\?:/); + // includeImages has default: false -> required (no ?) + expect(generatedFile).toMatch(/includeImages:/); - // crawlerType has default: "cheerio" -> optional (has ?) - expect(generatedFile).toMatch(/crawlerType\?:/); + // crawlerType has default: "cheerio" -> required (no ?) + expect(generatedFile).toMatch(/crawlerType:/); }); it('should make all properties optional with --all-optional flag', async () => { @@ -782,7 +781,7 @@ describe('prepareKvsCollectionsForCompilation', () => { }); describe('makePropertiesRequired', () => { - it('should add properties without defaults to required array', () => { + it('should add properties with defaults to required array', () => { const schema = { type: 'object', properties: { @@ -792,22 +791,22 @@ describe('makePropertiesRequired', () => { }; const result = makePropertiesRequired(schema); - expect(result.required).toEqual(['name']); + expect(result.required).toEqual(['age']); }); - it('should remove existing required entries that have defaults', () => { + it('should not remove existing required entries that dont have defaults', () => { const schema = { type: 'object', properties: { name: { type: 'string' }, age: { type: 'number', default: 25 }, }, - required: ['age'], + required: ['name'], }; const result = makePropertiesRequired(schema); expect(result.required).toContain('name'); - expect(result.required).not.toContain('age'); + expect(result.required).toContain('age'); }); it('should recurse into nested object properties', () => { @@ -817,16 +816,18 @@ describe('makePropertiesRequired', () => { nested: { type: 'object', properties: { + innerOptional: { type: 'string' }, innerRequired: { type: 'string' }, - innerOptional: { type: 'string', default: 'hello' }, + innerDefault: { type: 'string', default: 'hello' }, }, + required: ['innerRequired'], }, }, }; const result = makePropertiesRequired(schema); const { nested } = result.properties as any; - expect(nested.required).toEqual(['innerRequired']); + expect(nested.required).toEqual(['innerRequired', 'innerDefault']); }); it('should not mutate the original schema', () => { From 63a8a5d1fa9738daf93d235b138ec5f8c76a8b0b Mon Sep 17 00:00:00 2001 From: JuanGalilea Date: Wed, 25 Mar 2026 10:05:31 +0100 Subject: [PATCH 3/3] fix(generate-schema-types): remove requiredSet.has check --- src/lib/schema-transforms.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/lib/schema-transforms.ts b/src/lib/schema-transforms.ts index 7c2e80752..c0bc167d6 100644 --- a/src/lib/schema-transforms.ts +++ b/src/lib/schema-transforms.ts @@ -16,9 +16,6 @@ export function makePropertiesRequired(schema: Record): Record< const requiredSet = new Set(Array.isArray(clone.required) ? (clone.required as string[]) : []); for (const [key, prop] of Object.entries(properties)) { - if (requiredSet.has(key)) { - continue; - } if (prop.default !== undefined) { requiredSet.add(key); }