@aws-amplify/data-schema 0.13.16 → 0.13.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib-esm/src/ClientSchema.d.ts +8 -13
- package/lib-esm/src/CustomOperation.d.ts +5 -0
- package/lib-esm/src/CustomOperation.js +5 -0
- package/lib-esm/src/Handler.d.ts +1 -1
- package/lib-esm/src/MappedTypes/CustomOperations.d.ts +3 -3
- package/lib-esm/src/MappedTypes/ResolveFieldProperties.d.ts +5 -4
- package/lib-esm/src/MappedTypes/ResolveSchema.d.ts +2 -2
- package/lib-esm/src/ModelSchema.d.ts +21 -12
- package/lib-esm/src/ModelSchema.js +27 -6
- package/lib-esm/src/RefType.d.ts +3 -0
- package/lib-esm/src/RefType.js +5 -0
- package/lib-esm/src/SchemaProcessor.js +100 -8
- package/lib-esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1,34 +1,29 @@
|
|
|
1
1
|
import { type __modelMeta__ } from '@aws-amplify/data-schema-types';
|
|
2
|
-
import type
|
|
2
|
+
import { type GenericModelSchema, type RDSModelSchema } from './ModelSchema';
|
|
3
3
|
import type { ResolveSchema, SchemaTypes } from './MappedTypes/ResolveSchema';
|
|
4
|
-
import type { CreateImplicitModelsFromRelations, ResolveFieldProperties } from './MappedTypes/ResolveFieldProperties';
|
|
4
|
+
import type { CreateImplicitModelsFromRelations, ResolveFieldProperties, ResolveStaticFieldProperties } from './MappedTypes/ResolveFieldProperties';
|
|
5
5
|
import type { ModelIdentifier, ModelSecondaryIndexes, RelationalMetadata } from './MappedTypes/ModelMetadata';
|
|
6
6
|
import type { ExtractNonModelTypes, NonModelTypesShape } from './MappedTypes/ExtractNonModelTypes';
|
|
7
7
|
import { ResolveCustomOperations, CustomOperationHandlerTypes } from './MappedTypes/CustomOperations';
|
|
8
|
-
export type ClientSchema<Schema extends
|
|
8
|
+
export type ClientSchema<Schema extends GenericModelSchema<any>> = InternalClientSchema<Schema>;
|
|
9
9
|
/**
|
|
10
10
|
* Types for unwrapping generic type args into client-consumable types
|
|
11
11
|
*
|
|
12
|
-
* @typeParam Schema -
|
|
12
|
+
* @typeParam Schema - Data schema builder model type
|
|
13
13
|
*
|
|
14
14
|
* The following params are used solely as variables in order to simplify mapped type usage.
|
|
15
15
|
* They should not receive external type args.
|
|
16
16
|
*
|
|
17
17
|
* @internal @typeParam NonModelTypes - Custom Types, Enums, and Custom Operations
|
|
18
|
-
* @internal @typeParam
|
|
19
|
-
* @internal @typeParam ResolvedFields -
|
|
20
|
-
* @internal @typeParam IdentifierMeta - Map of model primary index metadata
|
|
18
|
+
* @internal @typeParam ImplicitModels - The implicit models created to represent relationships
|
|
19
|
+
* @internal @typeParam ResolvedFields - Resolved client-facing types used for CRUDL response shapes
|
|
21
20
|
* @internal @typeParam SecondaryIndexes - Map of model secondary index metadata
|
|
22
|
-
*
|
|
23
|
-
* @internal @typeParam Meta - Stores schema metadata: identifier, relationship metadata;
|
|
24
|
-
* used by `API.generateClient` to craft strongly typed mutation inputs; hidden from customer-facing types behind __modelMeta__ symbol
|
|
25
|
-
*
|
|
26
21
|
*/
|
|
27
|
-
type InternalClientSchema<Schema extends
|
|
22
|
+
type InternalClientSchema<Schema extends GenericModelSchema<any>, NonModelTypes extends NonModelTypesShape = ExtractNonModelTypes<Schema>, ResolvedSchema = ResolveSchema<Schema>, ImplicitModels = Schema extends RDSModelSchema<any, any> ? object : CreateImplicitModelsFromRelations<ResolvedSchema>, ImplicitModelsIdentifierMeta = {
|
|
28
23
|
[ImplicitModel in keyof ImplicitModels]: {
|
|
29
24
|
identifier: 'id';
|
|
30
25
|
};
|
|
31
|
-
}, ResolvedFields extends Record<string, unknown> = ResolveFieldProperties<Schema, NonModelTypes, ImplicitModels>, IdentifierMeta extends Record<string, any> = ModelIdentifier<SchemaTypes<Schema>>, SecondaryIndexes extends Record<string, any> = ModelSecondaryIndexes<SchemaTypes<Schema>>> =
|
|
26
|
+
}, ResolvedFields extends Record<string, unknown> = Schema extends RDSModelSchema<any, any> ? ResolveStaticFieldProperties<Schema, NonModelTypes, object> : ResolveFieldProperties<Schema, NonModelTypes, ImplicitModels>, IdentifierMeta extends Record<string, any> = ModelIdentifier<SchemaTypes<Schema>>, SecondaryIndexes extends Record<string, any> = Schema extends RDSModelSchema<any, any> ? object : ModelSecondaryIndexes<SchemaTypes<Schema>>> = CustomOperationHandlerTypes<ResolveCustomOperations<Schema, ResolvedFields, NonModelTypes>['customOperations']> & ResolvedFields & {
|
|
32
27
|
[__modelMeta__]: IdentifierMeta & ImplicitModelsIdentifierMeta & SecondaryIndexes & RelationalMetadata<ResolvedSchema, ResolvedFields, IdentifierMeta> & NonModelTypes & ResolveCustomOperations<Schema, ResolvedFields, NonModelTypes>;
|
|
33
28
|
};
|
|
34
29
|
export {};
|
|
@@ -11,6 +11,8 @@ declare const mutationBrand = "mutationCustomOperation";
|
|
|
11
11
|
declare const subscriptionBrand = "subscriptionCustomOperation";
|
|
12
12
|
type CustomOperationBrand = typeof queryBrand | typeof mutationBrand | typeof subscriptionBrand;
|
|
13
13
|
type CustomArguments = Record<string, ModelField<any, any> | EnumType<EnumTypeParamShape>>;
|
|
14
|
+
type SubscriptionSource = RefType<any, any>;
|
|
15
|
+
type InternalSubscriptionSource = InternalRef;
|
|
14
16
|
type CustomReturnType = RefType<any> | CustomType<any>;
|
|
15
17
|
type CustomFunctionRefType = string;
|
|
16
18
|
type InternalCustomArguments = Record<string, InternalField>;
|
|
@@ -25,11 +27,13 @@ type CustomData = {
|
|
|
25
27
|
authorization: Authorization<any, any, any>[];
|
|
26
28
|
typeName: CustomOperationName;
|
|
27
29
|
handlers: Handler[] | null;
|
|
30
|
+
subscriptionSource: SubscriptionSource[];
|
|
28
31
|
};
|
|
29
32
|
type InternalCustomData = CustomData & {
|
|
30
33
|
arguments: InternalCustomArguments;
|
|
31
34
|
returnType: InternalCustomReturnType;
|
|
32
35
|
functionRef: string | null;
|
|
36
|
+
subscriptionSource: InternalSubscriptionSource[];
|
|
33
37
|
authorization: Authorization<any, any, any>[];
|
|
34
38
|
};
|
|
35
39
|
export type CustomOperationParamShape = {
|
|
@@ -54,6 +58,7 @@ export type CustomOperation<T extends CustomOperationParamShape, K extends keyof
|
|
|
54
58
|
function<FunctionRef extends CustomFunctionRefType>(functionRefOrName: FunctionRef): CustomOperation<SetTypeSubArg<T, 'functionRef', FunctionRef>, K | 'function', B>;
|
|
55
59
|
authorization<AuthRuleType extends Authorization<any, any, any>>(rules: AuthRuleType[]): CustomOperation<SetTypeSubArg<T, 'authorization', AuthRuleType[]>, K | 'authorization', B>;
|
|
56
60
|
handler<H extends HandlerInputType>(handlers: H): CustomOperation<T, K | 'handler', B>;
|
|
61
|
+
for(source: SubscriptionSource | SubscriptionSource[]): CustomOperation<T, K | 'for', B>;
|
|
57
62
|
}, K> & Brand<B>;
|
|
58
63
|
/**
|
|
59
64
|
* Internal representation of Custom Type that exposes the `data` property.
|
|
@@ -21,6 +21,7 @@ function _custom(typeName, brand) {
|
|
|
21
21
|
authorization: [],
|
|
22
22
|
typeName: typeName,
|
|
23
23
|
handlers: null,
|
|
24
|
+
subscriptionSource: [],
|
|
24
25
|
};
|
|
25
26
|
const builder = brandedBuilder({
|
|
26
27
|
arguments(args) {
|
|
@@ -45,6 +46,10 @@ function _custom(typeName, brand) {
|
|
|
45
46
|
: [handlers];
|
|
46
47
|
return this;
|
|
47
48
|
},
|
|
49
|
+
for(source) {
|
|
50
|
+
data.subscriptionSource = Array.isArray(source) ? source : [source];
|
|
51
|
+
return this;
|
|
52
|
+
},
|
|
48
53
|
}, brand);
|
|
49
54
|
return { ...builder, data };
|
|
50
55
|
}
|
package/lib-esm/src/Handler.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ type CustomHandlerInput = {
|
|
|
23
23
|
* Defaults to 'NONE_DS'
|
|
24
24
|
*
|
|
25
25
|
*/
|
|
26
|
-
dataSource?: string | RefType<any
|
|
26
|
+
dataSource?: string | RefType<any>;
|
|
27
27
|
/**
|
|
28
28
|
* The path to the file that contains the function entry point.
|
|
29
29
|
* If this is a relative path, it is computed relative to the file where this handler is defined
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { GenericModelSchema } from '../ModelSchema';
|
|
2
2
|
import type { NonModelTypesShape } from './ExtractNonModelTypes';
|
|
3
3
|
import type { CustomOperation, CustomOperationParamShape } from '../CustomOperation';
|
|
4
4
|
import type { ModelField } from '../ModelField';
|
|
@@ -8,7 +8,7 @@ import type { AppSyncResolverHandler } from 'aws-lambda';
|
|
|
8
8
|
/**
|
|
9
9
|
* Creates meta types for custom operations from a schema.
|
|
10
10
|
*/
|
|
11
|
-
export type ResolveCustomOperations<Schema extends
|
|
11
|
+
export type ResolveCustomOperations<Schema extends GenericModelSchema<any>, FullyResolvedSchema extends Record<string, unknown>, NonModelTypes extends NonModelTypesShape> = {
|
|
12
12
|
customOperations: {
|
|
13
13
|
[OpName in keyof CustomOpShapes<Schema>]: {
|
|
14
14
|
arguments: CustomOpArguments<CustomOpShapes<Schema>[OpName]>;
|
|
@@ -22,7 +22,7 @@ export type ResolveCustomOperations<Schema extends ModelSchema<any, any>, FullyR
|
|
|
22
22
|
/**
|
|
23
23
|
* Filtered, mapped list of custom operations shapes from a schema.
|
|
24
24
|
*/
|
|
25
|
-
export type CustomOpShapes<Schema extends
|
|
25
|
+
export type CustomOpShapes<Schema extends GenericModelSchema<any>> = {
|
|
26
26
|
[K in keyof Schema['data']['types'] as Schema['data']['types'][K] extends CustomOperation<any, any> ? K : never]: Schema['data']['types'][K] extends CustomOperation<infer Shape, any> ? Shape : never;
|
|
27
27
|
};
|
|
28
28
|
/**
|
|
@@ -2,7 +2,7 @@ import type { UnionToIntersection, LazyLoader, ExcludeEmpty } from '@aws-amplify
|
|
|
2
2
|
import type { Authorization, ImpliedAuthFields } from '../Authorization';
|
|
3
3
|
import type { ModelField } from '../ModelField';
|
|
4
4
|
import type { ModelType, ModelTypeParamShape } from '../ModelType';
|
|
5
|
-
import type {
|
|
5
|
+
import type { GenericModelSchema } from '../ModelSchema';
|
|
6
6
|
import type { ModelRelationalField, ModelRelationalFieldParamShape, ModelRelationalTypeArgFactory, ModelRelationshipTypes } from '../ModelRelationalField';
|
|
7
7
|
import type { AllImpliedFKs } from './ForeignKeys';
|
|
8
8
|
import type { ResolveSchema, SchemaTypes } from './ResolveSchema';
|
|
@@ -13,9 +13,10 @@ import type { NonModelTypesShape } from './ExtractNonModelTypes';
|
|
|
13
13
|
import type { CustomType, CustomTypeParamShape } from '../CustomType';
|
|
14
14
|
import type { EnumType, EnumTypeParamShape } from '../EnumType';
|
|
15
15
|
import type { CustomOperation, CustomOperationParamShape } from '../CustomOperation';
|
|
16
|
-
export type ResolveFieldProperties<Schema extends
|
|
16
|
+
export type ResolveFieldProperties<Schema extends GenericModelSchema<any>, NonModelTypes extends NonModelTypesShape, ImplicitModelsSchema, ResolvedSchema = ResolveSchema<Schema>, IdentifierMeta extends Record<string, {
|
|
17
17
|
identifier: string;
|
|
18
18
|
}> = ModelIdentifier<SchemaTypes<Schema>>, FieldsWithInjectedImplicitFields = InjectImplicitModelFields<ResolvedSchema & ImplicitModelsSchema, IdentifierMeta>, FieldsWithRelationships = ResolveRelationships<FieldsWithInjectedImplicitFields, NonModelTypes>> = Intersection<FilterFieldTypes<MarkModelsNonNullableFieldsRequired<FieldsWithRelationships>>, FilterFieldTypes<MarkModelsNullableFieldsOptional<FieldsWithRelationships>>, FilterFieldTypes<ModelImpliedAuthFields<Schema>>, AllImpliedFKs<ResolvedSchema, IdentifierMeta>>;
|
|
19
|
+
export type ResolveStaticFieldProperties<Schema extends GenericModelSchema<any>, NonModelTypes extends NonModelTypesShape, ImplicitModelsSchema, ResolvedSchema = ResolveSchema<Schema>, FieldsWithInjectedImplicitFields = InjectImplicitModelFields<ResolvedSchema & ImplicitModelsSchema, object>, FieldsWithRelationships = ResolveRelationships<FieldsWithInjectedImplicitFields, NonModelTypes>> = Intersection<FilterFieldTypes<MarkModelsNonNullableFieldsRequired<FieldsWithRelationships>>, FilterFieldTypes<MarkModelsNullableFieldsOptional<FieldsWithRelationships>>>;
|
|
19
20
|
export type CreateImplicitModelsFromRelations<Schema> = UnionToIntersection<ExcludeEmpty<{
|
|
20
21
|
[ModelProp in keyof Schema]: {
|
|
21
22
|
[FieldProp in keyof Schema[ModelProp] as Schema[ModelProp][FieldProp] extends ModelRelationalFieldParamShape ? Schema[ModelProp][FieldProp]['relationName'] extends string ? Schema[ModelProp][FieldProp]['relationName'] extends keyof Schema ? never : Schema[ModelProp][FieldProp]['relationName'] : never : never]: Record<`${Lowercase<ModelProp & string>}`, ModelRelationalTypeArgFactory<ModelProp & string, ModelRelationshipTypes.hasMany, false>>;
|
|
@@ -59,9 +60,9 @@ type MarkModelsNonNullableFieldsRequired<Schema> = {
|
|
|
59
60
|
type Intersection<A = Record<never, never>, B = Record<never, never>, C = Record<never, never>, D = Record<never, never>> = A & B & C & D extends infer U ? {
|
|
60
61
|
[P in keyof U]: U[P];
|
|
61
62
|
} : never;
|
|
62
|
-
export type ModelImpliedAuthFields<Schema extends
|
|
63
|
+
export type ModelImpliedAuthFields<Schema extends GenericModelSchema<any>> = {
|
|
63
64
|
[ModelKey in keyof Schema['data']['types'] as Schema['data']['types'][ModelKey] extends EnumType<EnumTypeParamShape> ? never : Schema['data']['types'][ModelKey] extends CustomType<CustomTypeParamShape> ? never : Schema['data']['types'][ModelKey] extends CustomOperation<CustomOperationParamShape, any> ? never : ModelKey]: Schema['data']['types'][ModelKey] extends ModelType<infer Model, any> ? AllAuthFieldsForModel<Schema, Model> : object;
|
|
64
65
|
};
|
|
65
|
-
type AllAuthFieldsForModel<Schema extends
|
|
66
|
+
type AllAuthFieldsForModel<Schema extends GenericModelSchema<any>, Model extends Schema['data']['types'][keyof Schema['data']['types']]> = (Model['authorization'][number] extends never ? Schema['data']['authorization'][number] extends never ? object : ImpliedAuthFields<Schema['data']['authorization'][number]> : ImpliedAuthFields<Model['authorization'][number]>) & ImpliedAuthFieldsFromFields<Model>;
|
|
66
67
|
type ImpliedAuthFieldsFromFields<T> = UnionToIntersection<T extends ModelTypeParamShape ? T['fields'][keyof T['fields']] extends ModelField<any, any, infer Auth> | ModelRelationalField<any, any, any, infer Auth> | RefType<any, any, infer Auth> ? Auth extends Authorization<any, any, any> ? ImpliedAuthFields<Auth> : object : object : object>;
|
|
67
68
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ModelType } from '../ModelType';
|
|
2
|
-
import type {
|
|
2
|
+
import type { GenericModelSchema } from '../ModelSchema';
|
|
3
3
|
import type { ModelRelationalField, ModelRelationshipTypes, RelationTypeFunctionOmitMapping } from '../ModelRelationalField';
|
|
4
4
|
import type { ModelField } from '../ModelField';
|
|
5
5
|
import type { CustomType, CustomTypeParamShape } from '../CustomType';
|
|
@@ -7,7 +7,7 @@ import type { EnumType, EnumTypeParamShape } from '../EnumType';
|
|
|
7
7
|
import type { RefType, RefTypeParamShape } from '../RefType';
|
|
8
8
|
import type { CustomOperation, CustomOperationParamShape } from '../CustomOperation';
|
|
9
9
|
export type ResolveSchema<Schema> = FieldTypes<ModelTypes<SchemaTypes<Schema>>>;
|
|
10
|
-
export type SchemaTypes<T> = T extends
|
|
10
|
+
export type SchemaTypes<T> = T extends GenericModelSchema<any> ? T['data']['types'] : never;
|
|
11
11
|
/**
|
|
12
12
|
* Resolves model types
|
|
13
13
|
*
|
|
@@ -4,6 +4,12 @@ import type { EnumType, EnumTypeParamShape } from './EnumType';
|
|
|
4
4
|
import type { CustomType, CustomTypeParamShape } from './CustomType';
|
|
5
5
|
import type { CustomOperation, CustomOperationParamShape, InternalCustom, MutationCustomOperation, QueryCustomOperation, SubscriptionCustomOperation } from './CustomOperation';
|
|
6
6
|
import { SchemaAuthorization } from './Authorization';
|
|
7
|
+
import { Brand } from './util';
|
|
8
|
+
export declare const rdsSchemaBrandName = "RDSSchema";
|
|
9
|
+
export declare const rdsSchemaBrand: Brand<"RDSSchema">;
|
|
10
|
+
export type RDSSchemaBrand = Brand<typeof rdsSchemaBrandName>;
|
|
11
|
+
export declare const ddbSchemaBrandName = "DDBSchema";
|
|
12
|
+
export type DDBSchemaBrand = Brand<typeof ddbSchemaBrandName>;
|
|
7
13
|
type SchemaContent = ModelType<ModelTypeParamShape, any> | CustomType<CustomTypeParamShape> | EnumType<EnumTypeParamShape> | CustomOperation<CustomOperationParamShape, any>;
|
|
8
14
|
type ModelSchemaContents = Record<string, SchemaContent>;
|
|
9
15
|
type InternalSchemaModels = Record<string, InternalModel | EnumType<any> | CustomType<any> | InternalCustom>;
|
|
@@ -38,7 +44,7 @@ export type ModelSchemaParamShape = {
|
|
|
38
44
|
authorization: SchemaAuthorization<any, any, any>[];
|
|
39
45
|
configuration: SchemaConfig<any, any>;
|
|
40
46
|
};
|
|
41
|
-
export type
|
|
47
|
+
export type RDSModelSchemaParamShape = ModelSchemaParamShape & {
|
|
42
48
|
setSqlStatementFolderPath?: string;
|
|
43
49
|
};
|
|
44
50
|
export type InternalSchema = {
|
|
@@ -48,22 +54,25 @@ export type InternalSchema = {
|
|
|
48
54
|
configuration: SchemaConfig<any, any>;
|
|
49
55
|
};
|
|
50
56
|
};
|
|
51
|
-
|
|
52
|
-
authorization: <AuthRules extends SchemaAuthorization<any, any, any>>(auth: AuthRules[]) => ModelSchema<SetTypeSubArg<T, 'authorization', AuthRules[]>, UsedMethods | 'authorization'>;
|
|
53
|
-
}, UsedMethods> & {
|
|
57
|
+
type BaseSchema<T extends ModelSchemaParamShape> = {
|
|
54
58
|
data: T;
|
|
55
59
|
models: {
|
|
56
60
|
[TypeKey in keyof T['types']]: T['types'][TypeKey] extends ModelType<ModelTypeParamShape> ? SchemaModelType<T['types'][TypeKey]> : never;
|
|
57
61
|
};
|
|
58
62
|
transform: () => DerivedApiDefinition;
|
|
59
63
|
};
|
|
60
|
-
type
|
|
61
|
-
export type
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
export type GenericModelSchema<T extends ModelSchemaParamShape> = BaseSchema<T> & Brand<string>;
|
|
65
|
+
export type ModelSchema<T extends ModelSchemaParamShape, UsedMethods extends 'authorization' = never> = Omit<{
|
|
66
|
+
authorization: <AuthRules extends SchemaAuthorization<any, any, any>>(auth: AuthRules[]) => ModelSchema<SetTypeSubArg<T, 'authorization', AuthRules[]>, UsedMethods | 'authorization'>;
|
|
67
|
+
}, UsedMethods> & BaseSchema<T> & DDBSchemaBrand;
|
|
68
|
+
type RDSModelSchemaFunctions = 'setSqlStatementFolderPath' | 'addQueries' | 'addMutations' | 'addSubscriptions' | 'authorization';
|
|
69
|
+
export type RDSModelSchema<T extends RDSModelSchemaParamShape, UsedMethods extends RDSModelSchemaFunctions = never> = Omit<{
|
|
70
|
+
setSqlStatementFolderPath: (path: string) => RDSModelSchema<T, UsedMethods | 'setSqlStatementFolderPath'>;
|
|
71
|
+
addQueries: (types: Record<string, QueryCustomOperation>) => RDSModelSchema<T, UsedMethods | 'addQueries'>;
|
|
72
|
+
addMutations: (types: Record<string, MutationCustomOperation>) => RDSModelSchema<T, UsedMethods | 'addMutations'>;
|
|
73
|
+
addSubscriptions: (types: Record<string, SubscriptionCustomOperation>) => RDSModelSchema<T, UsedMethods | 'addSubscriptions'>;
|
|
74
|
+
authorization: <AuthRules extends SchemaAuthorization<any, any, any>>(auth: AuthRules[]) => RDSModelSchema<SetTypeSubArg<T, 'authorization', AuthRules[]>, UsedMethods | 'authorization'> & RDSSchemaBrand;
|
|
75
|
+
}, UsedMethods> & BaseSchema<T> & RDSSchemaBrand;
|
|
67
76
|
/**
|
|
68
77
|
* Amplify API Next Model Schema shape
|
|
69
78
|
*/
|
|
@@ -78,7 +87,7 @@ type SchemaReturnType<DE extends DatasourceEngine, Types extends ModelSchemaCont
|
|
|
78
87
|
types: Types;
|
|
79
88
|
authorization: [];
|
|
80
89
|
configuration: any;
|
|
81
|
-
}> :
|
|
90
|
+
}> : RDSModelSchema<{
|
|
82
91
|
types: Types;
|
|
83
92
|
authorization: [];
|
|
84
93
|
configuration: any;
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.configure = exports.schema = exports.isModelSchema = void 0;
|
|
3
|
+
exports.configure = exports.schema = exports.isModelSchema = exports.ddbSchemaBrandName = exports.rdsSchemaBrand = exports.rdsSchemaBrandName = void 0;
|
|
4
4
|
const ModelType_1 = require("./ModelType");
|
|
5
5
|
const SchemaProcessor_1 = require("./SchemaProcessor");
|
|
6
|
+
const util_1 = require("./util");
|
|
7
|
+
exports.rdsSchemaBrandName = 'RDSSchema';
|
|
8
|
+
exports.rdsSchemaBrand = (0, util_1.brand)(exports.rdsSchemaBrandName);
|
|
9
|
+
exports.ddbSchemaBrandName = 'DDBSchema';
|
|
10
|
+
const ddbSchemaBrand = (0, util_1.brand)(exports.ddbSchemaBrandName);
|
|
6
11
|
/**
|
|
7
12
|
* Filter the schema types down to only include the ModelTypes as SchemaModelType
|
|
8
13
|
*
|
|
@@ -29,9 +34,23 @@ const isModelSchema = (schema) => {
|
|
|
29
34
|
return typeof schema === 'object' && schema.data !== undefined;
|
|
30
35
|
};
|
|
31
36
|
exports.isModelSchema = isModelSchema;
|
|
32
|
-
function
|
|
37
|
+
function _rdsSchema(types, config) {
|
|
38
|
+
const data = {
|
|
39
|
+
types,
|
|
40
|
+
authorization: [],
|
|
41
|
+
configuration: config,
|
|
42
|
+
};
|
|
33
43
|
return {
|
|
34
|
-
|
|
44
|
+
data,
|
|
45
|
+
transform() {
|
|
46
|
+
const internalSchema = { data };
|
|
47
|
+
return (0, SchemaProcessor_1.processSchema)({ schema: internalSchema });
|
|
48
|
+
},
|
|
49
|
+
authorization(rules) {
|
|
50
|
+
this.data.authorization = rules;
|
|
51
|
+
const { authorization: _, ...rest } = this;
|
|
52
|
+
return rest;
|
|
53
|
+
},
|
|
35
54
|
setSqlStatementFolderPath(path) {
|
|
36
55
|
this.data.setSqlStatementFolderPath = path;
|
|
37
56
|
const { setSqlStatementFolderPath: _, ...rest } = this;
|
|
@@ -52,9 +71,10 @@ function _sqlSchemaExtension(schema) {
|
|
|
52
71
|
const { addSubscriptions: _, ...rest } = this;
|
|
53
72
|
return rest;
|
|
54
73
|
},
|
|
74
|
+
...exports.rdsSchemaBrand,
|
|
55
75
|
};
|
|
56
76
|
}
|
|
57
|
-
function
|
|
77
|
+
function _ddbSchema(types, config) {
|
|
58
78
|
const data = {
|
|
59
79
|
types,
|
|
60
80
|
authorization: [],
|
|
@@ -72,13 +92,14 @@ function _baseSchema(types, config) {
|
|
|
72
92
|
return rest;
|
|
73
93
|
},
|
|
74
94
|
models: filterSchemaModelTypes(data.types),
|
|
95
|
+
...ddbSchemaBrand,
|
|
75
96
|
};
|
|
76
97
|
}
|
|
77
98
|
function bindConfigToSchema(config) {
|
|
78
99
|
return (types) => {
|
|
79
100
|
return (config.database.engine === 'dynamodb'
|
|
80
|
-
?
|
|
81
|
-
:
|
|
101
|
+
? _ddbSchema(types, config)
|
|
102
|
+
: _rdsSchema(types, config));
|
|
82
103
|
};
|
|
83
104
|
}
|
|
84
105
|
/**
|
package/lib-esm/src/RefType.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ type RefTypeData = {
|
|
|
9
9
|
valueRequired: boolean;
|
|
10
10
|
array: boolean;
|
|
11
11
|
arrayRequired: boolean;
|
|
12
|
+
mutationOperations: MutationOperations[];
|
|
12
13
|
authorization: Authorization<any, any, any>[];
|
|
13
14
|
};
|
|
14
15
|
export type RefTypeParamShape = {
|
|
@@ -19,6 +20,7 @@ export type RefTypeParamShape = {
|
|
|
19
20
|
arrayRequired: boolean;
|
|
20
21
|
authorization: Authorization<any, any, any>[];
|
|
21
22
|
};
|
|
23
|
+
type MutationOperations = 'create' | 'update' | 'delete';
|
|
22
24
|
export type RefType<T extends RefTypeParamShape, K extends keyof RefType<T> = never, Auth = undefined> = Omit<{
|
|
23
25
|
/**
|
|
24
26
|
* Marks a field as required.
|
|
@@ -33,6 +35,7 @@ export type RefType<T extends RefTypeParamShape, K extends keyof RefType<T> = ne
|
|
|
33
35
|
* multiple authorization rules for this field.
|
|
34
36
|
*/
|
|
35
37
|
authorization<AuthRuleType extends Authorization<any, any, any>>(rules: AuthRuleType[]): RefType<T, K | 'authorization', AuthRuleType>;
|
|
38
|
+
mutations(operations: MutationOperations[]): RefType<T, K | 'mutations'>;
|
|
36
39
|
}, K> & {
|
|
37
40
|
[__auth]?: Auth;
|
|
38
41
|
} & Brand<typeof brandName>;
|
package/lib-esm/src/RefType.js
CHANGED
|
@@ -13,6 +13,7 @@ function _ref(link) {
|
|
|
13
13
|
valueRequired: false,
|
|
14
14
|
array: false,
|
|
15
15
|
arrayRequired: false,
|
|
16
|
+
mutationOperations: [],
|
|
16
17
|
authorization: [],
|
|
17
18
|
};
|
|
18
19
|
const builder = brandedBuilder({
|
|
@@ -33,6 +34,10 @@ function _ref(link) {
|
|
|
33
34
|
data.authorization = rules;
|
|
34
35
|
return this;
|
|
35
36
|
},
|
|
37
|
+
mutations(operations) {
|
|
38
|
+
data.mutationOperations = operations;
|
|
39
|
+
return this;
|
|
40
|
+
},
|
|
36
41
|
});
|
|
37
42
|
return { ...builder, data };
|
|
38
43
|
}
|
|
@@ -176,8 +176,8 @@ function transformFunctionHandler(handlers, callSignature) {
|
|
|
176
176
|
});
|
|
177
177
|
return { gqlHandlerContent, lambdaFunctionDefinition };
|
|
178
178
|
}
|
|
179
|
-
function customOperationToGql(typeName, typeDef, authorization, isCustom = false, databaseType) {
|
|
180
|
-
const { arguments: fieldArgs, returnType, functionRef, handlers, } = typeDef.data;
|
|
179
|
+
function customOperationToGql(typeName, typeDef, authorization, isCustom = false, databaseType, getRefType) {
|
|
180
|
+
const { arguments: fieldArgs, typeName: opType, returnType, functionRef, handlers, subscriptionSource, } = typeDef.data;
|
|
181
181
|
let callSignature = typeName;
|
|
182
182
|
const implicitModels = [];
|
|
183
183
|
const { authString } = isCustom
|
|
@@ -218,6 +218,21 @@ function customOperationToGql(typeName, typeDef, authorization, isCustom = false
|
|
|
218
218
|
else if (databaseType === 'sql' && handler && brand === 'sqlReference') {
|
|
219
219
|
gqlHandlerContent = `@sql(reference: "${(0, Handler_1.getHandlerData)(handler)}") `;
|
|
220
220
|
}
|
|
221
|
+
if (opType === 'Subscription') {
|
|
222
|
+
const subscriptionSources = subscriptionSource
|
|
223
|
+
.flatMap((source) => {
|
|
224
|
+
const refTarget = source.data.link;
|
|
225
|
+
const { type } = getRefType(refTarget, typeName);
|
|
226
|
+
if (type === 'CustomOperation') {
|
|
227
|
+
return refTarget;
|
|
228
|
+
}
|
|
229
|
+
if (type === 'Model') {
|
|
230
|
+
return source.data.mutationOperations.map((op) => `${op}${refTarget}`);
|
|
231
|
+
}
|
|
232
|
+
})
|
|
233
|
+
.join('", "');
|
|
234
|
+
gqlHandlerContent += `@aws_subscribe(mutations: ["${subscriptionSources}"]) `;
|
|
235
|
+
}
|
|
221
236
|
const gqlField = `${callSignature}: ${returnTypeName} ${gqlHandlerContent}${authString}`;
|
|
222
237
|
return { gqlField, models: implicitModels, lambdaFunctionDefinition };
|
|
223
238
|
}
|
|
@@ -732,6 +747,31 @@ const extractFunctionSchemaAccess = (authRules) => {
|
|
|
732
747
|
}
|
|
733
748
|
return { schemaAuth, functionSchemaAccess };
|
|
734
749
|
};
|
|
750
|
+
/**
|
|
751
|
+
* Returns a closure for retrieving reference type and definition from schema
|
|
752
|
+
*/
|
|
753
|
+
const getRefTypeForSchema = (schema) => {
|
|
754
|
+
const getRefType = (source, target) => {
|
|
755
|
+
const typeDef = schema.data.types[source];
|
|
756
|
+
if (typeDef === undefined) {
|
|
757
|
+
throw new Error(`Invalid ref. ${target} is referencing ${source} which is not defined in the schema`);
|
|
758
|
+
}
|
|
759
|
+
if (isInternalModel(typeDef)) {
|
|
760
|
+
return { type: 'Model', def: typeDef };
|
|
761
|
+
}
|
|
762
|
+
if (isCustomOperation(typeDef)) {
|
|
763
|
+
return { type: 'CustomOperation', def: typeDef };
|
|
764
|
+
}
|
|
765
|
+
if (isCustomType(typeDef)) {
|
|
766
|
+
return { type: 'CustomType', def: typeDef };
|
|
767
|
+
}
|
|
768
|
+
if (isEnumType(typeDef)) {
|
|
769
|
+
return { type: 'Enum', def: typeDef };
|
|
770
|
+
}
|
|
771
|
+
throw new Error(`Invalid ref. ${target} is referencing ${source} which is neither a Model, Custom Operation, Custom Type, or Enum`);
|
|
772
|
+
};
|
|
773
|
+
return getRefType;
|
|
774
|
+
};
|
|
735
775
|
const schemaPreprocessor = (schema) => {
|
|
736
776
|
const gqlModels = [];
|
|
737
777
|
const customQueries = [];
|
|
@@ -746,6 +786,7 @@ const schemaPreprocessor = (schema) => {
|
|
|
746
786
|
const fkFields = allImpliedFKs(schema);
|
|
747
787
|
const topLevelTypes = Object.entries(schema.data.types);
|
|
748
788
|
const { schemaAuth, functionSchemaAccess } = extractFunctionSchemaAccess(schema.data.authorization);
|
|
789
|
+
const getRefType = getRefTypeForSchema(schema);
|
|
749
790
|
for (const [typeName, typeDef] of topLevelTypes) {
|
|
750
791
|
validateAuth(typeDef.data?.authorization);
|
|
751
792
|
const mostRelevantAuthRules = typeDef.data?.authorization?.length > 0
|
|
@@ -773,7 +814,7 @@ const schemaPreprocessor = (schema) => {
|
|
|
773
814
|
}
|
|
774
815
|
else if (isCustomOperation(typeDef)) {
|
|
775
816
|
const { typeName: opType } = typeDef.data;
|
|
776
|
-
const { gqlField, models, jsFunctionForField, lambdaFunctionDefinition, } = transformCustomOperations(typeDef, typeName, mostRelevantAuthRules, databaseType);
|
|
817
|
+
const { gqlField, models, jsFunctionForField, lambdaFunctionDefinition, } = transformCustomOperations(typeDef, typeName, mostRelevantAuthRules, databaseType, getRefType);
|
|
777
818
|
lambdaFunctions = lambdaFunctionDefinition;
|
|
778
819
|
topLevelTypes.push(...models);
|
|
779
820
|
if (jsFunctionForField) {
|
|
@@ -849,8 +890,8 @@ const schemaPreprocessor = (schema) => {
|
|
|
849
890
|
lambdaFunctions,
|
|
850
891
|
};
|
|
851
892
|
};
|
|
852
|
-
function validateCustomOperations(typeDef, typeName, authRules) {
|
|
853
|
-
const { functionRef, handlers } = typeDef.data;
|
|
893
|
+
function validateCustomOperations(typeDef, typeName, authRules, getRefType) {
|
|
894
|
+
const { functionRef, handlers, typeName: opType, subscriptionSource, returnType, } = typeDef.data;
|
|
854
895
|
// TODO: remove `functionRef` after deprecating
|
|
855
896
|
const handlerConfigured = functionRef !== null || handlers?.length;
|
|
856
897
|
const authConfigured = authRules.length > 0;
|
|
@@ -873,6 +914,57 @@ function validateCustomOperations(typeDef, typeName, authRules) {
|
|
|
873
914
|
throw new Error(`Field handlers must be of the same type. ${typeName} has been configured with ${configuredHandlersStr}`);
|
|
874
915
|
}
|
|
875
916
|
}
|
|
917
|
+
if (opType === 'Subscription') {
|
|
918
|
+
if (subscriptionSource.length < 1) {
|
|
919
|
+
throw new Error(`${typeName} is missing a mutation source. Custom subscriptions must reference a mutation source via subscription().for(a.ref('ModelOrOperationName')) `);
|
|
920
|
+
}
|
|
921
|
+
subscriptionSource.forEach((source) => {
|
|
922
|
+
const sourceName = source.data.link;
|
|
923
|
+
const { type, def } = getRefType(sourceName, typeName);
|
|
924
|
+
if (type !== 'Model' && source.data.mutationOperations.length > 0) {
|
|
925
|
+
throw new Error(`Invalid subscription definition. .mutations() modifier can only be used with a Model ref. ${typeName} is referencing ${type}`);
|
|
926
|
+
}
|
|
927
|
+
if (type === 'Model' && source.data.mutationOperations.length === 0) {
|
|
928
|
+
throw new Error(`Invalid subscription definition. .mutations() modifier must be used with a Model ref subscription source. ${typeName} is referencing ${sourceName} without specifying a mutation`);
|
|
929
|
+
}
|
|
930
|
+
if (type === 'CustomOperation' && def.data.typeName !== 'Mutation') {
|
|
931
|
+
throw new Error(`Invalid subscription definition. .for() can only reference a mutation. ${typeName} is referencing ${sourceName} which is a ${def.data.typeName}`);
|
|
932
|
+
}
|
|
933
|
+
// Ensure subscription return type matches the return type of triggering mutation(s)
|
|
934
|
+
// TODO: when we remove .returns() for custom subscriptions, minor changes will be needed here. Instead of comparing subscriptionSource return val
|
|
935
|
+
// to a root returnType, we'll need to ensure that each subscriptionSource has the same return type
|
|
936
|
+
if (returnType.data.type === 'ref') {
|
|
937
|
+
const returnTypeName = returnType.data.link;
|
|
938
|
+
if (type === 'Model') {
|
|
939
|
+
if (returnTypeName !== sourceName ||
|
|
940
|
+
returnType.data.array !== source.data.array) {
|
|
941
|
+
throw new Error(`Invalid subscription definition. Subscription return type must match the return type of the mutation triggering it. ${typeName} is referencing ${sourceName} which has a different return type`);
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
if (type === 'CustomOperation') {
|
|
945
|
+
const customOperationReturnType = def.data.returnType.data.link;
|
|
946
|
+
const customOperationReturnTypeArray = def.data.returnType.data.array;
|
|
947
|
+
if (returnTypeName !== customOperationReturnType ||
|
|
948
|
+
returnType.data.array !== customOperationReturnTypeArray) {
|
|
949
|
+
throw new Error(`Invalid subscription definition. Subscription return type must match the return type of the mutation triggering it. ${typeName} is referencing ${sourceName} which has a different return type`);
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
else if (returnType.data.fieldType !== undefined) {
|
|
954
|
+
if (type === 'Model') {
|
|
955
|
+
throw new Error(`Invalid subscription definition. Subscription return type must match the return type of the mutation triggering it. ${typeName} is referencing ${sourceName} which has a different return type`);
|
|
956
|
+
}
|
|
957
|
+
if (type === 'CustomOperation') {
|
|
958
|
+
const customOperationReturnType = def.data.returnType.data.fieldType;
|
|
959
|
+
const customOperationReturnTypeArray = def.data.returnType.data.array;
|
|
960
|
+
if (returnType.data.fieldType !== customOperationReturnType ||
|
|
961
|
+
returnType.data.array !== customOperationReturnTypeArray) {
|
|
962
|
+
throw new Error(`Invalid subscription definition. Subscription return type must match the return type of the mutation triggering it. ${typeName} is referencing ${sourceName} which has a different return type`);
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
});
|
|
967
|
+
}
|
|
876
968
|
}
|
|
877
969
|
const isCustomHandler = (handler) => {
|
|
878
970
|
return Array.isArray(handler) && (0, util_1.getBrand)(handler[0]) === 'customHandler';
|
|
@@ -933,15 +1025,15 @@ const handleCustom = (handlers, opType, typeName) => {
|
|
|
933
1025
|
};
|
|
934
1026
|
return jsFn;
|
|
935
1027
|
};
|
|
936
|
-
function transformCustomOperations(typeDef, typeName, authRules, databaseType) {
|
|
1028
|
+
function transformCustomOperations(typeDef, typeName, authRules, databaseType, getRefType) {
|
|
937
1029
|
const { typeName: opType, handlers } = typeDef.data;
|
|
938
1030
|
let jsFunctionForField = undefined;
|
|
939
|
-
validateCustomOperations(typeDef, typeName, authRules);
|
|
1031
|
+
validateCustomOperations(typeDef, typeName, authRules, getRefType);
|
|
940
1032
|
if (isCustomHandler(handlers)) {
|
|
941
1033
|
jsFunctionForField = handleCustom(handlers, opType, typeName);
|
|
942
1034
|
}
|
|
943
1035
|
const isCustom = Boolean(jsFunctionForField);
|
|
944
|
-
const { gqlField, models, lambdaFunctionDefinition } = customOperationToGql(typeName, typeDef, authRules, isCustom, databaseType);
|
|
1036
|
+
const { gqlField, models, lambdaFunctionDefinition } = customOperationToGql(typeName, typeDef, authRules, isCustom, databaseType, getRefType);
|
|
945
1037
|
return { gqlField, models, jsFunctionForField, lambdaFunctionDefinition };
|
|
946
1038
|
}
|
|
947
1039
|
function generateCustomOperationTypes({ queries, mutations, subscriptions, }) {
|