Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@aws-amplify/data-schema

Package Overview
Dependencies
Maintainers
10
Versions
176
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@aws-amplify/data-schema - npm Package Compare versions

Comparing version 0.13.17 to 0.13.18

5

lib-esm/src/CustomOperation.d.ts

@@ -14,2 +14,4 @@ import { SetTypeSubArg } from '@aws-amplify/data-schema-types';

type CustomArguments = Record<string, ModelField<any, any> | EnumType<EnumTypeParamShape>>;
type SubscriptionSource = RefType<any, any>;
type InternalSubscriptionSource = InternalRef;
type CustomReturnType = RefType<any> | CustomType<any>;

@@ -29,2 +31,3 @@ type CustomFunctionRefType = string;

handlers: Handler[] | null;
subscriptionSource: SubscriptionSource[];
};

@@ -35,2 +38,3 @@ type InternalCustomData = CustomData & {

functionRef: string | null;
subscriptionSource: InternalSubscriptionSource[];
authorization: Authorization<any, any, any>[];

@@ -60,2 +64,3 @@ };

handler<H extends HandlerInputType>(handlers: H): CustomOperation<T, K | 'handler', B>;
for(source: SubscriptionSource | SubscriptionSource[]): CustomOperation<T, K | 'for', B>;
}, K> & Brand<B>;

