Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
e7f97fa
feat(custom-operations): allow CustomType and RefType in arguments
vaisshnavi7 Nov 8, 2024
0e0561e
Refactor type tests for CustomType and RefType
vaisshnavi7 Nov 8, 2024
1a54cde
Merge branch 'main' into feat/allow-customtype-ref-in-arguments
vaisshnavi7 Nov 13, 2024
ecf2ec2
Merge branch 'main' into feat/allow-customtype-ref-in-arguments
vaisshnavi7 Nov 21, 2024
a0872b9
feat: add support for custom, nested, and ref type arguments (#402)
vaisshnavi7 Nov 26, 2024
2f7e948
Merge branch 'main' into feat/allow-customtype-ref-in-arguments
vaisshnavi7 Nov 26, 2024
45074a3
Merge branch 'main' into feat/allow-customtype-ref-in-arguments
vaisshnavi7 Dec 11, 2024
3517643
feat: Custom type and ref arg handling in SchemaProcessor with tests …
vaisshnavi7 Jan 9, 2025
2e81a9d
Merge remote-tracking branch 'origin/main' into feat/allow-customtype…
vaisshnavi7 Jan 9, 2025
c54ed9b
Fix: Generate nested CustomTypes in schema output
vaisshnavi7 Jan 15, 2025
a7dd990
Merge branch 'main' into feat/allow-customtypes-ref-in-arguments/main
vaisshnavi7 Jan 15, 2025
cc50e20
refactor: Add tests for nested custom types and mixed refs
vaisshnavi7 Jan 15, 2025
fff0b5d
Add test for RefType with nested CustomType in complex structures
vaisshnavi7 Jan 16, 2025
f4b9171
Merge branch 'main' into feat/allow-customtypes-ref-in-arguments/main
stocaaro Jan 16, 2025
949e6ee
fix: Adjust schema component ordering to minimize enum reordering
vaisshnavi7 Jan 17, 2025
cdb02d1
Revert unnecessary changes for custom types and refs
vaisshnavi7 Jan 17, 2025
2f8c281
Merge branch 'main' into feat/allow-customtypes-ref-in-arguments/main
vaisshnavi7 Jan 21, 2025
6b82830
Add unit tests for custom operations with custom types and refs in Cu…
vaisshnavi7 Jan 22, 2025
f1b8e0e
Refactor schemaPreprocessor Consolidate schema components into single…
vaisshnavi7 Jan 23, 2025
acaa7d4
Improve tests for CustomType and RefType arguments in custom operations
vaisshnavi7 Jan 23, 2025
0f19e89
Fix: Support enums in custom types and references
vaisshnavi7 Jan 27, 2025
832a436
Remove empty block for enum ref handling in generateInputTypes
vaisshnavi7 Jan 27, 2025
3b32405
remove unused variable
vaisshnavi7 Jan 27, 2025
8ddcf13
Add unit tests for enum refs and improve ResolveFields type export
vaisshnavi7 Jan 28, 2025
a4c040e
Fix enum handling and duplication in nested custom types
vaisshnavi7 Jan 29, 2025
59c34ba
fix: lint errors for unused variables
vaisshnavi7 Jan 29, 2025
1310383
Merge branch 'main' into feat/allow-customtypes-ref-in-arguments/main
stocaaro Jan 30, 2025
bb7b4f2
test: add test cases for enum handling in arguments
vaisshnavi7 Jan 30, 2025
5b04623
Refactor custom operation input type generation
vaisshnavi7 Feb 4, 2025
29d3596
handle nested inout types
vaisshnavi7 Feb 4, 2025
cb5c732
Merge branch 'main' into feat/allow-customtypes-ref-in-arguments/main
vaisshnavi7 Feb 4, 2025
12cf372
remove unused variables
vaisshnavi7 Feb 4, 2025
e817980
update input naming convention
vaisshnavi7 Feb 6, 2025
e644a53
add comments
vaisshnavi7 Feb 6, 2025
69f1254
Merge branch 'main' into feat/allow-customtypes-ref-in-arguments/main
vaisshnavi7 Feb 6, 2025
bd835e3
Merge branch 'main' into feat/allow-customtypes-ref-in-arguments/main
stocaaro Feb 6, 2025
0f9992e
update error message and refactor
vaisshnavi7 Feb 7, 2025
ed6dd7c
Merge branch 'main' into feat/allow-customtypes-ref-in-arguments/main
vaisshnavi7 Feb 12, 2025
d7682c8
update naming for references
vaisshnavi7 Feb 13, 2025
36afaf4
fix: Update CustomOpArguments type
vaisshnavi7 Feb 18, 2025
7bd9d1d
Add tests for custom operation subscriptions with custom types and refs
vaisshnavi7 Feb 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/polite-crabs-rush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@aws-amplify/data-schema": minor
---

Allow CustomType and RefType in arguments for custom operations
152 changes: 146 additions & 6 deletions packages/data-schema/__tests__/CustomOperations.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
import { configure } from '../src/ModelSchema';
import { Nullable } from '../src/ModelField';
import { defineFunctionStub } from './utils';
import type { CustomOperation } from '../src/CustomOperation';

describe('custom operations return types', () => {
describe('when .ref() a basic custom type', () => {
Expand Down Expand Up @@ -84,15 +85,15 @@ describe('custom operations return types', () => {
});

it('produces async function handler types', () => {
const handler = defineFunctionStub({})
const handler = defineFunctionStub({});
const schema = a.schema({
aQuery: a
.query()
.handler(a.handler.function(handler).async())
.arguments({
input: a.string(),
content: a.string().required(),
})
}),
});

type Schema = ClientSchema<typeof schema>;
Expand All @@ -109,10 +110,7 @@ describe('custom operations return types', () => {
type ExpectedResult = {
success: boolean;
} | null;
type ExpectedFunctionHandler = AppSyncResolverHandler<
ActualArgs,
void
>;
type ExpectedFunctionHandler = AppSyncResolverHandler<ActualArgs, void>;
type _T1 = Expect<Equal<ActualArgs, ExpectedArgs>>;
type _T2 = Expect<Equal<ActualResult, ExpectedResult>>;
type _T3 = Expect<Equal<ActualHandler, ExpectedFunctionHandler>>;
Expand Down Expand Up @@ -858,3 +856,145 @@ describe('.for() modifier', () => {
a.subscription().for(a.ref('Model'));
});
});

describe('.arguments() modifier', () => {
// Test to verify that CustomType can be used as an argument in custom operations
it('accepts CustomType in arguments', () => {
const operation: CustomOperation<
any,
'arguments' | 'for',
'queryCustomOperation'
> = a.query().arguments({
customArg: a.customType({
field1: a.string(),
field2: a.integer(),
}),
});
});

// Test to verify that RefType can be used as an argument in custom operations
it('accepts RefType in arguments', () => {
const operation: CustomOperation<
any,
'arguments' | 'for',
'queryCustomOperation'
> = a.query().arguments({
refArg: a.ref('SomeType'),
});
});

it('handles deeply nested custom types', () => {
const schema = a.schema({
DeepNested: a.customType({
level1: a.customType({
level2: a.customType({
level3: a.string(),
}),
}),
}),
deepQuery: a
.query()
.arguments({
input: a.ref('DeepNested'),
})
.returns(a.string()),
});

type Schema = ClientSchema<typeof schema>;

type ExpectedArgs = {
input?: {
level1?: {
level2?: {
level3?: string | null;
} | null;
} | null;
} | null;
};

type ActualArgs = Schema['deepQuery']['args'];

type Test = Expect<Equal<ActualArgs, ExpectedArgs>>;
});

it('handles mixed custom types and refs', () => {
const schema = a.schema({
RefType: a.customType({
field: a.string(),
}),
MixedType: a.customType({
nested: a.customType({
refField: a.ref('RefType'),
customField: a.customType({
deepField: a.integer(),
}),
}),
}),
mixedQuery: a
.query()
.arguments({
input: a.ref('MixedType'),
})
.returns(a.string()),
});

type Schema = ClientSchema<typeof schema>;

type ExpectedArgs = {
input?: {
nested?: {
refField?: {
field?: string | null;
} | null;
customField?: {
deepField?: number | null;
} | null;
} | null;
} | null;
};

type ActualArgs = Schema['mixedQuery']['args'];

type Test = Expect<Equal<ActualArgs, ExpectedArgs>>;
});

it('handles RefType with multi-layered custom types in nested structures', () => {
const schema = a.schema({
NestedCustomType: a.customType({
nestedField: a.string(),
}),
RefType: a.customType({
field: a.string(),
nestedCustom: a.ref('NestedCustomType'),
}),
OuterType: a.customType({
refField: a.ref('RefType'),
otherField: a.integer(),
}),
complexQuery: a
.query()
.arguments({
input: a.ref('OuterType'),
})
.returns(a.string()),
});

type Schema = ClientSchema<typeof schema>;

type ExpectedArgs = {
input?: {
refField?: {
field?: string | null;
nestedCustom?: {
nestedField?: string | null;
} | null;
} | null;
otherField?: number | null;
} | null;
};

type ActualArgs = Schema['complexQuery']['args'];

type Test = Expect<Equal<ActualArgs, ExpectedArgs>>;
});
});
80 changes: 50 additions & 30 deletions packages/data-schema/__tests__/CustomOperations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -907,15 +907,15 @@ describe('CustomOperation transform', () => {
.query()
.arguments({})
.handler(a.handler.function(fn1).async())
.authorization((allow) => allow.authenticated())
.authorization((allow) => allow.authenticated()),
});

const { schema, lambdaFunctions } = s.transform();
expect(schema).toMatchSnapshot();
expect(lambdaFunctions).toMatchObject({
FnGetPostDetails: fn1,
});
})
});

test('defineFunction sync - async', () => {
const fn1 = defineFunctionStub({});
Expand All @@ -927,15 +927,15 @@ describe('CustomOperation transform', () => {
a.handler.function(fn1),
a.handler.function(fn1).async(),
])
.authorization((allow) => allow.authenticated())
.authorization((allow) => allow.authenticated()),
});

const { schema, lambdaFunctions } = s.transform();
expect(schema).toMatchSnapshot();
expect(lambdaFunctions).toMatchObject({
FnGetPostDetails: fn1,
});
})
});

