diff --git a/packages/amplify-category-api/src/category-utils/schema-reader.ts b/packages/amplify-category-api/src/category-utils/schema-reader.ts index 92e861938d..8e18aa201d 100644 --- a/packages/amplify-category-api/src/category-utils/schema-reader.ts +++ b/packages/amplify-category-api/src/category-utils/schema-reader.ts @@ -15,7 +15,9 @@ import { contextUtil } from './context-util'; */ export class SchemaReader { private schemaPath: string; + private schemaDocument: DocumentNode; + private preProcessedSchemaDocument: DocumentNode; getSchemaPath = async (resourceDir: string): Promise => { diff --git a/packages/amplify-category-api/src/graphql-transformer/amplify-cli-feature-flag-adapter.ts b/packages/amplify-category-api/src/graphql-transformer/amplify-cli-feature-flag-adapter.ts index 9bb25609ac..e166509709 100644 --- a/packages/amplify-category-api/src/graphql-transformer/amplify-cli-feature-flag-adapter.ts +++ b/packages/amplify-category-api/src/graphql-transformer/amplify-cli-feature-flag-adapter.ts @@ -5,9 +5,11 @@ export class AmplifyCLIFeatureFlagAdapterBase implements FeatureFlagProvider { getBoolean(featureName: string, defaultValue?: boolean): boolean { return this.getValue(featureName, 'boolean', defaultValue); } + getNumber(featureName: string, defaultValue?: number): number { return this.getValue(featureName, 'number', defaultValue); } + getObject(): object { // Todo: for future extensibility throw new Error('Not implemented'); diff --git a/packages/amplify-category-api/src/graphql-transformer/override.ts b/packages/amplify-category-api/src/graphql-transformer/override.ts index 5ea9e9f048..435c33b142 100644 --- a/packages/amplify-category-api/src/graphql-transformer/override.ts +++ b/packages/amplify-category-api/src/graphql-transformer/override.ts @@ -94,7 +94,9 @@ export function applyFileBasedOverride(stackManager: StackManager, overrideDirPa */ export class InvalidOverrideError extends Error { details: string; + resolution: string; + constructor(error: Error) { super('Executing overrides failed.'); this.name = 'InvalidOverrideError'; diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/api-input-manager/appsync-api-input-state.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/api-input-manager/appsync-api-input-state.ts index 1a1efddfe9..7dae196ae2 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/api-input-manager/appsync-api-input-state.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/api-input-manager/appsync-api-input-state.ts @@ -11,10 +11,14 @@ import * as fs from 'fs-extra'; import { AppSyncCLIInputs } from '../service-walkthrough-types/appsync-user-input-types'; export class AppsyncApiInputState { - #cliInputsFilePath: string; // cli-inputs.json (output) filepath - #resourceName: string; // user friendly name provided by user - #category: string; // category of the resource - #service: string; // AWS service for the resource + #cliInputsFilePath: string; //cli-inputs.json (output) filepath + + #resourceName: string; //user friendly name provided by user + + #category: string; //category of the resource + + #service: string; //AWS service for the resource + #buildFilePath: string; constructor(private readonly context: $TSContext, resourceName: string) { diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/apigw-input-state.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/apigw-input-state.ts index 28fe78877b..4ad6d22fd5 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/apigw-input-state.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/apigw-input-state.ts @@ -19,7 +19,9 @@ import { ApigwWalkthroughReturnPromise } from './service-walkthrough-types/apigw export class ApigwInputState { projectRootPath: string; + resourceName: string; + paths: { [pathName: string]: Path }; constructor(private readonly context: $TSContext, resourceName?: string) { diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/base-api-stack.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/base-api-stack.ts index cb2747c6a3..6a98f20d59 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/base-api-stack.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/base-api-stack.ts @@ -58,22 +58,39 @@ export type ContainersStackProps = Readonly<{ }>; export abstract class ContainersStack extends cdk.Stack { protected readonly vpcId: string; + private readonly vpcCidrBlock: string; + protected readonly subnets: ReadonlyArray; + private readonly clusterName: string; + private readonly zipPath: string; + private readonly cloudMapNamespaceId: string; + protected readonly vpcLinkId: string; + private readonly pipelineWithAwaiter: PipelineWithAwaiter; + protected readonly cloudMapService: cloudmap.CfnService | undefined; + protected readonly ecsService: ecs.CfnService; + protected readonly isAuthCondition: cdk.CfnCondition; + protected readonly appClientId: string | undefined; + protected readonly userPoolId: string | undefined; + protected readonly ecsServiceSecurityGroup: ec2.CfnSecurityGroup; + protected readonly parameters: ReadonlyMap; + protected readonly envName: string; + protected readonly deploymentBucketName: string; + protected readonly awaiterS3Key: string; constructor(scope: Construct, id: string, private readonly props: ContainersStackProps) { diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/cdk-stack-builder/apigw-stack-builder.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/cdk-stack-builder/apigw-stack-builder.ts index cbbdd4309c..711e81baf2 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/cdk-stack-builder/apigw-stack-builder.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/cdk-stack-builder/apigw-stack-builder.ts @@ -18,13 +18,21 @@ const ROOT_CFN_DESCRIPTION = 'API Gateway Resource for AWS Amplify CLI'; export class AmplifyApigwResourceStack extends cdk.Stack implements AmplifyApigwResourceTemplate { restApi: apigw.CfnRestApi; + deploymentResource: apigw.CfnDeployment; + paths: Record; + policies: { [pathName: string]: ApigwPathPolicy }; + private _scope: Construct; + private _props: ApigwInputs; + private _cfnParameterMap: Map = new Map(); + private _cfnParameterValues: Record; + private _seenLogicalIds: Set; constructor(scope: Construct, id: string, props: ApigwInputs) { diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/cdk-stack-builder/apigw-stack-transform.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/cdk-stack-builder/apigw-stack-transform.ts index be0ca1b870..d1acf1856e 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/cdk-stack-builder/apigw-stack-transform.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/cdk-stack-builder/apigw-stack-transform.ts @@ -22,11 +22,17 @@ import { AmplifyApigwResourceStack, ApigwInputs, CrudOperation, Path } from '.'; export class ApigwStackTransform { cliInputs: ApigwInputs; + resourceTemplateObj: AmplifyApigwResourceStack | undefined; + cliInputsState: ApigwInputState; + cfn: Template; + cfnInputParams: Record; + resourceName: string; + private _app: cdk.App; constructor(context: $TSContext, resourceName: string, cliInputState?: ApigwInputState) { diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/docker-compose/ecs-objects/container.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/docker-compose/ecs-objects/container.ts index b1568b1867..4a2456c37c 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/docker-compose/ecs-objects/container.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/docker-compose/ecs-objects/container.ts @@ -10,18 +10,29 @@ class Container implements IContainerDefinitions { }; build: string | IBuildConfig | undefined; + name: string; + portMappings: PortMappings; + logConfiguration = this.defaultLogConfiguration; command?: string[]; + entrypoint?: string[]; + env_file?: string[]; + environment?: Record; + image?: string; + healthcheck?: ContainerHealthCheck; + working_dir?: string; + user?: string; + secrets: Set; constructor( diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/docker-compose/ecs-objects/service.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/docker-compose/ecs-objects/service.ts index 63326e002a..73e02c87cd 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/docker-compose/ecs-objects/service.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/docker-compose/ecs-objects/service.ts @@ -30,10 +30,15 @@ const DEFAULT_CONTAINER_MEMORY_CPU = { class Service implements IServiceDefinition { containers: Container[] = []; + apiHealthcheck?: ServiceHealthCheck; + taskResources: TaskConfig = DEFAULT_TASK_MEMORY_CPU; + containerResources: ContainerConfig = DEFAULT_CONTAINER_MEMORY_CPU; + deploymentConfiguration: DeploymentConfiguration = DEFAULT_SERVICE_DEPLYMENT_CONFIG; + desiredCount: number = DEFAULT_DESIRED_COUNT; constructor( diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/pipeline-with-awaiter.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/pipeline-with-awaiter.ts index 888fcfa466..3b5e513842 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/pipeline-with-awaiter.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/pipeline-with-awaiter.ts @@ -92,6 +92,7 @@ class PipelineAwaiter extends Construct { export class PipelineWithAwaiter extends Construct { pipelineName: string; + constructor( scope: Construct, id: string, @@ -251,11 +252,17 @@ export class PipelineWithAwaiter extends Construct { clusterName: service.cluster, env: {}, } as ecs.ICluster; + serviceArn = cdk.Fn.ref(service.attrServiceArn); + serviceName = service.serviceName; + stack = cdk.Stack.of(this); + env = {} as any; + node = service.node; + public applyRemovalPolicy(policy: cdk.RemovalPolicy): void { // TODO: This is added for CDK upgrade. Modify the behavior if required. } diff --git a/packages/amplify-e2e-core/src/asciinema-recorder.ts b/packages/amplify-e2e-core/src/asciinema-recorder.ts index a6817a9b67..2217a8a43a 100644 --- a/packages/amplify-e2e-core/src/asciinema-recorder.ts +++ b/packages/amplify-e2e-core/src/asciinema-recorder.ts @@ -18,13 +18,21 @@ export type Recording = { export class Recorder { private isPaused: boolean = false; + private childProcess: pty.IPty; + private onDataHandlers: ((data: string) => void)[] = []; + private onExitHandlers: ((exitCode: number, signal: string | number) => void)[] = []; + private startTime: number; + private recording: Recording; + private cwd: string; + private exitCode: number | undefined; + constructor( private cmd: string, private args: string[], @@ -83,6 +91,7 @@ export class Recorder { addOnExitHandlers(fn: (code: number, signal: string | number) => void) { this.onExitHandlers.push(fn); } + removeOnExitHandlers(fn: (code: number, signal: string | number) => void): boolean { const idx = this.onExitHandlers.indexOf(fn); if (idx === -1) { diff --git a/packages/amplify-e2e-core/src/cli-version-controller.ts b/packages/amplify-e2e-core/src/cli-version-controller.ts index 2333a05e23..43e4f174fb 100644 --- a/packages/amplify-e2e-core/src/cli-version-controller.ts +++ b/packages/amplify-e2e-core/src/cli-version-controller.ts @@ -13,6 +13,7 @@ import * as e2eCore from '.'; */ class CLIVersionController { #getCLIPathSpy: jest.SpyInstance; + /** * All CLI calls (that use getCLIVersion) will use the specified CLI version */ diff --git a/packages/amplify-graphql-auth-transformer/src/accesscontrol/acm.ts b/packages/amplify-graphql-auth-transformer/src/accesscontrol/acm.ts index cd26a3d7de..596ebf912f 100644 --- a/packages/amplify-graphql-auth-transformer/src/accesscontrol/acm.ts +++ b/packages/amplify-graphql-auth-transformer/src/accesscontrol/acm.ts @@ -35,9 +35,13 @@ type ResourceOperationInput = { */ export class AccessControlMatrix { private name: string; + private roles: Array; + private operations: Array; + private resources: Array; + private matrix: Array>>; constructor(config: ACMConfig) { diff --git a/packages/amplify-graphql-auth-transformer/src/graphql-auth-transformer.ts b/packages/amplify-graphql-auth-transformer/src/graphql-auth-transformer.ts index 0639c00d0c..bc2cb268fe 100644 --- a/packages/amplify-graphql-auth-transformer/src/graphql-auth-transformer.ts +++ b/packages/amplify-graphql-auth-transformer/src/graphql-auth-transformer.ts @@ -161,20 +161,31 @@ const getReadRolesForField = (acm: AccessControlMatrix, readRoles: Array */ export class AuthTransformer extends TransformerAuthBase implements TransformerAuthProvider { private config: AuthTransformerConfig; + private configuredAuthProviders: ConfiguredAuthProviders; + private rules: AuthRule[]; + // access control private roleMap: Map; + private authModelConfig: Map; + private authNonModelConfig: Map; + // model config private modelDirectiveConfig: Map; + // schema generation private seenNonModelTypes: Map>; + // iam policy generation private generateIAMPolicyForUnauthRole: boolean; + private generateIAMPolicyForAuthRole: boolean; + private authPolicyResources = new Set(); + private unauthPolicyResources = new Set(); /** diff --git a/packages/amplify-graphql-default-value-transformer/src/validators.ts b/packages/amplify-graphql-default-value-transformer/src/validators.ts index 95591493b5..187d25a3ec 100644 --- a/packages/amplify-graphql-default-value-transformer/src/validators.ts +++ b/packages/amplify-graphql-default-value-transformer/src/validators.ts @@ -105,18 +105,32 @@ interface Indexable { export class TypeValidators implements Indexable { [key: string]: any; + ID = validateString; + String = validateString; + Int = validateInt; + Float = validateFloat; + Boolean = validateBoolean; + AWSJSON = validateJson; + AWSDate = validateAwsDate; + AWSTime = validateAwsTime; + AWSDateTime = validateAwsDateTime; + AWSTimestamp = validateAwsTimestamp; + AWSEmail = validateAwsEmail; + AWSURL = validateAwsUrl; + AWSPhone = validateAwsPhone; + AWSIPAddress = validateAwsIpAddress; } diff --git a/packages/amplify-graphql-index-transformer/src/graphql-index-transformer.ts b/packages/amplify-graphql-index-transformer/src/graphql-index-transformer.ts index 54e45eb411..d6ee7d8586 100644 --- a/packages/amplify-graphql-index-transformer/src/graphql-index-transformer.ts +++ b/packages/amplify-graphql-index-transformer/src/graphql-index-transformer.ts @@ -34,6 +34,7 @@ const directiveDefinition = ` */ export class IndexTransformer extends TransformerPluginBase { private directiveList: IndexDirectiveConfiguration[] = []; + private resolverMap: Map = new Map(); constructor() { diff --git a/packages/amplify-graphql-index-transformer/src/graphql-primary-key-transformer.ts b/packages/amplify-graphql-index-transformer/src/graphql-primary-key-transformer.ts index 1b0fccfe7a..a3d9a56586 100644 --- a/packages/amplify-graphql-index-transformer/src/graphql-primary-key-transformer.ts +++ b/packages/amplify-graphql-index-transformer/src/graphql-primary-key-transformer.ts @@ -41,6 +41,7 @@ const directiveDefinition = ` export class PrimaryKeyTransformer extends TransformerPluginBase { private directiveList: PrimaryKeyDirectiveConfiguration[] = []; + private resolverMap: Map = new Map(); constructor() { diff --git a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts index e9c73441f9..5759f988d8 100644 --- a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts +++ b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts @@ -118,16 +118,24 @@ const DDB_DATASOURCE_TYPE = { dbType: DDB_DB_TYPE, provisioned: true }; */ export class ModelTransformer extends TransformerModelBase implements TransformerModelProvider { private options: ModelTransformerOptions; + private datasourceMap: Record = {}; + private ddbTableMap: Record = {}; + private resolverMap: Record = {}; + private typesWithModelDirective: Set = new Set(); + private resourceGeneratorMap: Map = new Map(); + private modelToDatasourceMap: Map = new Map(); + /** * A Map to hold the directive configuration */ private modelDirectiveConfig: Map = new Map(); + constructor(options: ModelTransformerOptions = {}) { super('amplify-model-transformer', directiveDefinition); this.options = this.getOptions(options); diff --git a/packages/amplify-graphql-model-transformer/src/resolvers/generators/dynamodb-vtl-generator.ts b/packages/amplify-graphql-model-transformer/src/resolvers/generators/dynamodb-vtl-generator.ts index 821999c10d..f666b6ae8b 100644 --- a/packages/amplify-graphql-model-transformer/src/resolvers/generators/dynamodb-vtl-generator.ts +++ b/packages/amplify-graphql-model-transformer/src/resolvers/generators/dynamodb-vtl-generator.ts @@ -25,36 +25,47 @@ export class DynamoDBModelVTLGenerator implements ModelVTLGenerator { generateUpdateRequestTemplate(config: ModelUpdateRequestConfig): string { return generateUpdateRequestTemplate(config.modelName, config.isSyncEnabled); } + generateCreateRequestTemplate(config: ModelCreateRequestConfig): string { return generateCreateRequestTemplate(config.modelName, config.modelIndexFields); } + generateCreateInitSlotTemplate(config: ModelCreateInitSlotConfig): string { return generateCreateInitSlotTemplate(config.modelConfig); } + generateDeleteRequestTemplate(config: ModelUpdateRequestConfig): string { return generateDeleteRequestTemplate(config.modelName, config.isSyncEnabled); } + generateUpdateInitSlotTemplate(config: ModelCreateInitSlotConfig): string { return generateUpdateInitSlotTemplate(config.modelConfig); } + generateGetRequestTemplate(config: ModelRequestConfig): string { return generateGetRequestTemplate(); } + generateGetResponseTemplate(config: ModelUpdateRequestConfig): string { return generateGetResponseTemplate(config.isSyncEnabled); } + generateListRequestTemplate(config: ModelRequestConfig): string { return generateListRequestTemplate(); } + generateSyncRequestTemplate(config: ModelRequestConfig): string { return generateSyncRequestTemplate(); } + generateSubscriptionRequestTemplate(): string { return generateSubscriptionRequestTemplate(); } + generateSubscriptionResponseTemplate(): string { return generateSubscriptionResponseTemplate(); } + generateDefaultResponseMappingTemplate(config: ModelDefaultResponseConfig): string { return generateDefaultResponseMappingTemplate(config.isSyncEnabled, config.mutation); } diff --git a/packages/amplify-graphql-model-transformer/src/resolvers/generators/rds-vtl-generator.ts b/packages/amplify-graphql-model-transformer/src/resolvers/generators/rds-vtl-generator.ts index 317e53db00..4209c05e6b 100644 --- a/packages/amplify-graphql-model-transformer/src/resolvers/generators/rds-vtl-generator.ts +++ b/packages/amplify-graphql-model-transformer/src/resolvers/generators/rds-vtl-generator.ts @@ -24,36 +24,47 @@ export class RDSModelVTLGenerator implements ModelVTLGenerator { generateUpdateRequestTemplate(config: ModelUpdateRequestConfig): string { return generateLambdaUpdateRequestTemplate(config.modelName, config.operationName, config.modelIndexFields ?? ['id']); } + generateCreateRequestTemplate(config: ModelCreateRequestConfig): string { return generateLambdaCreateRequestTemplate(config.modelName, config.operationName); } + generateCreateInitSlotTemplate(config: ModelCreateInitSlotConfig): string { return generateCreateInitSlotTemplate(config.modelConfig); } + generateDeleteRequestTemplate(config: ModelUpdateRequestConfig): string { return generateLambdaDeleteRequestTemplate(config.modelName, config.operationName, config.modelIndexFields ?? ['id']); } + generateUpdateInitSlotTemplate(config: ModelCreateInitSlotConfig): string { return generateUpdateInitSlotTemplate(config.modelConfig); } + generateGetRequestTemplate(config: ModelRequestConfig): string { return generateLambdaRequestTemplate(config.modelName, config.operation, config.operationName); } + generateGetResponseTemplate(config: ModelUpdateRequestConfig): string { return generateGetLambdaResponseTemplate(false); } + generateListRequestTemplate(config: ModelRequestConfig): string { return generateLambdaListRequestTemplate(config.modelName, config.operation, config.operationName); } + generateSyncRequestTemplate(config: ModelRequestConfig): string { return generateDefaultLambdaResponseMappingTemplate(false); } + generateSubscriptionRequestTemplate(): string { return generateSubscriptionRequestTemplate(); } + generateSubscriptionResponseTemplate(): string { return generateSubscriptionResponseTemplate(); } + generateDefaultResponseMappingTemplate(config: ModelDefaultResponseConfig): string { return generateDefaultLambdaResponseMappingTemplate(false); } diff --git a/packages/amplify-graphql-model-transformer/src/resources/model-resource-generator.ts b/packages/amplify-graphql-model-transformer/src/resources/model-resource-generator.ts index 7cc802fd92..82b3ae42c6 100644 --- a/packages/amplify-graphql-model-transformer/src/resources/model-resource-generator.ts +++ b/packages/amplify-graphql-model-transformer/src/resources/model-resource-generator.ts @@ -20,13 +20,21 @@ import { ModelTransformerOptions } from '../types'; */ export abstract class ModelResourceGenerator { protected datasourceMap: Record = {}; + private resolverMap: Record = {}; + protected generatorType = 'ModelResourceGenerator'; + private enabled = false; + private provisioned = false; + private unprovisioned = false; + protected models: Array = new Array(); + protected modelDirectiveMap: Map = new Map(); + protected options: ModelTransformerOptions; constructor(options: ModelTransformerOptions = {}) { diff --git a/packages/amplify-graphql-predictions-transformer/src/graphql-predictions-transformer.ts b/packages/amplify-graphql-predictions-transformer/src/graphql-predictions-transformer.ts index f6717937ab..f445f28c74 100644 --- a/packages/amplify-graphql-predictions-transformer/src/graphql-predictions-transformer.ts +++ b/packages/amplify-graphql-predictions-transformer/src/graphql-predictions-transformer.ts @@ -73,6 +73,7 @@ export type PredictionsConfig = { export class PredictionsTransformer extends TransformerPluginBase { private directiveList: PredictionsDirectiveConfiguration[] = []; + private bucketName: string; constructor(predictionsConfig?: PredictionsConfig) { diff --git a/packages/amplify-graphql-relational-transformer/src/graphql-many-to-many-transformer.ts b/packages/amplify-graphql-relational-transformer/src/graphql-many-to-many-transformer.ts index 3468d38ebf..6744b0d017 100644 --- a/packages/amplify-graphql-relational-transformer/src/graphql-many-to-many-transformer.ts +++ b/packages/amplify-graphql-relational-transformer/src/graphql-many-to-many-transformer.ts @@ -73,10 +73,15 @@ const directiveDefinition = ` */ export class ManyToManyTransformer extends TransformerPluginBase { private relationMap = new Map(); + private directiveList: ManyToManyDirectiveConfiguration[] = []; + private modelTransformer: ModelTransformer; + private indexTransformer: IndexTransformer; + private hasOneTransformer: HasOneTransformer; + private authProvider: TransformerAuthProvider; constructor( diff --git a/packages/amplify-graphql-schema-generator/src/__tests__/mysql-datasource-adapter.test.ts b/packages/amplify-graphql-schema-generator/src/__tests__/mysql-datasource-adapter.test.ts index 58f07a2a20..cd3168a4ad 100644 --- a/packages/amplify-graphql-schema-generator/src/__tests__/mysql-datasource-adapter.test.ts +++ b/packages/amplify-graphql-schema-generator/src/__tests__/mysql-datasource-adapter.test.ts @@ -6,24 +6,30 @@ class TestDataSourceAdapter extends DataSourceAdapter { public async initialize(): Promise { // Do Nothing } + public mapDataType(type: string, nullable: boolean): FieldType { return { kind: 'Scalar', name: 'String', }; } + public async getTablesList(): Promise { return ['Test']; } + public async getFields(tableName: string): Promise { return []; } + public async getPrimaryKey(tableName: string): Promise { return null; } + public async getIndexes(tableName: string): Promise { return []; } + public cleanup(): void { // Do Nothing } diff --git a/packages/amplify-graphql-schema-generator/src/datasource-adapter/datasource-adapter.ts b/packages/amplify-graphql-schema-generator/src/datasource-adapter/datasource-adapter.ts index a82becedbf..ebb61d606f 100644 --- a/packages/amplify-graphql-schema-generator/src/datasource-adapter/datasource-adapter.ts +++ b/packages/amplify-graphql-schema-generator/src/datasource-adapter/datasource-adapter.ts @@ -2,11 +2,17 @@ import { Field, FieldType, Index, Model } from '../schema-representation'; export abstract class DataSourceAdapter { public abstract getTablesList(): Promise; + public abstract getFields(tableName: string): Promise; + public abstract getPrimaryKey(tableName: string): Promise; + public abstract getIndexes(tableName: string): Promise; + public abstract mapDataType(datatype: string, nullable: boolean, tableName: string, fieldName: string, columnType: string): FieldType; + public abstract initialize(): Promise; + public abstract cleanup(): void; public async getModels(): Promise { diff --git a/packages/amplify-graphql-schema-generator/src/datasource-adapter/mysql-datasource-adapter.ts b/packages/amplify-graphql-schema-generator/src/datasource-adapter/mysql-datasource-adapter.ts index 292855f2ac..65e320225d 100644 --- a/packages/amplify-graphql-schema-generator/src/datasource-adapter/mysql-datasource-adapter.ts +++ b/packages/amplify-graphql-schema-generator/src/datasource-adapter/mysql-datasource-adapter.ts @@ -33,9 +33,13 @@ interface MySQLColumn { export class MySQLDataSourceAdapter extends DataSourceAdapter { private dbBuilder: any; + private indexes: MySQLIndex[] = []; + private fields: MySQLColumn[] = []; + private enums: Map = new Map(); + private readonly PRIMARY_KEY_INDEX_NAME = 'PRIMARY'; constructor(private config: MySQLDataSourceConfig) { diff --git a/packages/amplify-graphql-schema-generator/src/schema-representation/schema.ts b/packages/amplify-graphql-schema-generator/src/schema-representation/schema.ts index 28d93822e9..0188fb240c 100644 --- a/packages/amplify-graphql-schema-generator/src/schema-representation/schema.ts +++ b/packages/amplify-graphql-schema-generator/src/schema-representation/schema.ts @@ -3,6 +3,7 @@ import { Engine } from './engine'; export class Schema { private models: Model[] = []; + constructor(private engine: Engine) {} public getModels(): Model[] { diff --git a/packages/amplify-graphql-schema-generator/src/schema-representation/types.ts b/packages/amplify-graphql-schema-generator/src/schema-representation/types.ts index c9a4147a1f..0d317dd83c 100644 --- a/packages/amplify-graphql-schema-generator/src/schema-representation/types.ts +++ b/packages/amplify-graphql-schema-generator/src/schema-representation/types.ts @@ -50,12 +50,15 @@ export interface DefaultValue { export class Field { public default: DefaultValue | undefined = undefined; + public length: number | null | undefined; + constructor(public name: string, public type: FieldType) {} } export class Index { private fields: string[] = []; + constructor(public name: string) {} public getFields(): string[] { @@ -69,7 +72,9 @@ export class Index { export class Model { private fields: Field[] = []; + private primaryKey: Index | undefined = undefined; + private indexes: Index[] = []; constructor(private name: string) {} diff --git a/packages/amplify-graphql-searchable-transformer/src/graphql-searchable-transformer.ts b/packages/amplify-graphql-searchable-transformer/src/graphql-searchable-transformer.ts index 9e68ba556f..27e61f65c3 100644 --- a/packages/amplify-graphql-searchable-transformer/src/graphql-searchable-transformer.ts +++ b/packages/amplify-graphql-searchable-transformer/src/graphql-searchable-transformer.ts @@ -260,6 +260,7 @@ const generateSearchableInputs = (ctx: TransformerSchemaVisitStepContextProvider export class SearchableModelTransformer extends TransformerPluginBase { searchableObjectTypeDefinitions: { node: ObjectTypeDefinitionNode; fieldName: string }[]; + searchableObjectNames: string[]; constructor() { diff --git a/packages/amplify-graphql-transformer-core/src/appsync-function.ts b/packages/amplify-graphql-transformer-core/src/appsync-function.ts index 026e84c485..e682bba0e3 100644 --- a/packages/amplify-graphql-transformer-core/src/appsync-function.ts +++ b/packages/amplify-graphql-transformer-core/src/appsync-function.ts @@ -43,6 +43,7 @@ export class AppSyncFunctionConfiguration extends Construct { * the ARN of the resolver */ public readonly arn: string; + public readonly functionId: string; private function: CfnFunctionConfiguration; diff --git a/packages/amplify-graphql-transformer-core/src/cdk-compat/file-asset.ts b/packages/amplify-graphql-transformer-core/src/cdk-compat/file-asset.ts index 73de2c9573..fc3198223e 100644 --- a/packages/amplify-graphql-transformer-core/src/cdk-compat/file-asset.ts +++ b/packages/amplify-graphql-transformer-core/src/cdk-compat/file-asset.ts @@ -11,10 +11,15 @@ export interface TemplateProps { export class FileAsset extends Construct implements cdk.IAsset { public readonly assetHash: string; + public readonly httpUrl: string; + public readonly s3BucketName: string; + public readonly s3ObjectKey: string; + public readonly s3Url: string; + constructor(scope: Construct, id: string, props: TemplateProps) { super(scope, id); diff --git a/packages/amplify-graphql-transformer-core/src/cdk-compat/nested-stack.ts b/packages/amplify-graphql-transformer-core/src/cdk-compat/nested-stack.ts index cc69adc2c3..27d2ef9627 100644 --- a/packages/amplify-graphql-transformer-core/src/cdk-compat/nested-stack.ts +++ b/packages/amplify-graphql-transformer-core/src/cdk-compat/nested-stack.ts @@ -21,13 +21,19 @@ export type TransformerNestedStackProps = NestedStackProps & { }; export class TransformerNestedStack extends TransformerRootStack { public readonly templateFile: string; + public readonly nestedStackResource?: CfnResource; private readonly parameters: { [name: string]: string }; + private readonly resource: CfnStack; + private readonly _contextualStackId: string; + private readonly _contextualStackName: string; + private _templateUrl?: string; + private _rootStack: Stack; constructor(scope: Construct, id: string, props: TransformerNestedStackProps = {}) { diff --git a/packages/amplify-graphql-transformer-core/src/cdk-compat/schema-asset.ts b/packages/amplify-graphql-transformer-core/src/cdk-compat/schema-asset.ts index 48cffbe2c2..9d89cd2c7c 100644 --- a/packages/amplify-graphql-transformer-core/src/cdk-compat/schema-asset.ts +++ b/packages/amplify-graphql-transformer-core/src/cdk-compat/schema-asset.ts @@ -5,10 +5,13 @@ import { FileAsset } from './file-asset'; export class TransformerSchema { private asset?: FileAsset; + private api?: GraphQLApi; + private definition = ''; private schemaConstruct?: CfnGraphQLSchema; + bind = (api: GraphQLApi): CfnGraphQLSchema => { if (!this.schemaConstruct) { const schema = this; @@ -35,6 +38,7 @@ export class TransformerSchema { } return this.asset; }; + addToSchema = (addition: string, delimiter: string): void => { const sep = delimiter ?? ''; this.definition = `${this.definition}${sep}${addition}\n`; diff --git a/packages/amplify-graphql-transformer-core/src/cdk-compat/stack-synthesizer.ts b/packages/amplify-graphql-transformer-core/src/cdk-compat/stack-synthesizer.ts index c48d384b58..6f1bcb9521 100644 --- a/packages/amplify-graphql-transformer-core/src/cdk-compat/stack-synthesizer.ts +++ b/packages/amplify-graphql-transformer-core/src/cdk-compat/stack-synthesizer.ts @@ -8,8 +8,11 @@ import { TransformerRootStack } from './root-stack'; */ export class TransformerStackSythesizer extends LegacyStackSynthesizer { private readonly stackAssets: Map = new Map(); + private readonly mapingTemplateAssets: Map = new Map(); + private _deploymentBucket?: CfnParameter; + private _deploymentRootKey?: CfnParameter; /** diff --git a/packages/amplify-graphql-transformer-core/src/cdk-compat/template-asset.ts b/packages/amplify-graphql-transformer-core/src/cdk-compat/template-asset.ts index 2489e980b7..707851e8ec 100644 --- a/packages/amplify-graphql-transformer-core/src/cdk-compat/template-asset.ts +++ b/packages/amplify-graphql-transformer-core/src/cdk-compat/template-asset.ts @@ -11,8 +11,11 @@ import { FileAsset } from './file-asset'; export class S3MappingFunctionCode implements S3MappingFunctionCodeProvider { public readonly type = MappingTemplateType.S3_LOCATION; + private asset?: FileAsset; + private fileName: string; + private filePath: string; constructor(fileName: string, filePath: string) { @@ -32,8 +35,11 @@ export class S3MappingFunctionCode implements S3MappingFunctionCodeProvider { } export class S3MappingTemplate implements S3MappingTemplateProvider { private content: string; + private name: string; + private asset?: FileAsset; + public readonly type = MappingTemplateType.S3_LOCATION; static fromInlineTemplate(code: string, templateName?: string): S3MappingTemplate { @@ -80,6 +86,7 @@ export class InlineTemplate implements InlineMappingTemplateProvider { // eslint-disable-next-line no-useless-constructor constructor(private content: string) {} + bind(): string { return this.content; } diff --git a/packages/amplify-graphql-transformer-core/src/errors/index.ts b/packages/amplify-graphql-transformer-core/src/errors/index.ts index 36929181cc..2e59ec64a5 100644 --- a/packages/amplify-graphql-transformer-core/src/errors/index.ts +++ b/packages/amplify-graphql-transformer-core/src/errors/index.ts @@ -76,7 +76,9 @@ export class TransformerContractError extends Error { */ export class InvalidMigrationError extends Error { fix: string; + causedBy: string; + constructor(message: string, causedBy: string, fix: string) { super(message); Object.setPrototypeOf(this, InvalidMigrationError.prototype); diff --git a/packages/amplify-graphql-transformer-core/src/graphql-api.ts b/packages/amplify-graphql-transformer-core/src/graphql-api.ts index fe38a18d24..bfd188b3cf 100644 --- a/packages/amplify-graphql-transformer-core/src/graphql-api.ts +++ b/packages/amplify-graphql-transformer-core/src/graphql-api.ts @@ -180,8 +180,11 @@ export class GraphQLApi extends GraphqlApiBase implements GraphQLAPIProvider { public readonly environmentName?: string; private schemaResource: CfnGraphQLSchema; + private api: CfnGraphQLApi; + private apiKeyResource?: CfnApiKey; + private authorizationConfig?: Required; constructor(scope: Construct, id: string, props: TransformerAPIProps) { diff --git a/packages/amplify-graphql-transformer-core/src/transform-host.ts b/packages/amplify-graphql-transformer-core/src/transform-host.ts index e800d599bb..0144478a2f 100644 --- a/packages/amplify-graphql-transformer-core/src/transform-host.ts +++ b/packages/amplify-graphql-transformer-core/src/transform-host.ts @@ -37,8 +37,11 @@ export interface DefaultTransformHostOptions { export class DefaultTransformHost implements TransformHostProvider { private dataSources: Map = new Map(); + private resolvers: Map = new Map(); + private appsyncFunctions: Map = new Map(); + private api: GraphQLApi; public constructor(options: DefaultTransformHostOptions) { diff --git a/packages/amplify-graphql-transformer-core/src/transformation/transform.ts b/packages/amplify-graphql-transformer-core/src/transformation/transform.ts index 78d039aea4..e0b67a6811 100644 --- a/packages/amplify-graphql-transformer-core/src/transformation/transform.ts +++ b/packages/amplify-graphql-transformer-core/src/transformation/transform.ts @@ -86,12 +86,19 @@ export interface GraphQLTransformOptions { export type StackMapping = { [resourceId: string]: string }; export class GraphQLTransform { private transformers: TransformerPluginProvider[]; + private stackMappingOverrides: StackMapping; + private app: App | undefined; + private readonly authConfig: AppSyncAuthConfiguration; + private readonly resolverConfig?: ResolverConfig; + private readonly userDefinedSlots: Record; + private readonly overrideConfig?: OverrideConfig; + private readonly transformParameters: TransformParameters; // A map from `${directive}.${typename}.${fieldName?}`: true diff --git a/packages/amplify-graphql-transformer-core/src/transformation/transformer-plugin-base.ts b/packages/amplify-graphql-transformer-core/src/transformation/transformer-plugin-base.ts index 256492e767..677da59592 100644 --- a/packages/amplify-graphql-transformer-core/src/transformation/transformer-plugin-base.ts +++ b/packages/amplify-graphql-transformer-core/src/transformation/transformer-plugin-base.ts @@ -33,10 +33,13 @@ import { InvalidTransformerError } from '../errors'; */ export abstract class TransformerPluginBase implements TransformerPluginProvider { public readonly name: string; + public readonly directive: DirectiveDefinitionNode; public readonly typeDefinitions: TypeDefinitionNode[]; + private logs: TransformerLog[]; + constructor( name: string, document: DocumentNode | string, diff --git a/packages/amplify-graphql-transformer-core/src/transformer-context/datasource.ts b/packages/amplify-graphql-transformer-core/src/transformer-context/datasource.ts index 5b61ac2e1f..961fc5acd1 100644 --- a/packages/amplify-graphql-transformer-core/src/transformer-context/datasource.ts +++ b/packages/amplify-graphql-transformer-core/src/transformer-context/datasource.ts @@ -4,6 +4,7 @@ import { ObjectTypeDefinitionNode, InterfaceTypeDefinitionNode } from 'graphql'; export class TransformerDataSourceManager implements TransformerDataSourceManagerProvider { private dataSourceMap: Map = new Map(); + add = (type: ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode, dataSourceInstance: BackedDataSource) => { const key = type.name.value; if (this.dataSourceMap.has(key)) { diff --git a/packages/amplify-graphql-transformer-core/src/transformer-context/index.ts b/packages/amplify-graphql-transformer-core/src/transformer-context/index.ts index 3ebe08754d..e75c34213b 100644 --- a/packages/amplify-graphql-transformer-core/src/transformer-context/index.ts +++ b/packages/amplify-graphql-transformer-core/src/transformer-context/index.ts @@ -44,19 +44,31 @@ export class TransformerContextMetadata implements TransformerContextMetadataPro export class TransformerContext implements TransformerContextProvider { public readonly output: TransformerContextOutputProvider; + public readonly resolvers: ResolverManager; + public readonly dataSources: TransformerDataSourceManagerProvider; + public readonly providerRegistry: TransformerContextProviderRegistry; + public readonly stackManager: StackManagerProvider; + public readonly resourceHelper: TransformerResourceHelper; + public readonly transformParameters: TransformParameters; + public _api?: GraphQLAPIProvider; + public readonly authConfig: AppSyncAuthConfiguration; + private resolverConfig: ResolverConfig | undefined; + public readonly modelToDatasourceMap: Map; + public readonly datasourceSecretParameterLocations: Map; public metadata: TransformerContextMetadata; + constructor( app: App, public readonly inputDocument: DocumentNode, @@ -91,6 +103,7 @@ export class TransformerContext implements TransformerContextProvider { this._api = api; this.resourceHelper.bind(api); } + public get api(): GraphQLAPIProvider { if (!this._api) { throw new Error('API is not initialized till generateResolver step'); diff --git a/packages/amplify-graphql-transformer-core/src/transformer-context/model-field-map.ts b/packages/amplify-graphql-transformer-core/src/transformer-context/model-field-map.ts index 91fd1a6f90..7db23721fe 100644 --- a/packages/amplify-graphql-transformer-core/src/transformer-context/model-field-map.ts +++ b/packages/amplify-graphql-transformer-core/src/transformer-context/model-field-map.ts @@ -6,6 +6,7 @@ import _ from 'lodash'; */ export class ModelFieldMapImpl implements ModelFieldMap { readonly #fieldMapping: FieldMapEntry[] = []; + readonly #resolverReferences: ResolverReferenceEntry[] = []; /** diff --git a/packages/amplify-graphql-transformer-core/src/transformer-context/output.ts b/packages/amplify-graphql-transformer-core/src/transformer-context/output.ts index 298482dea3..331be54423 100644 --- a/packages/amplify-graphql-transformer-core/src/transformer-context/output.ts +++ b/packages/amplify-graphql-transformer-core/src/transformer-context/output.ts @@ -127,6 +127,7 @@ export class TransformerOutput implements TransformerContextOutputProvider { } } } + public getTypeDefinitionsOfKind(kind: string) { const typeDefs: TypeDefinitionNode[] = []; for (const key of Object.keys(this.nodeMap)) { @@ -141,9 +142,11 @@ export class TransformerOutput implements TransformerContextOutputProvider { public putSchema(obj: SchemaDefinitionNode) { this.nodeMap.__schema = obj; } + public getSchema(): SchemaDefinitionNode { return this.nodeMap.__schema as SchemaDefinitionNode; } + public getQueryTypeName(): string | undefined { const schemaNode = this.getSchema(); const queryTypeName = schemaNode.operationTypes.find((op: OperationTypeDefinitionNode) => op.operation === 'query'); @@ -151,6 +154,7 @@ export class TransformerOutput implements TransformerContextOutputProvider { return queryTypeName.type.name.value; } } + public getQuery(): ObjectTypeDefinitionNode | undefined { const queryTypeName = this.getQueryTypeName(); if (queryTypeName) { @@ -198,6 +202,7 @@ export class TransformerOutput implements TransformerContextOutputProvider { } this.nodeMap[obj.name.value] = obj; } + public putType(obj: TypeDefinitionNode) { this.nodeMap[obj.name.value] = obj; } @@ -609,6 +614,7 @@ export class TransformerOutput implements TransformerContextOutputProvider { }, }; } + private static makeSchema(operationTypes: OperationTypeDefinitionNode[]): SchemaDefinitionNode { return { kind: Kind.SCHEMA_DEFINITION, diff --git a/packages/amplify-graphql-transformer-core/src/transformer-context/pre-process-context.ts b/packages/amplify-graphql-transformer-core/src/transformer-context/pre-process-context.ts index dc7d2094f4..e4543014ed 100644 --- a/packages/amplify-graphql-transformer-core/src/transformer-context/pre-process-context.ts +++ b/packages/amplify-graphql-transformer-core/src/transformer-context/pre-process-context.ts @@ -5,7 +5,9 @@ import { TransformerSchemaHelper } from './schema-helper'; export class TransformerPreProcessContext implements TransformerPreProcessContextProvider { inputDocument: DocumentNode; + transformParameters: TransformParameters; + schemaHelper: TransformerSchemaHelperProvider; constructor(inputDocument: DocumentNode, transformParameters: TransformParameters) { diff --git a/packages/amplify-graphql-transformer-core/src/transformer-context/provider-registry.ts b/packages/amplify-graphql-transformer-core/src/transformer-context/provider-registry.ts index 46c79e6520..6042166270 100644 --- a/packages/amplify-graphql-transformer-core/src/transformer-context/provider-registry.ts +++ b/packages/amplify-graphql-transformer-core/src/transformer-context/provider-registry.ts @@ -8,6 +8,7 @@ import { ObjectTypeDefinitionNode, InterfaceTypeDefinitionNode } from 'graphql'; export class TransformerContextProviderRegistry implements TransformerProviderRegistry { private dataSourceProviderRegistry: Map = new Map(); + private dataSourceEnhancerRegistry: Map> = new Map(); registerDataSourceProvider = (type: ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode, provider: TransformerModelProvider) => { @@ -17,6 +18,7 @@ export class TransformerContextProviderRegistry implements TransformerProviderRe } this.dataSourceProviderRegistry.set(typeName, provider); }; + getDataSourceProvider = (type: ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode): TransformerModelProvider => { const typeName = type.name.value; if (this.dataSourceProviderRegistry.has(typeName)) { @@ -24,6 +26,7 @@ export class TransformerContextProviderRegistry implements TransformerProviderRe } throw new Error(`No data source provider has been registered for type ${typeName}`); }; + hasDataSourceProvider = (type: ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode): boolean => { const typeName = type.name.value; return this.dataSourceProviderRegistry.has(typeName); diff --git a/packages/amplify-graphql-transformer-core/src/transformer-context/resolver.ts b/packages/amplify-graphql-transformer-core/src/transformer-context/resolver.ts index 29753064d9..a642148e10 100644 --- a/packages/amplify-graphql-transformer-core/src/transformer-context/resolver.ts +++ b/packages/amplify-graphql-transformer-core/src/transformer-context/resolver.ts @@ -130,8 +130,11 @@ export class ResolverManager implements TransformerResolversManagerProvider { */ export class TransformerResolver implements TransformerResolverProvider { private readonly slotMap: Map = new Map(); + private readonly slotNames: Set; + private stack?: Stack; + constructor( private typeName: string, private fieldName: string, diff --git a/packages/amplify-graphql-transformer-core/src/transformer-context/resource-helper.ts b/packages/amplify-graphql-transformer-core/src/transformer-context/resource-helper.ts index 658d9a4a09..bc23e66bff 100644 --- a/packages/amplify-graphql-transformer-core/src/transformer-context/resource-helper.ts +++ b/packages/amplify-graphql-transformer-core/src/transformer-context/resource-helper.ts @@ -11,6 +11,7 @@ import { StackManager } from './stack-manager'; */ export class TransformerResourceHelper implements TransformerResourceHelperProvider { private api?: GraphQLAPIProvider; + private exclusionSet = new Set(); // a mapping of models that have been renamed with @mapsTo diff --git a/packages/amplify-graphql-transformer-core/src/transformer-context/stack-manager.ts b/packages/amplify-graphql-transformer-core/src/transformer-context/stack-manager.ts index 17c9d309af..acdba6fe85 100644 --- a/packages/amplify-graphql-transformer-core/src/transformer-context/stack-manager.ts +++ b/packages/amplify-graphql-transformer-core/src/transformer-context/stack-manager.ts @@ -9,11 +9,17 @@ export type ResourceToStackMap = Record; */ export class StackManager implements StackManagerProvider { private stacks: Map = new Map(); + private childStackSynthesizers: Map = new Map(); + private stackSynthesizer = new TransformerStackSythesizer(); + public readonly rootStack: TransformerRootStack; + private resourceToStackMap: Map; + private paramMap: Map = new Map(); + constructor(app: App, resourceMapping: ResourceToStackMap) { this.rootStack = new TransformerRootStack(app, 'transformer-root-stack', { synthesizer: this.stackSynthesizer, diff --git a/packages/amplify-graphql-transformer-core/src/utils/directive-wrapper.ts b/packages/amplify-graphql-transformer-core/src/utils/directive-wrapper.ts index a1d34a3649..80dfa8b9a4 100644 --- a/packages/amplify-graphql-transformer-core/src/utils/directive-wrapper.ts +++ b/packages/amplify-graphql-transformer-core/src/utils/directive-wrapper.ts @@ -8,7 +8,9 @@ export type GetArgumentsOptions = { export class ArgumentWrapper { public readonly name: NameNode; + public readonly value: ValueNode; + constructor(argument: ArgumentNode) { this.name = argument.name; this.value = argument.value; @@ -25,8 +27,11 @@ export class ArgumentWrapper { export class DirectiveWrapper { private arguments: ArgumentWrapper[] = []; + private name: NameNode; + private location?: Location; + constructor(node: DirectiveNode) { this.name = node.name; this.arguments = (node.arguments ?? []).map((arg) => new ArgumentWrapper(arg)); diff --git a/packages/amplify-graphql-transformer-core/src/wrappers/object-definition-wrapper.ts b/packages/amplify-graphql-transformer-core/src/wrappers/object-definition-wrapper.ts index 969247ab67..54970626f1 100644 --- a/packages/amplify-graphql-transformer-core/src/wrappers/object-definition-wrapper.ts +++ b/packages/amplify-graphql-transformer-core/src/wrappers/object-definition-wrapper.ts @@ -28,15 +28,20 @@ import { DirectiveWrapper } from '../utils/directive-wrapper'; export class GenericFieldWrapper { protected type: TypeNode; + public readonly directives: DirectiveWrapper[]; + public loc?: Location; + public name: string; + constructor(field: FieldDefinitionNode | InputValueDefinitionNode) { this.type = field.type; this.name = field.name.value; this.loc = field.loc; this.directives = (field.directives || []).map((d) => new DirectiveWrapper(d)); } + isList = (): boolean => { return this.isListType(this.type); }; @@ -94,6 +99,7 @@ export class GenericFieldWrapper { } return node; }; + public getTypeName = (): string => { return this.getBaseType().name.value; }; @@ -126,9 +132,13 @@ export class GenericFieldWrapper { export class InputFieldWrapper extends GenericFieldWrapper { public readonly argumenets?: InputValueDefinitionNode[]; + public readonly description?: StringValueNode; + public type: TypeNode; + public readonly name: string; + public readonly loc?: Location; constructor(protected field: InputValueDefinitionNode) { @@ -210,7 +220,9 @@ export class InputFieldWrapper extends GenericFieldWrapper { } export class FieldWrapper extends GenericFieldWrapper { public readonly argumenets?: InputValueDefinitionNode[]; + public readonly description?: StringValueNode; + public readonly loc?: Location; // arguments to be added @@ -259,8 +271,11 @@ export class FieldWrapper extends GenericFieldWrapper { export class ObjectDefinitionWrapper { public readonly directives?: DirectiveWrapper[]; + public readonly fields: FieldWrapper[]; + public readonly name: string; + constructor(private node: ObjectTypeDefinitionNode) { this.directives = (node.directives || []).map((d) => new DirectiveWrapper(d)); this.fields = (node.fields || []).map((f) => new FieldWrapper(f)); @@ -323,8 +338,11 @@ export class ObjectDefinitionWrapper { export class InputObjectDefinitionWrapper { public readonly directives?: DirectiveWrapper[]; + public readonly fields: InputFieldWrapper[]; + public readonly name: string; + constructor(private node: InputObjectTypeDefinitionNode) { this.directives = (node.directives || []).map((d) => new DirectiveWrapper(d)); this.fields = (node.fields || []).map((f) => new InputFieldWrapper(f)); @@ -338,6 +356,7 @@ export class InputObjectDefinitionWrapper { directives: this.directives?.map((d) => d.serialize()), }; }; + hasField = (name: string): boolean => { const field = this.fields.find((f) => f.name === name); return field ? true : false; @@ -407,8 +426,11 @@ export class InputObjectDefinitionWrapper { export class EnumWrapper { public readonly name: string; + public values: string[]; + public directives: DirectiveWrapper[]; + constructor(private node: EnumTypeDefinitionNode) { this.name = node.name.value; this.values = node.values?.map((v) => v.name.value) || []; @@ -436,6 +458,7 @@ export class EnumWrapper { })), }; }; + static create = (name: string, values: string[] = []): EnumWrapper => { const wrappedEnum = new EnumWrapper({ kind: 'EnumTypeDefinition', diff --git a/packages/amplify-util-mock/src/__e2e__/utils/test-storage.ts b/packages/amplify-util-mock/src/__e2e__/utils/test-storage.ts index 4069410c44..f28f1b2b44 100644 --- a/packages/amplify-util-mock/src/__e2e__/utils/test-storage.ts +++ b/packages/amplify-util-mock/src/__e2e__/utils/test-storage.ts @@ -1,25 +1,31 @@ export default class TestStorage { private data: any; + constructor() { this.data = {}; } + // set item with the key public setItem(key: string, value: string): string { this.data[key] = value; return value; } + // get item with the key public getItem(key: string): string { return this.data[key]; } + // remove item with the key public removeItem(key: string): void { this.data[key] = undefined; } + // clear out the storage public clear(): void { this.data = {}; } + // If the storage operations are async(i.e AsyncStorage) // Then you need to sync those items into the memory in this method public sync(): Promise { diff --git a/packages/amplify-util-mock/src/api/api.ts b/packages/amplify-util-mock/src/api/api.ts index 76b2f86628..6159a905cd 100644 --- a/packages/amplify-util-mock/src/api/api.ts +++ b/packages/amplify-util-mock/src/api/api.ts @@ -24,14 +24,23 @@ export const MOCK_API_PORT = 20002; export class APITest { private apiName: string; + private transformerResult: any; + private ddbClient; + private appSyncSimulator: AmplifyAppSyncSimulator; + private resolverOverrideManager: ResolverOverrides; + private watcher: chokidar.FSWatcher; + private ddbEmulator; + private configOverrideManager: ConfigOverrideManager; + private apiParameters: object = {}; + private userOverriddenSlots: string[] = []; async start(context, port: number = MOCK_API_PORT, wsPort: number = 20003) { @@ -237,6 +246,7 @@ export class APITest { const ddbConfig = this.ddbClient.config; return configureDDBDataSource(config, ddbConfig); } + private async getAppSyncAPI(context) { const currentMeta = await getAmplifyMeta(context); const { api: apis = {} } = currentMeta; @@ -294,6 +304,7 @@ export class APITest { const apiDirectory = await this.getAPIBackendDirectory(context); return apiDirectory; } + private async registerWatcher(context: any): Promise { const watchDir = await this.getAPIBackendDirectory(context); return chokidar.watch(watchDir, { @@ -304,6 +315,7 @@ export class APITest { awaitWriteFinish: true, }); } + private async generateFrontendExports( context: any, localAppSyncDetails: { diff --git a/packages/amplify-util-mock/src/api/resolver-overrides.ts b/packages/amplify-util-mock/src/api/resolver-overrides.ts index 556c380c26..8fc15b89d2 100644 --- a/packages/amplify-util-mock/src/api/resolver-overrides.ts +++ b/packages/amplify-util-mock/src/api/resolver-overrides.ts @@ -4,6 +4,7 @@ import * as chokidar from 'chokidar'; export class ResolverOverrides { private overrides: Set; + private contentMap: Map; constructor( @@ -160,6 +161,7 @@ export class ResolverOverrides { private getRelativePath(filePath: string) { return path.relative(this.resolverTemplateRoot, filePath); } + private getAbsPath(filename: string) { return path.normalize(path.join(this.resolverTemplateRoot, filename)); } @@ -171,6 +173,7 @@ export class ResolverOverrides { onChange(path: string): boolean { return this.onFileChange(path); } + onUnlink(path: string): boolean { const relativePath = this.getRelativePath(path); this.contentMap.delete(relativePath); @@ -180,6 +183,7 @@ export class ResolverOverrides { } return false; } + get resolverTemplateRoot() { return this._rootFolder; } diff --git a/packages/amplify-util-mock/src/storage/storage.ts b/packages/amplify-util-mock/src/storage/storage.ts index a77f2324dc..bc0ee7bea0 100644 --- a/packages/amplify-util-mock/src/storage/storage.ts +++ b/packages/amplify-util-mock/src/storage/storage.ts @@ -30,9 +30,13 @@ async function invokeS3GetUserInputs(context, s3ResourceName) { export class StorageTest { private storageName: string; + private storageSimulator: AmplifyStorageSimulator; + private configOverrideManager: ConfigOverrideManager; + private storageRegion: string; + private bucketName: string; async start(context) { diff --git a/packages/amplify-util-mock/src/utils/config-override.ts b/packages/amplify-util-mock/src/utils/config-override.ts index 51ce79ec9d..fe8ad7c8ac 100644 --- a/packages/amplify-util-mock/src/utils/config-override.ts +++ b/packages/amplify-util-mock/src/utils/config-override.ts @@ -2,8 +2,11 @@ import { getAmplifyMeta } from './index'; export class ConfigOverrideManager { private static instance: ConfigOverrideManager = null; + private overrides: {}; + private amplifyMeta: any = {}; + constructor(context) { this.overrides = {}; context.amplify.addCleanUpTask(async (context) => { diff --git a/packages/amplify-util-mock/src/velocity/index.ts b/packages/amplify-util-mock/src/velocity/index.ts index 4df4074eb1..432d754a3a 100644 --- a/packages/amplify-util-mock/src/velocity/index.ts +++ b/packages/amplify-util-mock/src/velocity/index.ts @@ -48,6 +48,7 @@ export class VelocityTemplateSimulator { }, }); } + render(template: string, payload: AppSyncVTLPayload) { const ctxParameters: AppSyncVTLRenderContext = { source: {}, arguments: { input: {} }, stash: {}, ...payload.context }; const vtlInfo: any = { fieldNodes: [], fragments: {}, path: { key: '' }, ...(payload.info ?? {}) }; diff --git a/packages/graphql-auth-transformer/src/ModelAuthTransformer.ts b/packages/graphql-auth-transformer/src/ModelAuthTransformer.ts index e464a66b98..c62f3c97bc 100644 --- a/packages/graphql-auth-transformer/src/ModelAuthTransformer.ts +++ b/packages/graphql-auth-transformer/src/ModelAuthTransformer.ts @@ -156,11 +156,17 @@ export type ConfiguredAuthProviders = { export class ModelAuthTransformer extends Transformer { resources: ResourceFactory; + config: ModelAuthTransformerConfig; + configuredAuthProviders: ConfiguredAuthProviders; + generateIAMPolicyforUnauthRole: boolean; + generateIAMPolicyforAuthRole: boolean; + authPolicyResources: Set; + unauthPolicyResources: Set; constructor(config?: ModelAuthTransformerConfig) { diff --git a/packages/graphql-auth-transformer/src/resources.ts b/packages/graphql-auth-transformer/src/resources.ts index d3f4b6fbcb..61c4be740b 100644 --- a/packages/graphql-auth-transformer/src/resources.ts +++ b/packages/graphql-auth-transformer/src/resources.ts @@ -396,6 +396,7 @@ groupsField: "${rule.groupsField || DEFAULT_GROUPS_FIELD}", groupClaim: "${rule. this.ownershipAuthorizationExpressionForSubscriptions(rules, variableToCheck, variableToSet), ]); } + public ownershipAuthorizationExpressionForSubscriptions( rules: AuthRule[], variableToCheck: string = 'ctx.args', diff --git a/packages/graphql-dynamodb-transformer/src/DynamoDBModelTransformer.ts b/packages/graphql-dynamodb-transformer/src/DynamoDBModelTransformer.ts index 65c9110f79..c0a7c83a62 100644 --- a/packages/graphql-dynamodb-transformer/src/DynamoDBModelTransformer.ts +++ b/packages/graphql-dynamodb-transformer/src/DynamoDBModelTransformer.ts @@ -97,6 +97,7 @@ export const directiveDefinition = gql` export class DynamoDBModelTransformer extends Transformer { resources: ResourceFactory; + opts: DynamoDBModelTransformerOptions; constructor(opts: DynamoDBModelTransformerOptions = {}) { diff --git a/packages/graphql-key-transformer/src/KeyTransformer.ts b/packages/graphql-key-transformer/src/KeyTransformer.ts index 2a7a2551f8..e65731c2e3 100644 --- a/packages/graphql-key-transformer/src/KeyTransformer.ts +++ b/packages/graphql-key-transformer/src/KeyTransformer.ts @@ -114,6 +114,7 @@ export class KeyTransformer extends Transformer { } } }; + /** * Augment the table key structures based on the @key. */ @@ -755,9 +756,11 @@ export class KeyTransformer extends Transformer { } } } + private typeExist(type: string, ctx: TransformerContext): boolean { return Boolean(type in ctx.nodeMap); } + private supportsConditions(context: TransformerContext) { return context.getTransformerVersion() >= CONDITIONS_MINIMUM_VERSION; } diff --git a/packages/graphql-predictions-transformer/src/PredictionsTransformer.ts b/packages/graphql-predictions-transformer/src/PredictionsTransformer.ts index ef6516e6a1..ad8f85482f 100644 --- a/packages/graphql-predictions-transformer/src/PredictionsTransformer.ts +++ b/packages/graphql-predictions-transformer/src/PredictionsTransformer.ts @@ -22,6 +22,7 @@ export type PredictionsConfig = { export class PredictionsTransformer extends Transformer { resources: ResourceFactory; + predictionsConfig: PredictionsConfig; constructor(predictionsConfig?: PredictionsConfig) { diff --git a/packages/graphql-relational-schema-transformer/src/AuroraDataAPIClient.ts b/packages/graphql-relational-schema-transformer/src/AuroraDataAPIClient.ts index fcb3d11c7c..acd1089e80 100644 --- a/packages/graphql-relational-schema-transformer/src/AuroraDataAPIClient.ts +++ b/packages/graphql-relational-schema-transformer/src/AuroraDataAPIClient.ts @@ -4,7 +4,9 @@ */ export class AuroraDataAPIClient { AWS: any; + RDS: any; + Params: DataApiParams; setRDSClient(rdsClient: any) { @@ -94,17 +96,25 @@ export class AuroraDataAPIClient { export class DataApiParams { database: string; + secretArn: string; + resourceArn: string; + sql: string; } export class ColumnDescription { Field: string; + Type: string; + Null: string; + Key: string; + Default: string; + Extra: string; } diff --git a/packages/graphql-relational-schema-transformer/src/AuroraServerlessMySQLDatabaseReader.ts b/packages/graphql-relational-schema-transformer/src/AuroraServerlessMySQLDatabaseReader.ts index 72050f51af..9fa246f718 100644 --- a/packages/graphql-relational-schema-transformer/src/AuroraServerlessMySQLDatabaseReader.ts +++ b/packages/graphql-relational-schema-transformer/src/AuroraServerlessMySQLDatabaseReader.ts @@ -18,9 +18,13 @@ import { IRelationalDBReader } from './IRelationalDBReader'; */ export class AuroraServerlessMySQLDatabaseReader implements IRelationalDBReader { auroraClient: AuroraDataAPIClient; + dbRegion: string; + awsSecretStoreArn: string; + dbClusterOrInstanceArn: string; + database: string; setAuroraClient(auroraClient: AuroraDataAPIClient) { diff --git a/packages/graphql-relational-schema-transformer/src/RelationalDBResolverGenerator.ts b/packages/graphql-relational-schema-transformer/src/RelationalDBResolverGenerator.ts index de64b23288..2ec4c16f89 100644 --- a/packages/graphql-relational-schema-transformer/src/RelationalDBResolverGenerator.ts +++ b/packages/graphql-relational-schema-transformer/src/RelationalDBResolverGenerator.ts @@ -39,11 +39,17 @@ const rdsResponseErrorType = 'InvalidResponse'; */ export class RelationalDBResolverGenerator { document: DocumentNode; + typePrimaryKeyMap: Map; + stringFieldMap: Map; + intFieldMap: Map; + resolverFilePath: string; + typePrimaryKeyTypeMap: Map; + variableMapRefName: string; constructor(context: TemplateContext) { diff --git a/packages/graphql-relational-schema-transformer/src/RelationalDBSchemaTransformer.ts b/packages/graphql-relational-schema-transformer/src/RelationalDBSchemaTransformer.ts index a00e40d486..6f1f740890 100644 --- a/packages/graphql-relational-schema-transformer/src/RelationalDBSchemaTransformer.ts +++ b/packages/graphql-relational-schema-transformer/src/RelationalDBSchemaTransformer.ts @@ -21,13 +21,20 @@ import { IRelationalDBReader } from './IRelationalDBReader'; */ export class TableContext { tableTypeDefinition: ObjectTypeDefinitionNode; + createTypeDefinition: InputObjectTypeDefinitionNode; + updateTypeDefinition: InputObjectTypeDefinitionNode; + // Table primary key metadata, to help properly key queries and mutations. tableKeyField: string; + tableKeyFieldType: string; + stringFieldList: string[]; + intFieldList: string[]; + constructor( typeDefinition: ObjectTypeDefinitionNode, createDefinition: InputObjectTypeDefinitionNode, @@ -56,14 +63,23 @@ export class TableContext { */ export class TemplateContext { schemaDoc: DocumentNode; + typePrimaryKeyMap: Map; + typePrimaryKeyTypeMap: Map; + stringFieldMap: Map; + intFieldMap: Map; + secretStoreArn: string; + rdsClusterIdentifier: string; + databaseName: string; + databaseSchema: string; + region: string; constructor( @@ -83,7 +99,9 @@ export class TemplateContext { export class RelationalDBSchemaTransformer { dbReader: IRelationalDBReader; + database: string; + improvePluralization: boolean; constructor(dbReader: IRelationalDBReader, database: string, improvePluralization: boolean) { diff --git a/packages/graphql-transformer-common/src/ModelResourceIDs.ts b/packages/graphql-transformer-common/src/ModelResourceIDs.ts index 2cf412b99c..bda29b67f2 100644 --- a/packages/graphql-transformer-common/src/ModelResourceIDs.ts +++ b/packages/graphql-transformer-common/src/ModelResourceIDs.ts @@ -15,15 +15,19 @@ export class ModelResourceIDs { const tableName = this.#modelNameMap?.get(typeName) ?? typeName; return `${tableName}Table`; } + static ModelTableStreamArn(typeName: string): string { return `${typeName}TableStreamArn`; } + static ModelTableDataSourceID(typeName: string): string { return `${typeName}DataSource`; } + static ModelTableIAMRoleID(typeName: string): string { return `${typeName}IAMRole`; } + static ModelFilterInputTypeName(name: string): string { const nameOverride = DEFAULT_SCALARS[name]; if (nameOverride) { @@ -31,6 +35,7 @@ export class ModelResourceIDs { } return `Model${name}FilterInput`; } + static ModelFilterScalarInputTypeName(name: string, includeFilter: Boolean, isSubscriptionFilter: boolean = false): string { const nameOverride = DEFAULT_SCALARS[name]; if (nameOverride) { @@ -38,6 +43,7 @@ export class ModelResourceIDs { } return `Model${isSubscriptionFilter ? 'Subscription' : ''}${name}${includeFilter ? 'Filter' : ''}Input`; } + static ModelConditionInputTypeName(name: string): string { const nameOverride = DEFAULT_SCALARS[name]; if (nameOverride) { @@ -45,6 +51,7 @@ export class ModelResourceIDs { } return `Model${name}ConditionInput`; } + static ModelKeyConditionInputTypeName(name: string): string { const nameOverride = DEFAULT_SCALARS[name]; if (nameOverride) { @@ -52,21 +59,27 @@ export class ModelResourceIDs { } return `Model${name}KeyConditionInput`; } + static ModelCompositeKeyArgumentName(keyFieldNames: string[]) { return toCamelCase(keyFieldNames.map((n) => graphqlName(n))); } + static ModelCompositeKeySeparator() { return '#'; } + static ModelCompositeAttributeName(keyFieldNames: string[]) { return keyFieldNames.join(ModelResourceIDs.ModelCompositeKeySeparator()); } + static ModelCompositeKeyConditionInputTypeName(modelName: string, keyName: string): string { return `Model${modelName}${keyName}CompositeKeyConditionInput`; } + static ModelCompositeKeyInputTypeName(modelName: string, keyName: string): string { return `Model${modelName}${keyName}CompositeKeyInput`; } + static ModelFilterListInputTypeName(name: string, includeFilter: Boolean, isSubscriptionFilter: boolean = false): string { const nameOverride = DEFAULT_SCALARS[name]; if (nameOverride) { @@ -82,48 +95,63 @@ export class ModelResourceIDs { } return `Model${name}${includeFilter ? 'Filter' : ''}Input`; } + static ModelConnectionTypeName(typeName: string): string { return `Model${typeName}Connection`; } + static IsModelConnectionType(typeName: string): boolean { return /^Model.*Connection$/.test(typeName); } + static GetModelFromConnectionType(typeName: string): string { return /(?<=Model)(.*)(?=Connection)/.exec(typeName)?.[0]; } + static ModelDeleteInputObjectName(typeName: string): string { return graphqlName('Delete' + toUpper(typeName) + 'Input'); } + static ModelUpdateInputObjectName(typeName: string): string { return graphqlName('Update' + toUpper(typeName) + 'Input'); } + static ModelCreateInputObjectName(typeName: string): string { return graphqlName(`Create` + toUpper(typeName) + 'Input'); } + static ModelOnCreateSubscriptionName(typeName: string): string { return graphqlName(`onCreate` + toUpper(typeName)); } + static ModelOnUpdateSubscriptionName(typeName: string): string { return graphqlName(`onUpdate` + toUpper(typeName)); } + static ModelOnDeleteSubscriptionName(typeName: string): string { return graphqlName(`onDelete` + toUpper(typeName)); } + static ModelAttributeTypesName(): string { return `ModelAttributeTypes`; } + static ModelSizeInputTypeName(): string { return `ModelSizeInput`; } + static NonModelInputObjectName(typeName: string): string { return graphqlName(toUpper(typeName) + 'Input'); } + static UrlParamsInputObjectName(typeName: string, fieldName: string) { return graphqlName(toUpper(typeName) + toUpper(fieldName) + 'ParamsInput'); } + static HttpQueryInputObjectName(typeName: string, fieldName: string) { return graphqlName(toUpper(typeName) + toUpper(fieldName) + 'QueryInput'); } + static HttpBodyInputObjectName(typeName: string, fieldName: string) { return graphqlName(toUpper(typeName) + toUpper(fieldName) + 'BodyInput'); } diff --git a/packages/graphql-transformer-common/src/PredictionsResourceIDs.ts b/packages/graphql-transformer-common/src/PredictionsResourceIDs.ts index 9199750248..e1383ce31a 100644 --- a/packages/graphql-transformer-common/src/PredictionsResourceIDs.ts +++ b/packages/graphql-transformer-common/src/PredictionsResourceIDs.ts @@ -1,11 +1,18 @@ export class PredictionsResourceIDs { static actionMapID = 'predictionsActionMap'; + static iamRole = 'predictionsIAMRole'; + static lambdaIAMRole = 'predictionsLambdaIAMRole'; + static lambdaName = 'predictionsLambda'; + static lambdaID = 'predictionsLambdaFunction'; + static lambdaHandlerName = 'predictionsLambda.handler'; + static lambdaRuntime = 'nodejs14.x'; + static lambdaTimeout = 60; static getPredictionFunctionName(action: string) { diff --git a/packages/graphql-transformer-common/src/ResolverResourceIDs.ts b/packages/graphql-transformer-common/src/ResolverResourceIDs.ts index 53d5ba7016..6fd50f6d9c 100644 --- a/packages/graphql-transformer-common/src/ResolverResourceIDs.ts +++ b/packages/graphql-transformer-common/src/ResolverResourceIDs.ts @@ -4,24 +4,31 @@ export class ResolverResourceIDs { static DynamoDBCreateResolverResourceID(typeName: string): string { return `Create${resourceName(typeName)}Resolver`; } + static DynamoDBUpdateResolverResourceID(typeName: string): string { return `Update${resourceName(typeName)}Resolver`; } + static DynamoDBDeleteResolverResourceID(typeName: string): string { return `Delete${resourceName(typeName)}Resolver`; } + static DynamoDBGetResolverResourceID(typeName: string): string { return `Get${resourceName(typeName)}Resolver`; } + static DynamoDBListResolverResourceID(typeName: string): string { return `List${resourceName(typeName)}Resolver`; } + static ElasticsearchSearchResolverResourceID(typeName: string): string { return `Search${resourceName(typeName)}Resolver`; } + static SyncResolverResourceID(typeName: string): string { return `Sync${resourceName(typeName)}Resolver`; } + static ResolverResourceID(typeName: string, fieldName: string): string { return `${resourceName(`${typeName}${fieldName}`)}Resolver`; } diff --git a/packages/graphql-transformer-common/src/ResourceConstants.ts b/packages/graphql-transformer-common/src/ResourceConstants.ts index bebbb660e7..8975a52287 100644 --- a/packages/graphql-transformer-common/src/ResourceConstants.ts +++ b/packages/graphql-transformer-common/src/ResourceConstants.ts @@ -2,7 +2,9 @@ export class ResourceConstants { public static NONE = 'NONE'; public static DEFAULT_PAGE_LIMIT = 100; + public static DEFAULT_SYNC_QUERY_PAGE_LIMIT = 100; + public static DEFAULT_SEARCHABLE_PAGE_LIMIT = 100; public static readonly RESOURCES = { @@ -41,6 +43,7 @@ export class ResourceConstants { AuthCognitoUserPoolNativeClientLogicalID: 'AuthCognitoUserPoolNativeClient', AuthCognitoUserPoolJSClientLogicalID: 'AuthCognitoUserPoolJSClient', }; + public static PARAMETERS = { // cli Env: 'env', @@ -91,7 +94,9 @@ export class ResourceConstants { // Auth AuthCognitoUserPoolId: 'AuthCognitoUserPoolId', }; + public static MAPPINGS = {}; + public static CONDITIONS = { // Environment HasEnvironmentParameter: 'HasEnvironmentParameter', @@ -105,6 +110,7 @@ export class ResourceConstants { ShouldCreateAPIKey: 'ShouldCreateAPIKey', APIKeyExpirationEpochIsPositive: 'APIKeyExpirationEpochIsPositive', }; + public static OUTPUTS = { // AppSync GraphQLAPIEndpointOutput: 'GraphQLAPIEndpointOutput', @@ -128,6 +134,7 @@ export class ResourceConstants { AuthCognitoUserPoolNativeClientOutput: 'AuthCognitoUserPoolNativeClientId', AuthCognitoUserPoolJSClientOutput: 'AuthCognitoUserPoolJSClientId', }; + public static METADATA = {}; public static readonly SNIPPETS = { diff --git a/packages/graphql-transformer-common/src/SearchableResourceIDs.ts b/packages/graphql-transformer-common/src/SearchableResourceIDs.ts index 8ffaf72340..a8478d16f0 100644 --- a/packages/graphql-transformer-common/src/SearchableResourceIDs.ts +++ b/packages/graphql-transformer-common/src/SearchableResourceIDs.ts @@ -4,6 +4,7 @@ export class SearchableResourceIDs { static SearchableEventSourceMappingID(typeName: string): string { return `Searchable${typeName}LambdaMapping`; } + static SearchableFilterInputTypeName(name: string): string { const nameOverride = DEFAULT_SCALARS[name]; if (nameOverride) { diff --git a/packages/graphql-transformer-common/src/SyncResourceIDs.ts b/packages/graphql-transformer-common/src/SyncResourceIDs.ts index 82cfb2bf91..00032f00bb 100644 --- a/packages/graphql-transformer-common/src/SyncResourceIDs.ts +++ b/packages/graphql-transformer-common/src/SyncResourceIDs.ts @@ -2,12 +2,19 @@ import { simplifyName } from './util'; export class SyncResourceIDs { public static syncDataSourceID: string = 'DataStore'; + public static syncTableName: string = 'AmplifyDataStore'; + public static syncPrimaryKey: string = 'ds_pk'; + public static syncRangeKey: string = 'ds_sk'; + public static syncIAMRoleID: string = 'DataStoreIAMRole'; + public static syncIAMRoleName: string = 'AmplifyDataStoreIAMRole'; + public static syncFunctionRoleName: string = 'DataStoreLambdaRole'; + public static syncFunctionID(name: string, region?: string): string { return `${simplifyName(name)}${simplifyName(region || '')}Role`; } diff --git a/packages/graphql-transformer-core/src/FeatureFlags.ts b/packages/graphql-transformer-core/src/FeatureFlags.ts index 22ff7061f5..81e12d9f7b 100644 --- a/packages/graphql-transformer-core/src/FeatureFlags.ts +++ b/packages/graphql-transformer-core/src/FeatureFlags.ts @@ -8,9 +8,11 @@ export class NoopFeatureFlagProvider implements FeatureFlagProvider { getBoolean(featureName: string, options?: boolean): boolean { return this.getValue(featureName, options); } + getNumber(featureName: string, options?: number): number { return this.getValue(featureName, options); } + getObject(): object { // Todo: for future extensibility throw new Error('Not implemented'); diff --git a/packages/graphql-transformer-core/src/GraphQLTransform.ts b/packages/graphql-transformer-core/src/GraphQLTransform.ts index 1ba1f3a79d..f92e7281dc 100644 --- a/packages/graphql-transformer-core/src/GraphQLTransform.ts +++ b/packages/graphql-transformer-core/src/GraphQLTransform.ts @@ -197,8 +197,11 @@ export interface GraphQLTransformOptions { export type StackMapping = { [resourceId: string]: string }; export class GraphQLTransform { private transformers: ITransformer[]; + private stackMappingOverrides: StackMapping; + private transformConfig: TransformConfig; + private featureFlags: FeatureFlagProvider; // A map from `${directive}.${typename}.${fieldName?}`: true diff --git a/packages/graphql-transformer-core/src/errors.ts b/packages/graphql-transformer-core/src/errors.ts index b938b6172e..ee1a96b139 100644 --- a/packages/graphql-transformer-core/src/errors.ts +++ b/packages/graphql-transformer-core/src/errors.ts @@ -88,6 +88,7 @@ export class DestructiveMigrationError extends Error { } this.message = `${this.message}${os.EOL}ALL EXISTING DATA IN THESE TABLES WILL BE LOST!${os.EOL}If this is intended, rerun the command with '--allow-destructive-graphql-schema-updates'.`; } + toString = () => this.message; } @@ -100,12 +101,15 @@ export class InvalidMigrationError extends Error { Object.setPrototypeOf(this, new.target.prototype); this.name = 'InvalidMigrationError'; } + toString = () => `${this.message}\nCause: ${this.causedBy}\nHow to fix: ${this.fix}`; } export class InvalidGSIMigrationError extends InvalidMigrationError { fix: string; + causedBy: string; + constructor(message: string, causedBy: string, fix: string) { super(message, causedBy, fix); this.name = 'InvalidGSIMigrationError'; @@ -136,6 +140,7 @@ export class UnknownDirectiveError extends Error { export class ApiCategorySchemaNotFoundError extends Error { link: string; + constructor(schemaFilePath: string) { super(`Could not find a schema at ${schemaFilePath}`); this.name = 'ApiCategorySchemaNotFoundError'; diff --git a/packages/graphql-transformers-e2e-tests/src/IAMHelper.ts b/packages/graphql-transformers-e2e-tests/src/IAMHelper.ts index 847df5747a..948eafebb2 100644 --- a/packages/graphql-transformers-e2e-tests/src/IAMHelper.ts +++ b/packages/graphql-transformers-e2e-tests/src/IAMHelper.ts @@ -5,6 +5,7 @@ const REGION = resolveTestRegion(); export class IAMHelper { client: IAM; + constructor(region: string = REGION, credentials?: Credentials) { this.client = new IAM({ region, @@ -53,6 +54,7 @@ export class IAMHelper { return { authRole: authRole.Role, unauthRole: unauthRole.Role }; } + async createRoleForCognitoGroup(name: string): Promise { const role = await this.client .createRole({ diff --git a/packages/graphql-transformers-e2e-tests/src/LambdaHelper.ts b/packages/graphql-transformers-e2e-tests/src/LambdaHelper.ts index b1082c31b5..598132f57c 100644 --- a/packages/graphql-transformers-e2e-tests/src/LambdaHelper.ts +++ b/packages/graphql-transformers-e2e-tests/src/LambdaHelper.ts @@ -7,6 +7,7 @@ const REGION = resolveTestRegion(); export class LambdaHelper { client: Lambda; + constructor(region: string = REGION, credentials?: Credentials) { this.client = new Lambda({ region, diff --git a/packages/graphql-transformers-e2e-tests/src/TestStorage.ts b/packages/graphql-transformers-e2e-tests/src/TestStorage.ts index 4069410c44..f28f1b2b44 100644 --- a/packages/graphql-transformers-e2e-tests/src/TestStorage.ts +++ b/packages/graphql-transformers-e2e-tests/src/TestStorage.ts @@ -1,25 +1,31 @@ export default class TestStorage { private data: any; + constructor() { this.data = {}; } + // set item with the key public setItem(key: string, value: string): string { this.data[key] = value; return value; } + // get item with the key public getItem(key: string): string { return this.data[key]; } + // remove item with the key public removeItem(key: string): void { this.data[key] = undefined; } + // clear out the storage public clear(): void { this.data = {}; } + // If the storage operations are async(i.e AsyncStorage) // Then you need to sync those items into the memory in this method public sync(): Promise { diff --git a/scripts/cci/api.ts b/scripts/cci/api.ts index e3734b2764..86ba463499 100644 --- a/scripts/cci/api.ts +++ b/scripts/cci/api.ts @@ -10,8 +10,11 @@ export type CircleCIClientDefaults = { }; export class CircleCIAPIClient { private headers; + private options: CircleCIClientDefaults; + private slug: string; + constructor(token: string, options: CircleCIClientDefaults) { this.headers = { 'Circle-Token': token, @@ -32,6 +35,7 @@ export class CircleCIAPIClient { }); return result.data; }; + /** * Returns a job's details. * @@ -45,6 +49,7 @@ export class CircleCIAPIClient { }); return result.data; }; + /** * Returns a single job's artifacts. * @@ -58,6 +63,7 @@ export class CircleCIAPIClient { }); return result.data; }; + /** * Get test metadata for a single job * @@ -71,6 +77,7 @@ export class CircleCIAPIClient { }); return result.data; }; + /** * Get summary metrics for a project workflow's jobs. *