Skip to content

Commit

Permalink
Merge branch 'main' into feat/allow-customtype-ref-in-arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
vaisshnavi7 committed Dec 11, 2024
2 parents 2f7e948 + 43919e2 commit 45074a3
Show file tree
Hide file tree
Showing 13 changed files with 1,231 additions and 640 deletions.
22 changes: 22 additions & 0 deletions e2e-TEST-COVERAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# E2E Test Coverage

The following table outlines the current e2e test coverage for various runtimes and environments in our project:

| Runtime/Environment | Status |
|---------------------|-----------|
| Chrome | [](.github/workflows/callable-e2e-test.yml) |
| Node | [](packages/e2e-tests/node/jest.config.ts) |
| Webpack | ⚠️ |
| Rollup | ⚠️ |
| Metro | ⚠️ |
| React Natives | ⚠️ |

Legend:
- ✅ Fully covered by e2e tests
- ⚠️ In progress
- N/A Not applicable or not planned

## Notes

- Click on the icons in the table to view relevant e2e test configurations or workflows.

2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions packages/data-schema/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# @aws-amplify/data-schema

## 1.17.1

### Patch Changes

- 08727a2: add Amazon Nova Micro, Lite, and Pro models

## 1.17.0

### Minor Changes

- 2a9282b: Disable additional .array() modifier on model field definition

### Patch Changes

- 5945ba9: add Amazon Nova Micro, Lite, and Pro models
- cd8f4bd: fix: custom sel. set return type for array custom types

## 1.16.1

### Patch Changes
Expand Down
5 changes: 5 additions & 0 deletions packages/data-schema/__tests__/ModelField.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,8 @@ describe('field level auth', () => {
expect(field.data.authorization).toMatchSnapshot();
});
});

it('array modifier becomes unavailable after being used once', () => {
// @ts-expect-error .array() is not a valid modifier after being used once
a.model({ values: a.string().required().array().required().array().required() });
});
3 changes: 2 additions & 1 deletion packages/data-schema/docs/data-schema.modelfield.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ Public API for the chainable builder methods exposed by Model Field. The type is
export type ModelField<T extends ModelFieldTypeParamOuter = ModelFieldTypeParamOuter, UsedMethod extends UsableModelFieldKey = never, Auth = undefined> = Omit<{
[__auth]?: Auth;
[brandSymbol]: typeof brandName;
[internal](): ModelField<T>;
required(): ModelField<Required<T>, UsedMethod | 'required'>;
array(): ModelField<ArrayField<T>, Exclude<UsedMethod, 'required'>>;
array(): ModelField<ArrayField<T>, Exclude<UsedMethod, 'required'> | 'array'>;
default(value?: ModelFieldTypeParamOuter): ModelField<T, UsedMethod | 'default'>;
authorization<AuthRuleType extends Authorization<any, any, any>>(callback: (allow: Omit<AllowModifier, 'resource'>) => AuthRuleType | AuthRuleType[]): ModelField<T, UsedMethod | 'authorization', AuthRuleType>;
}, UsedMethod>;
Expand Down
2 changes: 1 addition & 1 deletion packages/data-schema/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aws-amplify/data-schema",
"version": "1.16.1",
"version": "1.17.1",
"license": "Apache-2.0",
"repository": {
"type": "git",
Expand Down
16 changes: 14 additions & 2 deletions packages/data-schema/src/ModelField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const __auth = Symbol('__auth');
export const __generated = Symbol('__generated');

const brandName = 'modelField';
const internal = Symbol('internal');

export enum ModelFieldType {
Id = 'ID',
Expand Down Expand Up @@ -82,7 +83,7 @@ export type BaseModelField<

export type UsableModelFieldKey = satisfy<
methodKeyOf<ModelField>,
'required' | 'default' | 'authorization'
'required' | 'default' | 'authorization' | 'array'
>;

/**
Expand All @@ -102,6 +103,14 @@ export type ModelField<
[__auth]?: Auth;
[brandSymbol]: typeof brandName;

/**
* Internal non-omittable method that allows `BaseModelField` to retain a reference to `T` type arg in `ModelField`.
* Since all public methods are omittable, the evaluated `BaseModelField` loses type information unless
* some property on the type is guaranteed to reference `T`
* Context: https://github.com/aws-amplify/amplify-api-next/pull/406/files#r1869481467
*/
[internal](): ModelField<T>;

/**
* Marks a field as required.
*/
Expand All @@ -110,7 +119,7 @@ export type ModelField<
/**
* Converts a field type definition to an array of the field type.
*/
array(): ModelField<ArrayField<T>, Exclude<UsedMethod, 'required'>>;
array(): ModelField<ArrayField<T>, Exclude<UsedMethod, 'required'> | 'array'>;
// TODO: should be T, but .array breaks this constraint. Fix later
/**
* Sets a default value for the scalar type.
Expand Down Expand Up @@ -199,6 +208,9 @@ function _field<T extends ModelFieldTypeParamOuter>(fieldType: ModelFieldType) {
return this;
},
...brand(brandName),
[internal]() {
return this;
},
} as ModelField<T>;

// this double cast gives us a Subtyping Constraint i.e., hides `data` from the public API,
Expand Down
4 changes: 4 additions & 0 deletions packages/data-schema/src/ai/ModelType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import { AiModel } from '@aws-amplify/data-schema-types';

const supportedModelsLookup = {
// Amazon Nova models
'Amazon Nova Pro': 'amazon.nova-pro-v1:0',
'Amazon Nova Lite': 'amazon.nova-lite-v1:0',
'Amazon Nova Micro': 'amazon.nova-micro-v1:0',
// Anthropic models
'Claude 3 Haiku': 'anthropic.claude-3-haiku-20240307-v1:0',
'Claude 3 Opus': 'anthropic.claude-3-opus-20240229-v1:0',
Expand Down
49 changes: 40 additions & 9 deletions packages/data-schema/src/runtime/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,21 +84,52 @@ type ReturnValue<
* This mapped type traverses the SelectionSetReturnValue result and the original FlatModel, restoring array types
* that were flattened in DeepPickFromPath
*
* Note: custom type field arrays are already handled correctly and don't need to be "restored", hence the `Result[K] extends Array<any>` check
* @typeParam Result - this is the result of applying the selection set path to FlatModel; return type of UnionToIntersection<DeepPickFromPath<FlatModel, Paths>>
* @typeParam FlatModel - the reference model shape; return type of ResolvedModel<Model>
*
* Note: we wrap `Result` and `FlatModel` in NonNullable, because recursive invocations of this mapped type
* can result in the type arguments containing `{} | null | undefined` which breaks indexed access, e.g. Result[K]
*
* Using NonNullable<> directly inside the mapped type is significantly more performant here than attempting to pre-compute in the type params,
* e.g., `type RestoreArrays<Result, FlatModel, NonNullableResult = NonNullable<Result>, NonNullableFlatModel = NonNullable<FlatModel>> = {...}`
*/
type RestoreArrays<Result, FlatModel> = {
[K in keyof Result]: K extends keyof FlatModel
? FlatModel[K] extends Array<any>
? Result[K] extends Array<any>
? Result[K]
: Array<RestoreArrays<Result[K], UnwrapArray<FlatModel[K]>>>
: FlatModel[K] extends Record<string, any>
? RestoreArrays<Result[K], FlatModel[K]>
: Result[K]
[K in keyof NonNullable<Result>]: K extends keyof NonNullable<FlatModel>
? Array<any> extends NonNullable<FlatModel>[K]
? HandleArrayNullability<
NonNullable<Result>[K],
NonNullable<FlatModel>[K]
>
: NonNullable<FlatModel>[K] extends Record<string, any>
? RestoreArrays<NonNullable<Result>[K], NonNullable<FlatModel>[K]>
: NonNullable<Result>[K]
: never;
};

/**
* This mapped type gets called by RestoreArrays<T, K> and it restores the expected
* nullability in array fields (e.g. nullable vs. required value & nullable vs. required array)
*/
type HandleArrayNullability<Result, FlatModel> =
Array<any> extends Result
? // If Result is already an array, return it as is.
Result
: NonNullable<FlatModel> extends Array<infer InnerValue>
? // is the array nullable?
null extends FlatModel
? // is the value nullable?
null extends InnerValue
? // value and array are nullable - a.ref('SomeType').array()
Array<RestoreArrays<Result, UnwrapArray<FlatModel>> | null> | null
: // value required; array nullable - a.ref('SomeType').required().array()
Array<RestoreArrays<Result, UnwrapArray<FlatModel>>> | null
: null extends InnerValue
? // value nullable; array required - a.ref('SomeType').array().required()
Array<RestoreArrays<Result, UnwrapArray<FlatModel>> | null>
: // value required; array required - a.ref('SomeType').required().array().required()
Array<RestoreArrays<Result, UnwrapArray<FlatModel>>>
: never;

/**
* Generates flattened, readonly return type using specified custom sel. set
*/
Expand Down
Loading

0 comments on commit 45074a3

Please sign in to comment.