test('defineFunction sync - async with returns generates type errors', () => {
const fn1 = defineFunctionStub({});
Expand All @@ -949,9 +949,9 @@ describe('CustomOperation transform', () => {
])
.authorization((allow) => allow.authenticated())
// @ts-expect-error
.returns({ })
.returns({}),
});
})
});

test('defineFunction async - async', () => {
const fn1 = defineFunctionStub({});
Expand All @@ -965,7 +965,7 @@ describe('CustomOperation transform', () => {
a.handler.function(fn1).async(),
a.handler.function(fn2).async(),
])
.authorization((allow) => allow.authenticated())
.authorization((allow) => allow.authenticated()),
});

const { schema, lambdaFunctions } = s.transform();
Expand All @@ -974,7 +974,7 @@ describe('CustomOperation transform', () => {
FnGetPostDetails: fn1,
FnGetPostDetails2: fn2,
});
})
});

test('defineFunction async - sync', () => {
const fn1 = defineFunctionStub({});
Expand All @@ -987,12 +987,12 @@ describe('CustomOperation transform', () => {
a.handler.function(fn1),
])
.returns(a.customType({}))
.authorization((allow) => allow.authenticated())
.authorization((allow) => allow.authenticated()),
});

const { schema, lambdaFunctions } = s.transform();
expect(schema).toMatchSnapshot();
})
});