@@ -62,0 +67,0 @@ /**

@@ -24,2 +24,3 @@ "use strict";

handlers: null,
subscriptionSource: [],
};

@@ -49,2 +50,6 @@ const builder = brandedBuilder({

},
for(source) {
data.subscriptionSource = Array.isArray(source) ? source : [source];
return this;
},
}, brand);

@@ -51,0 +56,0 @@ return { ...builder, data };

2

lib-esm/src/Handler.d.ts

@@ -26,3 +26,3 @@ import type { DefineFunction } from '@aws-amplify/data-schema-types';

*/
dataSource?: string | RefType<any, any, any>;
dataSource?: string | RefType<any>;
/**

@@ -29,0 +29,0 @@ * The path to the file that contains the function entry point.

@@ -12,2 +12,3 @@ import { SetTypeSubArg } from '@aws-amplify/data-schema-types';

arrayRequired: boolean;
mutationOperations: MutationOperations[];
authorization: Authorization<any, any, any>[];

@@ -23,2 +24,3 @@ };

};
type MutationOperations = 'create' | 'update' | 'delete';
export type RefType<T extends RefTypeParamShape, K extends keyof RefType<T> = never, Auth = undefined> = Omit<{

@@ -38,2 +40,3 @@ /**

authorization<AuthRuleType extends Authorization<any, any, any>>(rules: AuthRuleType[]): RefType<T, K | 'authorization', AuthRuleType>;
mutations(operations: MutationOperations[]): RefType<T, K | 'mutations'>;
}, K> & {

@@ -40,0 +43,0 @@ [__auth]?: Auth;

@@ -16,2 +16,3 @@ "use strict";

arrayRequired: false,
mutationOperations: [],
authorization: [],

@@ -37,2 +38,6 @@ };

},
mutations(operations) {
data.mutationOperations = operations;
return this;
},
});

@@ -39,0 +44,0 @@ return { ...builder, data };

@@ -179,4 +179,4 @@ "use strict";

}
function customOperationToGql(typeName, typeDef, authorization, isCustom = false, databaseType) {
const { arguments: fieldArgs, returnType, functionRef, handlers, } = typeDef.data;
function customOperationToGql(typeName, typeDef, authorization, isCustom = false, databaseType, getRefType) {
const { arguments: fieldArgs, typeName: opType, returnType, functionRef, handlers, subscriptionSource, } = typeDef.data;
let callSignature = typeName;

@@ -222,2 +222,17 @@ const implicitModels = [];

}
if (opType === 'Subscription') {
const subscriptionSources = subscriptionSource
.flatMap((source) => {
const refTarget = source.data.link;
const { type } = getRefType(refTarget, typeName);
if (type === 'CustomOperation') {
return refTarget;
}
if (type === 'Model') {
return source.data.mutationOperations.map((op) => `${op}${refTarget}`);
}
})
.join('", "');
gqlHandlerContent += `@aws_subscribe(mutations: ["${subscriptionSources}"]) `;
}
const gqlField = `${callSignature}: ${returnTypeName} ${gqlHandlerContent}${authString}`;

@@ -737,2 +752,27 @@ return { gqlField, models: implicitModels, lambdaFunctionDefinition };

};
/**
* Returns a closure for retrieving reference type and definition from schema
*/
const getRefTypeForSchema = (schema) => {
const getRefType = (source, target) => {
const typeDef = schema.data.types[source];
if (typeDef === undefined) {
throw new Error(`Invalid ref. ${target} is referencing ${source} which is not defined in the schema`);
}
if (isInternalModel(typeDef)) {
return { type: 'Model', def: typeDef };
}
if (isCustomOperation(typeDef)) {
return { type: 'CustomOperation', def: typeDef };
}
if (isCustomType(typeDef)) {
return { type: 'CustomType', def: typeDef };
}
if (isEnumType(typeDef)) {
return { type: 'Enum', def: typeDef };
}
throw new Error(`Invalid ref. ${target} is referencing ${source} which is neither a Model, Custom Operation, Custom Type, or Enum`);
};
return getRefType;
};
const schemaPreprocessor = (schema) => {

@@ -752,2 +792,3 @@ const gqlModels = [];

const { schemaAuth, functionSchemaAccess } = extractFunctionSchemaAccess(schema.data.authorization);
const getRefType = getRefTypeForSchema(schema);
for (const [typeName, typeDef] of topLevelTypes) {

@@ -780,3 +821,3 @@ validateAuth(typeDef.data?.authorization);

const { typeName: opType } = typeDef.data;
const { gqlField, models, jsFunctionForField, lambdaFunctionDefinition, } = transformCustomOperations(typeDef, typeName, mostRelevantAuthRules, databaseType);
const { gqlField, models, jsFunctionForField, lambdaFunctionDefinition, } = transformCustomOperations(typeDef, typeName, mostRelevantAuthRules, databaseType, getRefType);
lambdaFunctions = lambdaFunctionDefinition;

@@ -857,4 +898,4 @@ topLevelTypes.push(...models);

};
function validateCustomOperations(typeDef, typeName, authRules) {
const { functionRef, handlers } = typeDef.data;
function validateCustomOperations(typeDef, typeName, authRules, getRefType) {
const { functionRef, handlers, typeName: opType, subscriptionSource, returnType, } = typeDef.data;
// TODO: remove `functionRef` after deprecating

@@ -882,2 +923,53 @@ const handlerConfigured = functionRef !== null || handlers?.length;

}
if (opType === 'Subscription') {
if (subscriptionSource.length < 1) {
throw new Error(`${typeName} is missing a mutation source. Custom subscriptions must reference a mutation source via subscription().for(a.ref('ModelOrOperationName')) `);
}
subscriptionSource.forEach((source) => {
const sourceName = source.data.link;
const { type, def } = getRefType(sourceName, typeName);
if (type !== 'Model' && source.data.mutationOperations.length > 0) {
throw new Error(`Invalid subscription definition. .mutations() modifier can only be used with a Model ref. ${typeName} is referencing ${type}`);
}
if (type === 'Model' && source.data.mutationOperations.length === 0) {
throw new Error(`Invalid subscription definition. .mutations() modifier must be used with a Model ref subscription source. ${typeName} is referencing ${sourceName} without specifying a mutation`);
}
if (type === 'CustomOperation' && def.data.typeName !== 'Mutation') {
throw new Error(`Invalid subscription definition. .for() can only reference a mutation. ${typeName} is referencing ${sourceName} which is a ${def.data.typeName}`);
}
// Ensure subscription return type matches the return type of triggering mutation(s)
// TODO: when we remove .returns() for custom subscriptions, minor changes will be needed here. Instead of comparing subscriptionSource return val
// to a root returnType, we'll need to ensure that each subscriptionSource has the same return type
if (returnType.data.type === 'ref') {
const returnTypeName = returnType.data.link;
if (type === 'Model') {
if (returnTypeName !== sourceName ||
returnType.data.array !== source.data.array) {
throw new Error(`Invalid subscription definition. Subscription return type must match the return type of the mutation triggering it. ${typeName} is referencing ${sourceName} which has a different return type`);
}
}
if (type === 'CustomOperation') {
const customOperationReturnType = def.data.returnType.data.link;
const customOperationReturnTypeArray = def.data.returnType.data.array;
if (returnTypeName !== customOperationReturnType ||
returnType.data.array !== customOperationReturnTypeArray) {
throw new Error(`Invalid subscription definition. Subscription return type must match the return type of the mutation triggering it. ${typeName} is referencing ${sourceName} which has a different return type`);
}
}
}
else if (returnType.data.fieldType !== undefined) {
if (type === 'Model') {
throw new Error(`Invalid subscription definition. Subscription return type must match the return type of the mutation triggering it. ${typeName} is referencing ${sourceName} which has a different return type`);
}
if (type === 'CustomOperation') {
const customOperationReturnType = def.data.returnType.data.fieldType;
const customOperationReturnTypeArray = def.data.returnType.data.array;
if (returnType.data.fieldType !== customOperationReturnType ||
returnType.data.array !== customOperationReturnTypeArray) {
throw new Error(`Invalid subscription definition. Subscription return type must match the return type of the mutation triggering it. ${typeName} is referencing ${sourceName} which has a different return type`);
}
}
}
});
}
}

@@ -943,6 +1035,6 @@ const isCustomHandler = (handler) => {

};
function transformCustomOperations(typeDef, typeName, authRules, databaseType) {
function transformCustomOperations(typeDef, typeName, authRules, databaseType, getRefType) {
const { typeName: opType, handlers } = typeDef.data;
let jsFunctionForField = undefined;
validateCustomOperations(typeDef, typeName, authRules);
validateCustomOperations(typeDef, typeName, authRules, getRefType);
if (isCustomHandler(handlers)) {

@@ -952,3 +1044,3 @@ jsFunctionForField = handleCustom(handlers, opType, typeName);

const isCustom = Boolean(jsFunctionForField);
const { gqlField, models, lambdaFunctionDefinition } = customOperationToGql(typeName, typeDef, authRules, isCustom, databaseType);
const { gqlField, models, lambdaFunctionDefinition } = customOperationToGql(typeName, typeDef, authRules, isCustom, databaseType, getRefType);
return { gqlField, models, jsFunctionForField, lambdaFunctionDefinition };

@@ -955,0 +1047,0 @@ }

{
"name": "@aws-amplify/data-schema",
"version": "0.13.17",
"version": "0.13.18",
"license": "Apache-2.0",

@@ -5,0 +5,0 @@ "repository": {

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc