Skip to content

Commit

Permalink
refactor: move api utility isNameUnique to core as isResourceNameUniq…
Browse files Browse the repository at this point in the history
…ue (#8038)
  • Loading branch information
jhockett authored Sep 9, 2021
1 parent 92821aa commit 8624305
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 63 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import { ApiArtifactHandler } from '../api-artifact-handler';
import { isResourceNameUnique } from 'amplify-cli-core';
import {
AddApiRequest,
ConflictResolution,
AppSyncServiceConfiguration,
ConflictResolution,
ResolutionStrategy,
UpdateApiRequest,
} from 'amplify-headless-interface';
import path from 'path';
import fs from 'fs-extra';
import { category } from '../../category-constants';
import { rootAssetDir, provider, gqlSchemaFilename, cfnParametersFilename } from './aws-constants';
import * as fs from 'fs-extra';
import { readTransformerConfiguration, TRANSFORM_CURRENT_VERSION, writeTransformerConfiguration } from 'graphql-transformer-core';
import { conflictResolutionToResolverConfig } from './utils/resolver-config-to-conflict-resolution-bi-di-mapper';
import { appSyncAuthTypeToAuthConfig } from './utils/auth-config-to-app-sync-auth-type-bi-di-mapper';
import uuid from 'uuid';
import _ from 'lodash';
import { getAppSyncResourceName, getAppSyncAuthConfig, checkIfAuthExists, authConfigHasApiKey } from './utils/amplify-meta-utils';
import * as path from 'path';
import uuid from 'uuid';
import { category } from '../../category-constants';
import { ApiArtifactHandler } from '../api-artifact-handler';
import { cfnParametersFilename, gqlSchemaFilename, provider, rootAssetDir } from './aws-constants';
import { authConfigHasApiKey, checkIfAuthExists, getAppSyncAuthConfig, getAppSyncResourceName } from './utils/amplify-meta-utils';
import { appSyncAuthTypeToAuthConfig } from './utils/auth-config-to-app-sync-auth-type-bi-di-mapper';
import { printApiKeyWarnings } from './utils/print-api-key-warnings';
import { isNameUnique } from './utils/check-case-sensitivity';
import { conflictResolutionToResolverConfig } from './utils/resolver-config-to-conflict-resolution-bi-di-mapper';

// keep in sync with ServiceName in amplify-category-function, but probably it will not change
const FunctionServiceNameLambdaFunction = 'Lambda';
Expand Down Expand Up @@ -50,7 +50,7 @@ class CfnApiArtifactHandler implements ApiArtifactHandler {
}
const serviceConfig = request.serviceConfiguration;

isNameUnique('api', serviceConfig.apiName);
isResourceNameUnique('api', serviceConfig.apiName);

const resourceDir = this.getResourceDir(serviceConfig.apiName);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { JSONUtilities } from 'amplify-cli-core';
import { isResourceNameUnique, JSONUtilities } from 'amplify-cli-core';
import * as fs from 'fs-extra';
import * as path from 'path';
import { cfnParametersFilename, parametersFileName, rootAssetDir } from './aws-constants';
import { serviceMetadataFor } from './utils/dynamic-imports';
import { isNameUnique } from './utils/check-case-sensitivity';
import fs from 'fs-extra';
import path from 'path';
import { parametersFileName, cfnParametersFilename, rootAssetDir } from './aws-constants';

// this is the old logic for generating resources in the project directory
// it is still used for adding REST APIs
Expand Down Expand Up @@ -33,7 +32,7 @@ export const legacyAddResource = async (serviceWalkthroughPromise: Promise<any>,
const parameters = { ...answers };
const resourceDirPath = path.join(projectBackendDirPath, category, parameters.resourceName);

isNameUnique(category, parameters.resourceName);
isResourceNameUnique(category, parameters.resourceName);

fs.ensureDirSync(resourceDirPath);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { $TSContext, exitOnNextTick, isResourceNameUnique, open, ResourceDoesNotExistError, stateManager } from 'amplify-cli-core';
import * as fs from 'fs-extra';
import inquirer from 'inquirer';
import path from 'path';
import fs from 'fs-extra';
import os from 'os';
import * as path from 'path';
import uuid from 'uuid';
import { rootAssetDir } from '../aws-constants';
import { checkForPathOverlap, validatePathName, formatCFNPathParamsForExpressJs } from '../utils/rest-api-path-utils';
import { ResourceDoesNotExistError, exitOnNextTick, $TSContext, stateManager, open } from 'amplify-cli-core';
import { isNameUnique } from '../utils/check-case-sensitivity';
import { checkForPathOverlap, formatCFNPathParamsForExpressJs, validatePathName } from '../utils/rest-api-path-utils';

// keep in sync with ServiceName in amplify-category-function, but probably it will not change
const FunctionServiceNameLambdaFunction = 'Lambda';
Expand Down Expand Up @@ -193,9 +192,16 @@ async function askApiNames(context, defaults) {
},
required: true,
})(input);
const uniqueCheck = isNameUnique(category, input, false);
return typeof amplifyValidatorOutput === 'string' ? amplifyValidatorOutput : typeof uniqueCheck === 'string' ? uniqueCheck : true;

let uniqueCheck = false;
try {
uniqueCheck = isResourceNameUnique(category, input);
} catch (e) {
return e.message || e;
}
return typeof amplifyValidatorOutput === 'string' ? amplifyValidatorOutput : uniqueCheck;
};

const answer: { apiName?: string; resourceName: string } = await inquirer.prompt([
{
name: 'resourceName',
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { isResourceNameUnique } from '../../utils';
import { stateManager } from '../../state-manager';

jest.mock('../../state-manager');

const stateManager_mock = stateManager as jest.Mocked<typeof stateManager>;

stateManager_mock.getMeta.mockReturnValue({
api: {
testBlog: {},
},
});

test('conflict exists if names differ by case only', () => {
expect(() => isResourceNameUnique('api', 'testblog')).toThrowErrorMatchingInlineSnapshot(
`"A resource named 'testBlog' already exists. Amplify resource names must be unique and are case-insensitive."`,
);
});

test('conflict does not exist if names differ by characters', () => {
const result = isResourceNameUnique('api', 'newname');
expect(result).toBe(true);
});
1 change: 1 addition & 0 deletions packages/amplify-cli-core/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './fileSize';
export * from './isResourceNameUnique';
export * from './open';
export * from './packageManager';
export * from './recursiveOmit';
17 changes: 17 additions & 0 deletions packages/amplify-cli-core/src/utils/isResourceNameUnique.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { stateManager } from '../state-manager';

export const isResourceNameUnique = (category: string, resourceName: string, throwOnMatch = true) => {
const meta = stateManager.getMeta();
const resourceNames = Object.keys(meta?.[category] || {});
const matchIdx = resourceNames.map(name => name.toLowerCase()).indexOf(resourceName.toLowerCase());
if (matchIdx === -1) {
return true;
}

if (throwOnMatch) {
const msg = `A resource named '${resourceNames[matchIdx]}' already exists. Amplify resource names must be unique and are case-insensitive.`;
throw new Error(msg);
} else {
return false;
}
};

0 comments on commit 8624305

Please sign in to comment.