test('pipeline / mix', () => {
const fn1 = defineFunctionStub({});
Expand Down Expand Up @@ -1341,15 +1341,14 @@ describe('custom operations + custom type auth inheritance', () => {

test('implicit custom type inherits auth rules from referencing op', () => {
const s = a.schema({
MyQueryReturnType: a.customType({
fieldA: a.string(),
fieldB: a.integer(),
}),
myQuery: a
.query()
.handler(a.handler.function('myFn'))
.returns(
a.customType({
fieldA: a.string(),
fieldB: a.integer(),
}),
)
.returns(a.ref('MyQueryReturnType'))
.authorization((allow) => allow.publicApiKey()),
});

Expand All @@ -1363,23 +1362,22 @@ describe('custom operations + custom type auth inheritance', () => {

test('nested custom types inherit auth rules from top-level referencing op', () => {
const s = a.schema({
MyQueryReturnType: a.customType({
fieldA: a.string(),
fieldB: a.integer(),
nestedCustomType: a.customType({
nestedA: a.string(),
nestedB: a.string(),
grandChild: a.customType({
grandA: a.string(),
grandB: a.string(),
}),
}),
}),
myQuery: a
.query()
.handler(a.handler.function('myFn'))
.returns(
a.customType({
fieldA: a.string(),
fieldB: a.integer(),
nestedCustomType: a.customType({
nestedA: a.string(),
nestedB: a.string(),
grandChild: a.customType({
grandA: a.string(),
grandB: a.string(),
}),
}),
}),
)
.returns(a.ref('MyQueryReturnType'))
.authorization((allow) => allow.publicApiKey()),
});

Expand All @@ -1401,6 +1399,28 @@ describe('custom operations + custom type auth inheritance', () => {
);
});

test('inline custom type inherits auth rules from referencing op', () => {
const s = a.schema({
myQuery: a
.query()
.handler(a.handler.function('myFn'))
.returns(
a.customType({
fieldA: a.string(),
fieldB: a.integer(),
}),
)
.authorization((allow) => allow.publicApiKey()),
});

const result = s.transform().schema;

expect(result).toMatchSnapshot();
expect(result).toEqual(
expect.stringContaining('type MyQueryReturnType @aws_api_key\n{'),
);
});

test('top-level custom type with nested top-level custom types inherits combined auth rules from referencing ops', () => {
const s = a.schema({
myQuery: a
Expand Down
Loading
Loading