@aws-amplify/data-schema 0.13.3 → 0.13.5
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/internals/package.json +6 -0
- package/lib-esm/src/CustomOperation.d.ts +11 -2
- package/lib-esm/src/CustomOperation.js +5 -0
- package/lib-esm/src/CustomType.d.ts +2 -2
- package/lib-esm/src/EnumType.d.ts +2 -2
- package/lib-esm/src/Handler.d.ts +26 -0
- package/lib-esm/src/Handler.js +26 -0
- package/lib-esm/src/MappedTypes/ExtractNonModelTypes.d.ts +1 -1
- package/lib-esm/src/MappedTypes/ResolveSchema.d.ts +1 -1
- package/lib-esm/src/ModelField.d.ts +2 -2
- package/lib-esm/src/ModelField.js +2 -0
- package/lib-esm/src/ModelIndex.d.ts +3 -3
- package/lib-esm/src/ModelIndex.js +3 -1
- package/lib-esm/src/ModelRelationalField.d.ts +3 -2
- package/lib-esm/src/ModelSchema.d.ts +56 -3
- package/lib-esm/src/ModelSchema.js +45 -18
- package/lib-esm/src/ModelType.d.ts +4 -3
- package/lib-esm/src/ModelType.js +3 -1
- package/lib-esm/src/RefType.d.ts +3 -2
- package/lib-esm/src/SchemaProcessor.js +27 -12
- package/lib-esm/src/index.d.ts +2 -1
- package/lib-esm/src/index.js +3 -1
- package/lib-esm/src/internals/index.d.ts +1 -0
- package/lib-esm/src/internals/index.js +5 -0
- package/lib-esm/src/util/Brand.d.ts +29 -0
- package/lib-esm/src/util/Brand.js +23 -0
- package/lib-esm/src/util/index.d.ts +1 -0
- package/lib-esm/src/util/index.js +5 -0
- package/lib-esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +19 -1
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import { SetTypeSubArg
|
|
1
|
+
import { SetTypeSubArg } from '@aws-amplify/data-schema-types';
|
|
2
|
+
import { Brand } from './util';
|
|
2
3
|
import { ModelField, InternalField } from './ModelField';
|
|
3
4
|
import { Authorization } from './Authorization';
|
|
4
5
|
import { RefType, InternalRef } from './RefType';
|
|
5
6
|
import { EnumType, EnumTypeParamShape } from './EnumType';
|
|
6
7
|
import { CustomType } from './CustomType';
|
|
8
|
+
import { Handler } from './Handler';
|
|
7
9
|
type CustomArguments = Record<string, ModelField<any, any> | EnumType<EnumTypeParamShape>>;
|
|
8
10
|
type CustomReturnType = RefType<any> | CustomType<any>;
|
|
9
11
|
type CustomFunctionRefType = string;
|
|
10
12
|
type InternalCustomArguments = Record<string, InternalField>;
|
|
11
13
|
type InternalCustomReturnType = InternalRef;
|
|
12
14
|
declare const brandName = "customOperation";
|
|
15
|
+
type HandlerInputType = Handler | Handler[];
|
|
13
16
|
export declare const CustomOperationNames: readonly ["Query", "Mutation", "Subscription"];
|
|
14
17
|
type CustomOperationName = (typeof CustomOperationNames)[number];
|
|
15
18
|
type CustomData = {
|
|
@@ -18,6 +21,7 @@ type CustomData = {
|
|
|
18
21
|
functionRef: string | null;
|
|
19
22
|
authorization: Authorization<any, any, any>[];
|
|
20
23
|
typeName: CustomOperationName;
|
|
24
|
+
handlers: Handler[] | null;
|
|
21
25
|
};
|
|
22
26
|
type InternalCustomData = CustomData & {
|
|
23
27
|
arguments: InternalCustomArguments;
|
|
@@ -31,13 +35,15 @@ export type CustomOperationParamShape = {
|
|
|
31
35
|
functionRef: string | null;
|
|
32
36
|
authorization: Authorization<any, any, any>[];
|
|
33
37
|
typeName: CustomOperationName;
|
|
38
|
+
handlers: Handler[] | null;
|
|
34
39
|
};
|
|
35
40
|
export type CustomOperation<T extends CustomOperationParamShape, K extends keyof CustomOperation<T> = never> = Omit<{
|
|
36
41
|
arguments<Arguments extends CustomArguments>(args: Arguments): CustomOperation<SetTypeSubArg<T, 'arguments', Arguments>, K | 'arguments'>;
|
|
37
42
|
returns<ReturnType extends CustomReturnType>(returnType: ReturnType): CustomOperation<SetTypeSubArg<T, 'returnType', ReturnType>, K | 'returns'>;
|
|
38
43
|
function<FunctionRef extends CustomFunctionRefType>(functionRefOrName: FunctionRef): CustomOperation<SetTypeSubArg<T, 'functionRef', FunctionRef>, K | 'function'>;
|
|
39
44
|
authorization<AuthRuleType extends Authorization<any, any, any>>(rules: AuthRuleType[]): CustomOperation<SetTypeSubArg<T, 'authorization', AuthRuleType[]>, K | 'authorization'>;
|
|
40
|
-
|
|
45
|
+
handler(handlers: HandlerInputType): CustomOperation<SetTypeSubArg<T, 'handlers', Handler[]>, K | 'handler'>;
|
|
46
|
+
}, K> & Brand<typeof brandName>;
|
|
41
47
|
/**
|
|
42
48
|
* Internal representation of Custom Type that exposes the `data` property.
|
|
43
49
|
* Used at buildtime.
|
|
@@ -51,6 +57,7 @@ export declare function query(): CustomOperation<{
|
|
|
51
57
|
functionRef: null;
|
|
52
58
|
authorization: [];
|
|
53
59
|
typeName: 'Query';
|
|
60
|
+
handlers: null;
|
|
54
61
|
}>;
|
|
55
62
|
export declare function mutation(): CustomOperation<{
|
|
56
63
|
arguments: CustomArguments;
|
|
@@ -58,6 +65,7 @@ export declare function mutation(): CustomOperation<{
|
|
|
58
65
|
functionRef: null;
|
|
59
66
|
authorization: [];
|
|
60
67
|
typeName: 'Mutation';
|
|
68
|
+
handlers: null;
|
|
61
69
|
}>;
|
|
62
70
|
export declare function subscription(): CustomOperation<{
|
|
63
71
|
arguments: CustomArguments;
|
|
@@ -65,5 +73,6 @@ export declare function subscription(): CustomOperation<{
|
|
|
65
73
|
functionRef: null;
|
|
66
74
|
authorization: [];
|
|
67
75
|
typeName: 'Subscription';
|
|
76
|
+
handlers: null;
|
|
68
77
|
}>;
|
|
69
78
|
export {};
|
|
@@ -17,6 +17,7 @@ function _custom(typeName) {
|
|
|
17
17
|
functionRef: null,
|
|
18
18
|
authorization: [],
|
|
19
19
|
typeName: typeName,
|
|
20
|
+
handlers: null,
|
|
20
21
|
};
|
|
21
22
|
const builder = brandedBuilder({
|
|
22
23
|
arguments(args) {
|
|
@@ -35,6 +36,10 @@ function _custom(typeName) {
|
|
|
35
36
|
data.authorization = rules;
|
|
36
37
|
return this;
|
|
37
38
|
},
|
|
39
|
+
handler(handlers) {
|
|
40
|
+
data.handlers = Array.isArray(handlers) ? handlers : [handlers];
|
|
41
|
+
return this;
|
|
42
|
+
},
|
|
38
43
|
});
|
|
39
44
|
return { ...builder, data };
|
|
40
45
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Brand } from '
|
|
1
|
+
import { Brand } from './util';
|
|
2
2
|
import { ModelField, InternalField, ModelFieldTypeParamOuter } from './ModelField';
|
|
3
3
|
/**
|
|
4
4
|
* Custom Types
|
|
@@ -19,7 +19,7 @@ type InternalCustomTypeData = CustomTypeData & {
|
|
|
19
19
|
export type CustomTypeParamShape = {
|
|
20
20
|
fields: CustomTypeFields;
|
|
21
21
|
};
|
|
22
|
-
export type CustomType<T extends CustomTypeParamShape> = Brand<
|
|
22
|
+
export type CustomType<T extends CustomTypeParamShape> = T & Brand<'customType'>;
|
|
23
23
|
/**
|
|
24
24
|
* Internal representation of CustomType that exposes the `data` property.
|
|
25
25
|
* Used at buildtime.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Brand } from '
|
|
1
|
+
import { Brand } from './util';
|
|
2
2
|
export type EnumTypeParamShape = {
|
|
3
3
|
type: 'enum';
|
|
4
4
|
values: readonly string[];
|
|
5
5
|
};
|
|
6
|
-
export type EnumType<T extends EnumTypeParamShape> = Brand<
|
|
6
|
+
export type EnumType<T extends EnumTypeParamShape> = T & Brand<'enum'>;
|
|
7
7
|
type EnumTypeArgFactory<Values extends readonly string[]> = {
|
|
8
8
|
type: 'enum';
|
|
9
9
|
values: Values;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Brand } from './util';
|
|
2
|
+
declare const brandName = "Handler";
|
|
3
|
+
export type Handler = Brand<typeof brandName>;
|
|
4
|
+
type InlineSqlResult = {
|
|
5
|
+
sql: string;
|
|
6
|
+
} & Handler;
|
|
7
|
+
declare function inlineSql(sql: string): InlineSqlResult;
|
|
8
|
+
type SqlReferenceResult = {
|
|
9
|
+
sqlReference: string;
|
|
10
|
+
} & Handler;
|
|
11
|
+
declare function sqlReference(sqlReference: string): SqlReferenceResult;
|
|
12
|
+
type CustomResult = {
|
|
13
|
+
custom: string;
|
|
14
|
+
} & Handler;
|
|
15
|
+
declare function custom(file: string): CustomResult;
|
|
16
|
+
type FunctionResult = {
|
|
17
|
+
function: (...args: any[]) => any;
|
|
18
|
+
} & Handler;
|
|
19
|
+
declare function fcn(fcn: (...args: any[]) => any): FunctionResult;
|
|
20
|
+
export declare const handler: {
|
|
21
|
+
inlineSql: typeof inlineSql;
|
|
22
|
+
sqlReference: typeof sqlReference;
|
|
23
|
+
custom: typeof custom;
|
|
24
|
+
function: typeof fcn;
|
|
25
|
+
};
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handler = void 0;
|
|
4
|
+
const util_1 = require("./util");
|
|
5
|
+
const brandName = 'Handler';
|
|
6
|
+
function buildHandler() {
|
|
7
|
+
return (0, util_1.brand)(brandName);
|
|
8
|
+
}
|
|
9
|
+
function inlineSql(sql) {
|
|
10
|
+
return { sql, ...buildHandler() };
|
|
11
|
+
}
|
|
12
|
+
function sqlReference(sqlReference) {
|
|
13
|
+
return { sqlReference, ...buildHandler() };
|
|
14
|
+
}
|
|
15
|
+
function custom(file) {
|
|
16
|
+
return { custom: file, ...buildHandler() };
|
|
17
|
+
}
|
|
18
|
+
function fcn(fcn) {
|
|
19
|
+
return { function: fcn, ...buildHandler() };
|
|
20
|
+
}
|
|
21
|
+
exports.handler = {
|
|
22
|
+
inlineSql,
|
|
23
|
+
sqlReference,
|
|
24
|
+
custom,
|
|
25
|
+
function: fcn,
|
|
26
|
+
};
|
|
@@ -15,7 +15,7 @@ export type ExtractNonModelTypes<Schema> = ResolveNonModelFields<ResolveNonModel
|
|
|
15
15
|
*/
|
|
16
16
|
type ExtractImplicitNonModelTypes<Schema, ResolvedModels = ModelTypes<SchemaTypes<Schema>>> = UnionToIntersection<{
|
|
17
17
|
[Model in keyof ResolvedModels]: {
|
|
18
|
-
[Field in keyof ResolvedModels[Model] as ResolvedModels[Model][Field] extends EnumType<EnumTypeParamShape> | CustomType<CustomTypeParamShape> ? `${Capitalize<Field & string>}` : never]: ResolvedModels[Model][Field];
|
|
18
|
+
[Field in keyof ResolvedModels[Model] as ResolvedModels[Model][Field] extends EnumType<EnumTypeParamShape> | CustomType<CustomTypeParamShape> ? `${Capitalize<Model & string>}${Capitalize<Field & string>}` : never]: ResolvedModels[Model][Field];
|
|
19
19
|
};
|
|
20
20
|
}[keyof ResolvedModels]>;
|
|
21
21
|
type ResolveNonModelTypes<Schema, Extracted, ResolvedSchema = SchemaTypes<Schema> & Extracted> = {
|
|
@@ -26,7 +26,7 @@ export type ModelTypes<Schema> = {
|
|
|
26
26
|
export type FieldTypes<T> = {
|
|
27
27
|
[ModelProp in keyof T]: {
|
|
28
28
|
[FieldProp in keyof T[ModelProp]]: T[ModelProp][FieldProp] extends RefType<infer R extends RefTypeParamShape, any, any> ? R['required'] extends true ? T[ModelProp][FieldProp] : T[ModelProp][FieldProp] | null : T[ModelProp][FieldProp] extends EnumType<EnumTypeParamShape> | CustomType<CustomTypeParamShape> ? RefType<{
|
|
29
|
-
link: Capitalize<FieldProp & string
|
|
29
|
+
link: `${Capitalize<ModelProp & string>}${Capitalize<FieldProp & string>}`;
|
|
30
30
|
type: 'ref';
|
|
31
31
|
required: false;
|
|
32
32
|
authorization: [];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Brand } from '
|
|
1
|
+
import { Brand } from './util';
|
|
2
2
|
import { Authorization } from './Authorization';
|
|
3
3
|
/**
|
|
4
4
|
* Used to "attach" auth types to ModelField without exposing them on the builder.
|
|
@@ -73,7 +73,7 @@ export type ModelField<T extends ModelFieldTypeParamOuter, K extends keyof Model
|
|
|
73
73
|
authorization<AuthRuleType extends Authorization<any, any, any>>(rules: AuthRuleType[]): ModelField<T, K | 'authorization', AuthRuleType>;
|
|
74
74
|
}, K> & {
|
|
75
75
|
[__auth]?: Auth;
|
|
76
|
-
} & Brand<
|
|
76
|
+
} & Brand<typeof brandName>;
|
|
77
77
|
/**
|
|
78
78
|
* Internal representation of Model Field that exposes the `data` property.
|
|
79
79
|
* Used at buildtime.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ipAddress = exports.url = exports.phone = exports.json = exports.email = exports.timestamp = exports.datetime = exports.time = exports.date = exports.boolean = exports.float = exports.integer = exports.string = exports.id = exports.ModelFieldDataType = exports.ModelFieldType = exports.__auth = void 0;
|
|
4
|
+
const util_1 = require("./util");
|
|
4
5
|
/**
|
|
5
6
|
* Used to "attach" auth types to ModelField without exposing them on the builder.
|
|
6
7
|
*/
|
|
@@ -81,6 +82,7 @@ function _field(fieldType) {
|
|
|
81
82
|
_meta.lastInvokedMethod = 'authorization';
|
|
82
83
|
return this;
|
|
83
84
|
},
|
|
85
|
+
...(0, util_1.brand)(brandName),
|
|
84
86
|
};
|
|
85
87
|
// this double cast gives us a Subtyping Constraint i.e., hides `data` from the public API,
|
|
86
88
|
// but makes it available internally when needed
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
declare const
|
|
1
|
+
import { Brand } from './util';
|
|
2
|
+
declare const brandName = "modelIndexType";
|
|
3
3
|
export type ModelIndexData = {
|
|
4
4
|
partitionKey: string;
|
|
5
5
|
sortKeys: readonly unknown[];
|
|
@@ -13,6 +13,6 @@ export type ModelIndexType<ModelFieldKeys extends string, PK, SK = readonly [],
|
|
|
13
13
|
sortKeys<FieldKeys extends ModelFieldKeys = ModelFieldKeys, const SK extends ReadonlyArray<Exclude<FieldKeys, PK>> = readonly []>(sortKeys: SK): ModelIndexType<FieldKeys, PK, SK, QueryField, K | 'sortKeys'>;
|
|
14
14
|
name(name: string): ModelIndexType<ModelFieldKeys, PK, SK, QueryField, K | 'name'>;
|
|
15
15
|
queryField<QF extends string = never, MF extends ModelFieldKeys = ModelFieldKeys>(field: QF): ModelIndexType<MF, PK, SK, QF, K | 'queryField'>;
|
|
16
|
-
}, K> & Brand<
|
|
16
|
+
}, K> & Brand<typeof brandName>;
|
|
17
17
|
export declare function modelIndex<ModelFieldKeys extends string, PK extends ModelFieldKeys, SK = readonly [], QueryField = never>(partitionKeyFieldName: PK): ModelIndexType<ModelFieldKeys, PK, SK, QueryField, never>;
|
|
18
18
|
export {};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.modelIndex = void 0;
|
|
4
|
-
const
|
|
4
|
+
const util_1 = require("./util");
|
|
5
|
+
const brandName = 'modelIndexType';
|
|
5
6
|
function _modelIndex(partitionKeyFieldName) {
|
|
6
7
|
const data = {
|
|
7
8
|
partitionKey: partitionKeyFieldName,
|
|
@@ -22,6 +23,7 @@ function _modelIndex(partitionKeyFieldName) {
|
|
|
22
23
|
data.queryField = field;
|
|
23
24
|
return this;
|
|
24
25
|
},
|
|
26
|
+
...(0, util_1.brand)(brandName),
|
|
25
27
|
};
|
|
26
28
|
return { ...builder, data };
|
|
27
29
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { SetTypeSubArg
|
|
1
|
+
import { SetTypeSubArg } from '@aws-amplify/data-schema-types';
|
|
2
|
+
import { Brand } from './util';
|
|
2
3
|
import { Authorization } from './Authorization';
|
|
3
4
|
/**
|
|
4
5
|
* Used to "attach" auth types to ModelField without exposing them on the builder.
|
|
@@ -60,7 +61,7 @@ type ModelRelationalFieldFunctions<T extends ModelRelationalFieldParamShape, RM
|
|
|
60
61
|
};
|
|
61
62
|
export type ModelRelationalField<T extends ModelRelationalFieldParamShape, RM extends string | symbol, K extends keyof ModelRelationalField<T, RM> = never, Auth = undefined> = Omit<ModelRelationalFieldFunctions<T, RM, K>, K> & {
|
|
62
63
|
[__auth]?: Auth;
|
|
63
|
-
} & Brand<
|
|
64
|
+
} & Brand<typeof brandName>;
|
|
64
65
|
/**
|
|
65
66
|
* Internal representation of Model Field that exposes the `data` property.
|
|
66
67
|
* Used at buildtime.
|
|
@@ -3,14 +3,43 @@ import { type ModelType, type ModelTypeParamShape, type InternalModel, SchemaMod
|
|
|
3
3
|
import type { EnumType, EnumTypeParamShape } from './EnumType';
|
|
4
4
|
import type { CustomType, CustomTypeParamShape } from './CustomType';
|
|
5
5
|
import type { CustomOperation, CustomOperationParamShape, InternalCustom } from './CustomOperation';
|
|
6
|
-
export { __auth } from './ModelField';
|
|
7
6
|
import { Authorization } from './Authorization';
|
|
8
7
|
type SchemaContent = ModelType<ModelTypeParamShape, any> | CustomType<CustomTypeParamShape> | EnumType<EnumTypeParamShape> | CustomOperation<CustomOperationParamShape, any>;
|
|
9
8
|
type ModelSchemaContents = Record<string, SchemaContent>;
|
|
10
9
|
type InternalSchemaModels = Record<string, InternalModel | EnumType<any> | CustomType<any> | InternalCustom>;
|
|
10
|
+
/**
|
|
11
|
+
* Importing the full objects from @aws-amplify/plugin-types
|
|
12
|
+
* more than doubles dev env runtime. This type replacement
|
|
13
|
+
* will contain the content for config without the negative
|
|
14
|
+
* side-effects. We may need to re-approach if customers interact
|
|
15
|
+
* with these programmatically to avoid forcing narrowing.
|
|
16
|
+
*/
|
|
17
|
+
type BackendSecret = {
|
|
18
|
+
resolve: (scope: any, backendIdentifier: any) => any;
|
|
19
|
+
resolvePath: (backendIdentifier: any) => any;
|
|
20
|
+
};
|
|
21
|
+
export type DatasourceEngine = 'mysql' | 'postgresql' | 'dynamodb';
|
|
22
|
+
type DatasourceConfig<DE extends DatasourceEngine> = DE extends 'dynamodb' ? {
|
|
23
|
+
engine: DE;
|
|
24
|
+
} : {
|
|
25
|
+
engine: DE;
|
|
26
|
+
hostname: BackendSecret;
|
|
27
|
+
username: BackendSecret;
|
|
28
|
+
password: BackendSecret;
|
|
29
|
+
port: BackendSecret;
|
|
30
|
+
databaseName: BackendSecret;
|
|
31
|
+
vpcConfig?: Record<string, never>;
|
|
32
|
+
};
|
|
33
|
+
export type SchemaConfig<DE extends DatasourceEngine, DC extends DatasourceConfig<DE>> = {
|
|
34
|
+
database: DC;
|
|
35
|
+
};
|
|
11
36
|
export type ModelSchemaParamShape = {
|
|
12
37
|
types: ModelSchemaContents;
|
|
13
38
|
authorization: Authorization<any, any, any>[];
|
|
39
|
+
configuration: SchemaConfig<any, any>;
|
|
40
|
+
};
|
|
41
|
+
export type SQLModelSchemaParamShape = ModelSchemaParamShape & {
|
|
42
|
+
setSqlStatementFolderPath?: string;
|
|
14
43
|
};
|
|
15
44
|
export type InternalSchema = {
|
|
16
45
|
data: {
|
|
@@ -27,6 +56,9 @@ export type ModelSchema<T extends ModelSchemaParamShape, UsedMethods extends 'au
|
|
|
27
56
|
};
|
|
28
57
|
transform: () => DerivedApiDefinition;
|
|
29
58
|
};
|
|
59
|
+
export type SqlModelSchema<T extends SQLModelSchemaParamShape, UsedMethods extends 'authorization' | 'setSqlStatementFolderPath' = never> = ModelSchema<T, Exclude<UsedMethods, 'setSqlStatementFolderPath'>> & Omit<{
|
|
60
|
+
setSqlStatementFolderPath: (path: string) => SqlModelSchema<T, UsedMethods | 'setSqlStatementFolderPath'>;
|
|
61
|
+
}, UsedMethods>;
|
|
30
62
|
/**
|
|
31
63
|
* Amplify API Next Model Schema shape
|
|
32
64
|
*/
|
|
@@ -37,6 +69,15 @@ export type ModelSchemaType = ModelSchema<ModelSchemaParamShape>;
|
|
|
37
69
|
* @returns true if the given value is a ModelSchema
|
|
38
70
|
*/
|
|
39
71
|
export declare const isModelSchema: (schema: string | ModelSchemaType) => schema is ModelSchemaType;
|
|
72
|
+
type SchemaReturnType<DE extends DatasourceEngine, Types extends ModelSchemaContents> = DE extends 'dynamodb' ? ModelSchema<{
|
|
73
|
+
types: Types;
|
|
74
|
+
authorization: [];
|
|
75
|
+
configuration: any;
|
|
76
|
+
}> : SqlModelSchema<{
|
|
77
|
+
types: Types;
|
|
78
|
+
authorization: [];
|
|
79
|
+
configuration: any;
|
|
80
|
+
}>;
|
|
40
81
|
/**
|
|
41
82
|
* The API and data model definition for Amplify Data. Pass in `{ <NAME>: a.model(...) }` to create a database table
|
|
42
83
|
* and exposes CRUDL operations via an API.
|
|
@@ -44,7 +85,19 @@ export declare const isModelSchema: (schema: string | ModelSchemaType) => schema
|
|
|
44
85
|
* @returns An API and data model definition to be deployed with Amplify (Gen 2) experience (`processSchema(...)`)
|
|
45
86
|
* or with the Amplify Data CDK construct (`@aws-amplify/data-construct`)
|
|
46
87
|
*/
|
|
47
|
-
export declare
|
|
88
|
+
export declare const schema: <Types extends ModelSchemaContents>(types: Types) => ModelSchema<{
|
|
48
89
|
types: Types;
|
|
49
90
|
authorization: [];
|
|
50
|
-
|
|
91
|
+
configuration: any;
|
|
92
|
+
}, never>;
|
|
93
|
+
/**
|
|
94
|
+
* Configure wraps schema definition with non-default config to allow usecases other than
|
|
95
|
+
* the default DynamoDB use-case.
|
|
96
|
+
*
|
|
97
|
+
* @param config The SchemaConfig augments the schema with content like the database type
|
|
98
|
+
* @returns
|
|
99
|
+
*/
|
|
100
|
+
export declare function configure<DE extends DatasourceEngine>(config: SchemaConfig<DE, DatasourceConfig<DE>>): {
|
|
101
|
+
schema: <Types extends ModelSchemaContents>(types: Types) => SchemaReturnType<DE, Types>;
|
|
102
|
+
};
|
|
103
|
+
export {};
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.configure = exports.schema = exports.isModelSchema = void 0;
|
|
4
4
|
const ModelType_1 = require("./ModelType");
|
|
5
|
-
var ModelField_1 = require("./ModelField");
|
|
6
|
-
Object.defineProperty(exports, "__auth", { enumerable: true, get: function () { return ModelField_1.__auth; } });
|
|
7
5
|
const SchemaProcessor_1 = require("./SchemaProcessor");
|
|
8
6
|
/**
|
|
9
7
|
* Filter the schema types down to only include the ModelTypes as SchemaModelType
|
|
@@ -31,22 +29,41 @@ const isModelSchema = (schema) => {
|
|
|
31
29
|
return typeof schema === 'object' && schema.data !== undefined;
|
|
32
30
|
};
|
|
33
31
|
exports.isModelSchema = isModelSchema;
|
|
34
|
-
function
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
function _sqlSchemaExtension(schema) {
|
|
33
|
+
return {
|
|
34
|
+
...schema,
|
|
35
|
+
setSqlStatementFolderPath(path) {
|
|
36
|
+
this.data.setSqlStatementFolderPath = path;
|
|
37
|
+
const { setSqlStatementFolderPath: _, ...rest } = this;
|
|
38
|
+
return rest;
|
|
39
|
+
},
|
|
40
40
|
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
}
|
|
42
|
+
function _baseSchema(types, config) {
|
|
43
|
+
const data = {
|
|
44
|
+
types,
|
|
45
|
+
authorization: [],
|
|
46
|
+
configuration: config,
|
|
44
47
|
};
|
|
45
48
|
return {
|
|
46
49
|
data,
|
|
47
|
-
transform
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
transform() {
|
|
51
|
+
const internalSchema = { data };
|
|
52
|
+
return (0, SchemaProcessor_1.processSchema)({ schema: internalSchema });
|
|
53
|
+
},
|
|
54
|
+
authorization(rules) {
|
|
55
|
+
this.data.authorization = rules;
|
|
56
|
+
const { authorization: _, ...rest } = this;
|
|
57
|
+
return rest;
|
|
58
|
+
},
|
|
59
|
+
models: filterSchemaModelTypes(data.types),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function bindConfigToSchema(config) {
|
|
63
|
+
return (types) => {
|
|
64
|
+
return (config.database.engine === 'dynamodb'
|
|
65
|
+
? _baseSchema(types, config)
|
|
66
|
+
: _sqlSchemaExtension(_baseSchema(types, config)));
|
|
50
67
|
};
|
|
51
68
|
}
|
|
52
69
|
/**
|
|
@@ -56,7 +73,17 @@ function _schema(types) {
|
|
|
56
73
|
* @returns An API and data model definition to be deployed with Amplify (Gen 2) experience (`processSchema(...)`)
|
|
57
74
|
* or with the Amplify Data CDK construct (`@aws-amplify/data-construct`)
|
|
58
75
|
*/
|
|
59
|
-
|
|
60
|
-
|
|
76
|
+
exports.schema = bindConfigToSchema({ database: { engine: 'dynamodb' } });
|
|
77
|
+
/**
|
|
78
|
+
* Configure wraps schema definition with non-default config to allow usecases other than
|
|
79
|
+
* the default DynamoDB use-case.
|
|
80
|
+
*
|
|
81
|
+
* @param config The SchemaConfig augments the schema with content like the database type
|
|
82
|
+
* @returns
|
|
83
|
+
*/
|
|
84
|
+
function configure(config) {
|
|
85
|
+
return {
|
|
86
|
+
schema: bindConfigToSchema(config),
|
|
87
|
+
};
|
|
61
88
|
}
|
|
62
|
-
exports.
|
|
89
|
+
exports.configure = configure;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SetTypeSubArg, SecondaryIndexIrShape } from '@aws-amplify/data-schema-types';
|
|
2
|
+
import { Brand } from './util';
|
|
2
3
|
import { ModelField, InternalField } from './ModelField';
|
|
3
4
|
import type { ModelRelationalField, InternalRelationalField } from './ModelRelationalField';
|
|
4
5
|
import { Authorization } from './Authorization';
|
|
@@ -7,7 +8,7 @@ import { EnumType, EnumTypeParamShape } from './EnumType';
|
|
|
7
8
|
import { CustomType, CustomTypeParamShape } from './CustomType';
|
|
8
9
|
import { ModelIndexType, InternalModelIndexType } from './ModelIndex';
|
|
9
10
|
import { SecondaryIndexToIR } from './MappedTypes/MapSecondaryIndexes';
|
|
10
|
-
declare const
|
|
11
|
+
declare const brandName = "modelType";
|
|
11
12
|
type ModelFields = Record<string, ModelField<any, any, any> | ModelRelationalField<any, string, any, any> | RefType<any, any, any> | EnumType<EnumTypeParamShape> | CustomType<CustomTypeParamShape>>;
|
|
12
13
|
type InternalModelFields = Record<string, InternalField | InternalRelationalField>;
|
|
13
14
|
type ModelData = {
|
|
@@ -44,7 +45,7 @@ export type ModelType<T extends ModelTypeParamShape, K extends keyof ModelType<T
|
|
|
44
45
|
identifier<ID extends IdentifierType<T> = []>(identifier: ID): ModelType<SetTypeSubArg<T, 'identifier', ID>, K | 'identifier'>;
|
|
45
46
|
secondaryIndexes<const Indexes extends readonly ModelIndexType<SecondaryIndexFields<ExtractType<T>>, SecondaryIndexFields<ExtractType<T>>, unknown, never, any>[] = readonly [], const IndexesIR extends readonly any[] = SecondaryIndexToIR<Indexes, ExtractType<T>>>(indexes: Indexes): ModelType<SetTypeSubArg<T, 'secondaryIndexes', IndexesIR>, K | 'secondaryIndexes'>;
|
|
46
47
|
authorization<AuthRuleType extends Authorization<any, any, any>>(rules: AuthRuleType[]): ModelType<SetTypeSubArg<T, 'authorization', AuthRuleType[]>, K | 'authorization'>;
|
|
47
|
-
}, K> & Brand<
|
|
48
|
+
}, K> & Brand<typeof brandName>;
|
|
48
49
|
/**
|
|
49
50
|
* External representation of Model Type that exposes the `addRelationships` modifier.
|
|
50
51
|
* Used on the complete schema object.
|
package/lib-esm/src/ModelType.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.model = exports.isSchemaModelType = void 0;
|
|
4
|
-
const
|
|
4
|
+
const util_1 = require("./util");
|
|
5
|
+
const brandName = 'modelType';
|
|
5
6
|
function _model(fields) {
|
|
6
7
|
const data = {
|
|
7
8
|
fields,
|
|
@@ -22,6 +23,7 @@ function _model(fields) {
|
|
|
22
23
|
data.authorization = rules;
|
|
23
24
|
return this;
|
|
24
25
|
},
|
|
26
|
+
...(0, util_1.brand)(brandName),
|
|
25
27
|
};
|
|
26
28
|
return {
|
|
27
29
|
...builder,
|
package/lib-esm/src/RefType.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { SetTypeSubArg
|
|
1
|
+
import { SetTypeSubArg } from '@aws-amplify/data-schema-types';
|
|
2
|
+
import { Brand } from './util';
|
|
2
3
|
import { Authorization } from './Authorization';
|
|
3
4
|
import { __auth } from './ModelField';
|
|
4
5
|
declare const brandName = "ref";
|
|
@@ -26,7 +27,7 @@ export type RefType<T extends RefTypeParamShape, K extends keyof RefType<T> = ne
|
|
|
26
27
|
authorization<AuthRuleType extends Authorization<any, any, any>>(rules: AuthRuleType[]): RefType<T, K | 'authorization', AuthRuleType>;
|
|
27
28
|
}, K> & {
|
|
28
29
|
[__auth]?: Auth;
|
|
29
|
-
} & Brand<
|
|
30
|
+
} & Brand<typeof brandName>;
|
|
30
31
|
/**
|
|
31
32
|
* Internal representation of Ref that exposes the `data` property.
|
|
32
33
|
* Used at buildtime.
|
|
@@ -123,8 +123,8 @@ function refFieldToGql(fieldDef) {
|
|
|
123
123
|
// }
|
|
124
124
|
return field;
|
|
125
125
|
}
|
|
126
|
-
function customOperationToGql(typeName, typeDef) {
|
|
127
|
-
const { arguments: fieldArgs, returnType,
|
|
126
|
+
function customOperationToGql(typeName, typeDef, authorization) {
|
|
127
|
+
const { arguments: fieldArgs, returnType, functionRef } = typeDef.data;
|
|
128
128
|
let callSignature = typeName;
|
|
129
129
|
const implicitModels = [];
|
|
130
130
|
const { authString } = calculateAuth(authorization);
|
|
@@ -143,7 +143,7 @@ function customOperationToGql(typeName, typeDef) {
|
|
|
143
143
|
throw new Error(`Unrecognized return type on ${typeName}`);
|
|
144
144
|
}
|
|
145
145
|
if (Object.keys(fieldArgs).length > 0) {
|
|
146
|
-
const { gqlFields, models } = processFields(fieldArgs, {});
|
|
146
|
+
const { gqlFields, models } = processFields(typeName, fieldArgs, {});
|
|
147
147
|
callSignature += `(${gqlFields.join(', ')})`;
|
|
148
148
|
implicitModels.push(...models);
|
|
149
149
|
}
|
|
@@ -434,7 +434,7 @@ function processFieldLevelAuthRules(fields, authFields) {
|
|
|
434
434
|
}
|
|
435
435
|
return fieldLevelAuthRules;
|
|
436
436
|
}
|
|
437
|
-
function processFields(fields, fieldLevelAuthRules, identifier, partitionKey, secondaryIndexes = {}) {
|
|
437
|
+
function processFields(typeName, fields, fieldLevelAuthRules, identifier, partitionKey, secondaryIndexes = {}) {
|
|
438
438
|
const gqlFields = [];
|
|
439
439
|
const models = [];
|
|
440
440
|
for (const [fieldName, fieldDef] of Object.entries(fields)) {
|
|
@@ -452,12 +452,16 @@ function processFields(fields, fieldLevelAuthRules, identifier, partitionKey, se
|
|
|
452
452
|
gqlFields.push(`${fieldName}: ${refFieldToGql(fieldDef.data)}${fieldAuth}`);
|
|
453
453
|
}
|
|
454
454
|
else if (isEnumType(fieldDef)) {
|
|
455
|
-
|
|
455
|
+
// The inline enum type name should be `<TypeName><FieldName>` to avoid
|
|
456
|
+
// enum type name conflicts
|
|
457
|
+
const enumName = `${capitalize(typeName)}${capitalize(fieldName)}`;
|
|
456
458
|
models.push([enumName, fieldDef]);
|
|
457
459
|
gqlFields.push(`${fieldName}: ${enumName}`);
|
|
458
460
|
}
|
|
459
461
|
else if (isCustomType(fieldDef)) {
|
|
460
|
-
|
|
462
|
+
// The inline CustomType name should be `<TypeName><FieldName>` to avoid
|
|
463
|
+
// CustomType name conflicts
|
|
464
|
+
const customTypeName = `${capitalize(typeName)}${capitalize(fieldName)}`;
|
|
461
465
|
models.push([customTypeName, fieldDef]);
|
|
462
466
|
gqlFields.push(`${fieldName}: ${customTypeName}`);
|
|
463
467
|
}
|
|
@@ -520,8 +524,14 @@ const schemaPreprocessor = (schema) => {
|
|
|
520
524
|
const fkFields = allImpliedFKs(schema);
|
|
521
525
|
const topLevelTypes = Object.entries(schema.data.types);
|
|
522
526
|
for (const [typeName, typeDef] of topLevelTypes) {
|
|
527
|
+
const mostRelevantAuthRules = typeDef.data?.authorization?.length > 0
|
|
528
|
+
? typeDef.data.authorization
|
|
529
|
+
: schema.data.authorization;
|
|
523
530
|
if (!isInternalModel(typeDef)) {
|
|
524
531
|
if (isEnumType(typeDef)) {
|
|
532
|
+
if (typeDef.values.some((value) => /\s/.test(value))) {
|
|
533
|
+
throw new Error(`Values of the enum type ${typeName} should not contain any whitespace.`);
|
|
534
|
+
}
|
|
525
535
|
const enumType = `enum ${typeName} {\n ${typeDef.values.join('\n ')}\n}`;
|
|
526
536
|
gqlModels.push(enumType);
|
|
527
537
|
}
|
|
@@ -530,7 +540,7 @@ const schemaPreprocessor = (schema) => {
|
|
|
530
540
|
const authString = '';
|
|
531
541
|
const authFields = {};
|
|
532
542
|
const fieldLevelAuthRules = processFieldLevelAuthRules(fields, authFields);
|
|
533
|
-
const { gqlFields, models } = processFields(fields, fieldLevelAuthRules);
|
|
543
|
+
const { gqlFields, models } = processFields(typeName, fields, fieldLevelAuthRules);
|
|
534
544
|
topLevelTypes.push(...models);
|
|
535
545
|
const joined = gqlFields.join('\n ');
|
|
536
546
|
const model = `type ${typeName} ${authString}\n{\n ${joined}\n}`;
|
|
@@ -538,7 +548,15 @@ const schemaPreprocessor = (schema) => {
|
|
|
538
548
|
}
|
|
539
549
|
else if (isCustomOperation(typeDef)) {
|
|
540
550
|
const { typeName: opType } = typeDef.data;
|
|
541
|
-
|
|
551
|
+
if ((mostRelevantAuthRules.length > 0 && !typeDef.data.functionRef) ||
|
|
552
|
+
(typeDef.data.functionRef && mostRelevantAuthRules.length < 1)) {
|
|
553
|
+
// Deploying a custom operation with auth and no handler reference OR
|
|
554
|
+
// with a handler reference but not auth
|
|
555
|
+
// causes the CFN stack to reach an unrecoverable state. Ideally, this should be fixed
|
|
556
|
+
// in the CDK construct, but we're catching it early here as a stopgap
|
|
557
|
+
throw new Error(`Custom operation ${typeName} requires both an authorization rule and a handler reference`);
|
|
558
|
+
}
|
|
559
|
+
const { gqlField, models } = customOperationToGql(typeName, typeDef, mostRelevantAuthRules);
|
|
542
560
|
topLevelTypes.push(...models);
|
|
543
561
|
switch (opType) {
|
|
544
562
|
case 'Query':
|
|
@@ -560,15 +578,12 @@ const schemaPreprocessor = (schema) => {
|
|
|
560
578
|
const identifier = typeDef.data.identifier;
|
|
561
579
|
const [partitionKey] = identifier;
|
|
562
580
|
const transformedSecondaryIndexes = transformedSecondaryIndexesForModel(typeDef.data.secondaryIndexes);
|
|
563
|
-
const mostRelevantAuthRules = typeDef.data.authorization.length > 0
|
|
564
|
-
? typeDef.data.authorization
|
|
565
|
-
: schema.data.authorization;
|
|
566
581
|
const { authString, authFields } = calculateAuth(mostRelevantAuthRules);
|
|
567
582
|
if (authString == '') {
|
|
568
583
|
throw new Error(`Model \`${typeName}\` is missing authorization rules. Add global rules to the schema or ensure every model has its own rules.`);
|
|
569
584
|
}
|
|
570
585
|
const fieldLevelAuthRules = processFieldLevelAuthRules(fields, authFields);
|
|
571
|
-
const { gqlFields, models } = processFields({
|
|
586
|
+
const { gqlFields, models } = processFields(typeName, {
|
|
572
587
|
// ID fields are not merged outside `mergeFieldObjects` to skip
|
|
573
588
|
// validation, because the `identifer()` method doesn't specify or
|
|
574
589
|
// care what the underlying field type is. We should always just defer
|
package/lib-esm/src/index.d.ts
CHANGED
|
@@ -8,4 +8,5 @@ import { allow } from './Authorization';
|
|
|
8
8
|
import { customType } from './CustomType';
|
|
9
9
|
import { enumType } from './EnumType';
|
|
10
10
|
import { query, mutation, subscription } from './CustomOperation';
|
|
11
|
-
|
|
11
|
+
import { handler } from './Handler';
|
|
12
|
+
export { schema, model, modelIndex as index, ref, customType, enumType as enum, query, mutation, subscription, hasOne, hasMany, belongsTo, manyToMany, allow, id, string, integer, float, boolean, date, time, datetime, timestamp, email, json, phone, url, ipAddress, handler, };
|