@aws-amplify/amplify-util-uibuilder 1.10.0 → 1.10.1-rds-1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/package.json +7 -7
  3. package/src/__tests__/.eslintrc.js +0 -9
  4. package/src/__tests__/__snapshots__/syncAmplifyUiComponents.test.ts.snap +0 -46
  5. package/src/__tests__/cloneComponentsFromEnv.test.ts +0 -79
  6. package/src/__tests__/detachedFormCleanup.test.ts +0 -77
  7. package/src/__tests__/generateComponents.test.ts +0 -342
  8. package/src/__tests__/getAmplifyDataSchema.test.ts +0 -82
  9. package/src/__tests__/handleEvents.test.ts +0 -27
  10. package/src/__tests__/help.test.ts +0 -10
  11. package/src/__tests__/mock.json +0 -1
  12. package/src/__tests__/notifyMissingPackages.test.ts +0 -86
  13. package/src/__tests__/package.json +0 -3
  14. package/src/__tests__/prePushHandler.test.ts +0 -116
  15. package/src/__tests__/shouldRenderComponents.test.ts +0 -112
  16. package/src/__tests__/storageManager.test.ts +0 -45
  17. package/src/__tests__/syncAmplifyUiComponents.test.ts +0 -309
  18. package/src/__tests__/utils/getApiConfiguration.test.ts +0 -41
  19. package/src/__tests__/utils.ts +0 -72
  20. package/src/__tests__/version.test.ts +0 -10
  21. package/src/clients/amplify-studio-client.ts +0 -320
  22. package/src/clients/index.ts +0 -1
  23. package/src/commands/cloneComponentsFromEnv.ts +0 -53
  24. package/src/commands/generateComponents.ts +0 -125
  25. package/src/commands/help.ts +0 -8
  26. package/src/commands/utils/codegenResources.ts +0 -23
  27. package/src/commands/utils/detachedFormCleanup.ts +0 -54
  28. package/src/commands/utils/environmentHelpers.ts +0 -32
  29. package/src/commands/utils/extractArgs.ts +0 -25
  30. package/src/commands/utils/featureFlags.ts +0 -61
  31. package/src/commands/utils/getApiConfiguration.ts +0 -73
  32. package/src/commands/utils/getUiBuilderComponentsPath.ts +0 -21
  33. package/src/commands/utils/index.ts +0 -9
  34. package/src/commands/utils/notifyMissingPackages.ts +0 -47
  35. package/src/commands/utils/shouldRenderComponents.ts +0 -48
  36. package/src/commands/utils/storageManager.ts +0 -13
  37. package/src/commands/utils/syncAmplifyUiBuilderComponents.ts +0 -232
  38. package/src/commands/version.ts +0 -9
  39. package/src/event-handlers/handle-PostEnvAdd.ts +0 -16
  40. package/src/event-handlers/handle-PostPull.ts +0 -15
  41. package/src/event-handlers/handle-PostPush.ts +0 -15
  42. package/src/event-handlers/handle-PrePush.ts +0 -15
  43. package/src/index.ts +0 -26
  44. package/src/utils/prePushHandler.ts +0 -51
  45. package/tsconfig.json +0 -9
  46. package/tsconfig.tsbuildinfo +0 -1
@@ -1,61 +0,0 @@
1
- /* eslint-disable spellcheck/spell-checker */
2
- import { FeatureFlags, pathManager, stateManager } from '@aws-amplify/amplify-cli-core';
3
- import { printer } from '@aws-amplify/amplify-prompts';
4
-
5
- // This is copy-pasta from the category api until they can expose the method to plugins
6
-
7
- /**
8
- * Shorthand for Feature flag retrieval.
9
- */
10
- const useExperimentalPipelinedTransformerFF = (): boolean =>
11
- FeatureFlags.getBoolean('graphQLTransformer.useExperimentalPipelinedTransformer');
12
- const transformerVersionFF = (): number => FeatureFlags.getNumber('graphQLTransformer.transformerVersion');
13
-
14
- /**
15
- * Inspect feature flags for the project and determine if this particular project should be using graphql v2 or v1.
16
- * Coerces feature flags into a sane state if they are out of, and throws error on invalid configuration.
17
- */
18
- export const getTransformerVersion = async (): Promise<number> => {
19
- if (useExperimentalPipelinedTransformerFF() === false) {
20
- return 1;
21
- }
22
-
23
- if (isLegacyFeatureFlagConfiguration()) {
24
- await migrateToTransformerVersionFeatureFlag();
25
- }
26
-
27
- const transformerVersion = transformerVersionFF();
28
- if (transformerVersion !== 1 && transformerVersion !== 2) {
29
- throw new Error(`Invalid value specified for transformerVersion: '${transformerVersion}'`);
30
- }
31
-
32
- return transformerVersion;
33
- };
34
-
35
- /**
36
- * Return whether or not the project is configured with legacy pipelined transformer feature flags, and may need to be updated.
37
- */
38
- const isLegacyFeatureFlagConfiguration = (): boolean => useExperimentalPipelinedTransformerFF() && transformerVersionFF() === 1;
39
-
40
- /**
41
- * Update project feature flags and alert the user if they have a deprecated set of feature flags.
42
- */
43
- const migrateToTransformerVersionFeatureFlag = async (): Promise<void> => {
44
- const projectPath = pathManager.findProjectRoot() ?? process.cwd();
45
-
46
- const config = stateManager.getCLIJSON(projectPath, undefined, {
47
- throwIfNotExist: false,
48
- preserveComments: true,
49
- });
50
-
51
- // eslint-disable-next-line spellcheck/spell-checker
52
- config.features.graphqltransformer.transformerversion = 2;
53
- stateManager.setCLIJSON(projectPath, config);
54
- await FeatureFlags.reloadValues();
55
- // eslint-disable-next-line spellcheck/spell-checker
56
- printer.warn(
57
- `\nThe project is configured with 'transformerVersion': ${transformerVersionFF()}, but 'useExperimentalPipelinedTransformer': ${useExperimentalPipelinedTransformerFF()}. Setting the 'transformerVersion': ${
58
- config.features.graphqltransformer.transformerversion
59
- }. 'useExperimentalPipelinedTransformer' is deprecated.`,
60
- );
61
- };
@@ -1,73 +0,0 @@
1
- import { printer } from '@aws-amplify/amplify-prompts';
2
- import { AmplifyStudioClient } from '../../clients';
3
- import { $TSContext } from '@aws-amplify/amplify-cli-core';
4
- import { getUiBuilderComponentsPath } from './getUiBuilderComponentsPath';
5
- import { getCodegenConfig } from 'amplify-codegen';
6
- import { ApiConfiguration } from 'aws-sdk/clients/amplifyuibuilder';
7
- import path from 'path';
8
-
9
- //a posix formatted relative path must always be returned as the return values are used directly in jsx files as import paths
10
- export function relativeToComponentsPath(importPath: string, context: $TSContext): string {
11
- const componentsPath = getUiBuilderComponentsPath(context);
12
- const segments = path.relative(componentsPath, importPath).split(path.sep);
13
- return path.posix.join(...segments);
14
- }
15
-
16
- export function getApiConfiguration(studioClient: AmplifyStudioClient, context: $TSContext): ApiConfiguration {
17
- if (studioClient.isDataStoreEnabled) {
18
- return {
19
- dataStoreConfig: {},
20
- };
21
- }
22
-
23
- if (studioClient.metadata.isGraphQLEnabled) {
24
- printer.debug('building graphql config');
25
- // attempt to get api codegen info
26
- const projectPath = context.exeInfo.localEnvInfo.projectPath;
27
- let promptForUpdateCodegen = false;
28
-
29
- try {
30
- const codegenConfig = getCodegenConfig(projectPath);
31
- const typesPath = codegenConfig.getGeneratedTypesPath();
32
- const apiConfiguration = {
33
- graphQLConfig: {
34
- typesFilePath: (typesPath && relativeToComponentsPath(typesPath, context)) || '',
35
- queriesFilePath: relativeToComponentsPath(codegenConfig.getGeneratedQueriesPath(), context),
36
- mutationsFilePath: relativeToComponentsPath(codegenConfig.getGeneratedMutationsPath(), context),
37
- subscriptionsFilePath: relativeToComponentsPath(codegenConfig.getGeneratedSubscriptionsPath(), context),
38
- fragmentsFilePath: relativeToComponentsPath(codegenConfig.getGeneratedFragmentsPath(), context),
39
- },
40
- };
41
-
42
- const minQueryDepth = 3;
43
- const isQueryingTooShallow = (codegenConfig.getQueryMaxDepth() || 0) < minQueryDepth;
44
-
45
- if (studioClient.metadata.formFeatureFlags.isRelationshipSupported && isQueryingTooShallow) {
46
- promptForUpdateCodegen = true;
47
- printer.warn(`Forms with relationships require a maximum query depth of at least ${minQueryDepth}.`);
48
- }
49
- return apiConfiguration;
50
- } catch {
51
- promptForUpdateCodegen = true;
52
- printer.warn(
53
- 'Unable to successfully configure component generation for GraphQL. This will impact generating forms and components bound to your data models.',
54
- );
55
- } finally {
56
- if (promptForUpdateCodegen) {
57
- printer.warn(`Run 'amplify update codegen' to ensure GraphQL configurations for your project are correct.`);
58
- }
59
- }
60
- }
61
-
62
- return {
63
- noApiConfig: {},
64
- };
65
- }
66
-
67
- export function hasDataStoreConfiguration(apiConfiguration: ApiConfiguration): boolean {
68
- return apiConfiguration.dataStoreConfig !== undefined;
69
- }
70
-
71
- export function hasGraphQLConfiguration(apiConfiguration: ApiConfiguration): boolean {
72
- return apiConfiguration.graphQLConfig !== undefined;
73
- }
@@ -1,21 +0,0 @@
1
- import path from 'path';
2
- import fs from 'fs-extra';
3
- import { $TSContext } from '@aws-amplify/amplify-cli-core';
4
- import { extractArgs } from './extractArgs';
5
-
6
- /**
7
- *
8
- * locates components path directory
9
- */
10
- export const getUiBuilderComponentsPath = (context: $TSContext): string => {
11
- const args = extractArgs(context);
12
- const srcDir = args.srcDir ? args.srcDir : context.exeInfo.projectConfig.javascript.config.SourceDir;
13
- const uiBuilderComponentsPath = path.resolve(path.join('.', srcDir, 'ui-components'));
14
-
15
- if (!fs.existsSync(uiBuilderComponentsPath)) {
16
- // eslint-disable-next-line spellcheck/spell-checker
17
- fs.mkdirpSync(uiBuilderComponentsPath);
18
- }
19
-
20
- return uiBuilderComponentsPath;
21
- };
@@ -1,9 +0,0 @@
1
- export * from './codegenResources';
2
- export * from './environmentHelpers';
3
- export * from './extractArgs';
4
- export * from './getUiBuilderComponentsPath';
5
- export * from './notifyMissingPackages';
6
- export * from './shouldRenderComponents';
7
- export * from './syncAmplifyUiBuilderComponents';
8
- export * from './detachedFormCleanup';
9
- export * from './storageManager';
@@ -1,47 +0,0 @@
1
- import { pathManager, JSONUtilities, $TSContext, $TSAny } from '@aws-amplify/amplify-cli-core';
2
- import { printer } from '@aws-amplify/amplify-prompts';
3
- import fs from 'fs-extra';
4
- import path from 'path';
5
- import rangeSubset from 'semver/ranges/subset';
6
- import { RequiredDependency } from '@aws-amplify/codegen-ui';
7
- import { ReactRequiredDependencyProvider } from '@aws-amplify/codegen-ui-react';
8
- import { extractArgs } from './extractArgs';
9
-
10
- const getRequiredDependencies = (hasStorageManagerField?: boolean): RequiredDependency[] =>
11
- new ReactRequiredDependencyProvider().getRequiredDependencies(hasStorageManagerField);
12
-
13
- /**
14
- * Displays a warning to the user if they have npm dependencies
15
- * they need to install in their application for UIBuilder components to work properly
16
- */
17
- export const notifyMissingPackages = (context: $TSContext, hasStorageManagerField?: boolean): void => {
18
- const args = extractArgs(context);
19
- const localEnvFilePath = args.localEnvFilePath ?? pathManager.getLocalEnvFilePath();
20
- if (!fs.existsSync(localEnvFilePath)) {
21
- printer.debug('localEnvFilePath could not be determined - skipping dependency notification.');
22
- return;
23
- }
24
- const localEnvJson = JSONUtilities.readJson(localEnvFilePath);
25
- const packageJsonPath = path.join((localEnvJson as $TSAny).projectPath, 'package.json');
26
- if (!fs.existsSync(packageJsonPath)) {
27
- printer.debug('package.json file not found - skipping dependency notification.');
28
- return;
29
- }
30
- const packageJson = JSONUtilities.readJson(packageJsonPath) as { dependencies: { [key: string]: string } };
31
- getRequiredDependencies(hasStorageManagerField).forEach((dependency: $TSAny) => {
32
- const packageIsInstalled = Object.keys(packageJson.dependencies).includes(dependency.dependencyName);
33
- if (!packageIsInstalled) {
34
- printer.warn(
35
- `UIBuilder components require "${dependency.dependencyName}" that is not in your package.json. Run \`npm install "${dependency.dependencyName}@${dependency.supportedSemVerPattern}"\`. ${dependency.reason}`,
36
- );
37
- } else if (!rangeSubset(packageJson.dependencies[dependency.dependencyName], dependency.supportedSemVerPattern)) {
38
- printer.warn(
39
- `UIBuilder components require version "${dependency.supportedSemVerPattern}" of "${
40
- dependency.dependencyName
41
- }". You currently are on version "${packageJson.dependencies[dependency.dependencyName]}". Run \`npm install "${
42
- dependency.dependencyName
43
- }@${dependency.supportedSemVerPattern}"\`. ${dependency.reason}`,
44
- );
45
- }
46
- });
47
- };
@@ -1,48 +0,0 @@
1
- /* eslint-disable prefer-arrow/prefer-arrow-functions */
2
- import { $TSContext, stateManager } from '@aws-amplify/amplify-cli-core';
3
- import { printer } from '@aws-amplify/amplify-prompts';
4
- import { AmplifyStudioClient } from '../../clients';
5
- import { getAppId } from './environmentHelpers';
6
-
7
- /**
8
- * process to decide if we should render components
9
- */
10
- export const shouldRenderComponents = async (context: $TSContext): Promise<boolean> => {
11
- const projectConfig = stateManager.getProjectConfig();
12
-
13
- if (process.env.FORCE_RENDER) {
14
- printer.debug('Forcing component render since environment variable flag is set.');
15
- return true;
16
- }
17
- if (context?.input?.options?.['no-codegen']) {
18
- printer.debug('Not pulling components because --no-codegen flag is set.');
19
- return false;
20
- }
21
-
22
- if (!projectConfig) {
23
- printer.debug('Not pulling components because there is no projectConfig set for this project.');
24
- return false;
25
- }
26
-
27
- if (!projectConfig.providers.includes('awscloudformation')) {
28
- printer.debug('Not pulling components because there is no "awscloudformation" provider.');
29
- return false;
30
- }
31
-
32
- if (projectConfig.frontend !== 'javascript') {
33
- printer.debug('Not pulling components because this project is not configured as a javascript frontend.');
34
- return false;
35
- }
36
-
37
- if (projectConfig.javascript.framework !== 'react') {
38
- printer.debug('Not pulling components because this project is not configured with the "react" framework.');
39
- return false;
40
- }
41
-
42
- if (!(await AmplifyStudioClient.isAmplifyApp(context, getAppId(context)))) {
43
- printer.debug('Not pulling components because this project is not Amplify Studio enabled.');
44
- return false;
45
- }
46
-
47
- return true;
48
- };
@@ -1,13 +0,0 @@
1
- import { FieldConfig, Form } from 'aws-sdk/clients/amplifyuibuilder';
2
-
3
- export const hasStorageField = (form: Form): boolean => {
4
- const result = Object.values(form.fields).some((field) => {
5
- return isGenericFieldConfig(field) && field.inputType?.type === 'StorageField';
6
- });
7
-
8
- return result;
9
- };
10
-
11
- export const isGenericFieldConfig = (config: FieldConfig) => {
12
- return !Object.keys(config).includes('excluded');
13
- };
@@ -1,232 +0,0 @@
1
- import { printer } from '@aws-amplify/amplify-prompts';
2
- import type { GenericDataSchema, GenericDataField, GenericDataRelationshipType } from '@aws-amplify/codegen-ui';
3
- import {
4
- CodegenGenericDataEnum,
5
- CodegenGenericDataFieldDataType,
6
- CodegenGenericDataFields,
7
- CodegenGenericDataModel,
8
- CodegenGenericDataNonModel,
9
- CodegenGenericDataRelationshipType,
10
- CodegenJob,
11
- CodegenJobGenericDataSchema,
12
- } from 'aws-sdk/clients/amplifyuibuilder';
13
- import fetch from 'node-fetch';
14
- import { performance } from 'perf_hooks';
15
- import path from 'path';
16
- import fs from 'fs';
17
- import asyncPool from 'tiny-async-pool';
18
-
19
- const mapRelationshipTypeToCodegen = (
20
- relationship: GenericDataRelationshipType | undefined,
21
- ): CodegenGenericDataRelationshipType | undefined => {
22
- if (!relationship) return undefined;
23
-
24
- switch (relationship.type) {
25
- case 'HAS_MANY':
26
- return {
27
- type: 'HAS_MANY',
28
- relatedModelFields: relationship.relatedModelFields,
29
- canUnlinkAssociatedModel: !!relationship.canUnlinkAssociatedModel,
30
- relatedJoinFieldName: relationship.relatedJoinFieldName,
31
- relatedJoinTableName: relationship.relatedJoinTableName,
32
- belongsToFieldOnRelatedModel: relationship.belongsToFieldOnRelatedModel,
33
- relatedModelName: relationship.relatedModelName,
34
- };
35
- case 'HAS_ONE':
36
- return {
37
- type: 'HAS_ONE',
38
- associatedFields: relationship.associatedFields,
39
- isHasManyIndex: !!relationship.isHasManyIndex,
40
- relatedModelName: relationship.relatedModelName,
41
- };
42
- case 'BELONGS_TO':
43
- return {
44
- type: 'BELONGS_TO',
45
- associatedFields: relationship.associatedFields,
46
- isHasManyIndex: !!relationship.isHasManyIndex,
47
- relatedModelName: relationship.relatedModelName,
48
- };
49
- default:
50
- throw new Error('Invalid relationship type');
51
- }
52
- };
53
-
54
- const mapDataFieldsToCodegen = (fields: { [fieldName: string]: GenericDataField }): CodegenGenericDataFields => {
55
- const codegenFields: CodegenGenericDataFields = {};
56
-
57
- Object.entries(fields).forEach(([fieldName, dataField]) => {
58
- let dataType: CodegenGenericDataFieldDataType = '';
59
- let dataTypeValue = '';
60
- if (typeof dataField.dataType === 'object' && dataField.dataType !== null) {
61
- if ('enum' in dataField.dataType) {
62
- dataType = 'Enum';
63
- dataTypeValue = dataField.dataType.enum;
64
- } else if ('model' in dataField.dataType) {
65
- dataType = 'Model';
66
- dataTypeValue = dataField.dataType.model;
67
- } else if ('nonModel' in dataField.dataType) {
68
- dataType = 'NonModel';
69
- dataTypeValue = dataField.dataType.nonModel;
70
- }
71
- } else {
72
- dataType = dataField.dataType;
73
- dataTypeValue = dataField.dataType;
74
- }
75
- codegenFields[fieldName] = {
76
- dataType: dataType,
77
- dataTypeValue: dataTypeValue,
78
- required: dataField.required,
79
- readOnly: dataField.readOnly,
80
- isArray: dataField.isArray,
81
- };
82
- if (dataField.relationship) {
83
- codegenFields[fieldName].relationship = mapRelationshipTypeToCodegen(dataField.relationship);
84
- }
85
- });
86
-
87
- return codegenFields;
88
- };
89
-
90
- export const mapGenericDataSchemaToCodegen = (genericDataSchema: GenericDataSchema): CodegenJobGenericDataSchema => {
91
- const { models, nonModels, enums, dataSourceType } = genericDataSchema;
92
- const codegenModels: { [key: string]: CodegenGenericDataModel } = {};
93
- const codegenNonModels: { [key: string]: CodegenGenericDataNonModel } = {};
94
- const codegenEnums: { [key: string]: CodegenGenericDataEnum } = {};
95
-
96
- Object.entries(models).forEach(([modelName, genericDataModel]) => {
97
- const modelFields = mapDataFieldsToCodegen(genericDataModel.fields);
98
-
99
- codegenModels[modelName] = {
100
- isJoinTable: genericDataModel.isJoinTable,
101
- primaryKeys: genericDataModel.primaryKeys,
102
- fields: modelFields,
103
- };
104
- });
105
-
106
- Object.entries(nonModels).forEach(([nonModelName, genericDataModel]) => {
107
- const nonModelFields = mapDataFieldsToCodegen(genericDataModel.fields);
108
-
109
- codegenNonModels[nonModelName] = {
110
- fields: nonModelFields,
111
- };
112
- });
113
-
114
- Object.entries(enums).forEach(([enumName, genericEnum]) => {
115
- codegenEnums[enumName] = {
116
- values: genericEnum.values,
117
- };
118
- });
119
-
120
- return {
121
- models: codegenModels,
122
- nonModels: codegenNonModels,
123
- enums: codegenEnums,
124
- dataSourceType,
125
- };
126
- };
127
-
128
- function delay(durationMs: number): Promise<void> {
129
- return new Promise((r) => setTimeout(() => r(), durationMs));
130
- }
131
-
132
- export const waitForSucceededJob = async (getJob: () => Promise<CodegenJob>, { pollInterval }: { pollInterval: number }) => {
133
- const startTime = performance.now();
134
- // Adding env variable because if something happens and we need a longer timeout
135
- // we will give the customer a chance to increase timeout as a workaround.
136
- // Default timeout is 2 minutes for customers with thousands of components.
137
- const waitTimeout = process.env.UI_BUILDER_CODEGENJOB_TIMEOUT ? parseInt(process.env.UI_BUILDER_CODEGENJOB_TIMEOUT) : 1000 * 60 * 2;
138
-
139
- const endTime = startTime + waitTimeout;
140
-
141
- while (performance.now() < endTime) {
142
- const job = await getJob();
143
-
144
- if (!job) {
145
- printer.error('Codegen job not found');
146
- throw new Error('Codegen job not found');
147
- }
148
-
149
- if (job.status === 'failed') {
150
- printer.error('Codegen job status is failed', { message: job.statusMessage });
151
- throw new Error(job.statusMessage);
152
- }
153
-
154
- if (job.status === 'succeeded') {
155
- printer.debug(`Polling time: ${performance.now() - startTime}`);
156
-
157
- return job;
158
- }
159
-
160
- await delay(pollInterval);
161
- }
162
-
163
- if (performance.now() > endTime) {
164
- printer.error(`Codegen job never succeeded before timeout`);
165
- }
166
-
167
- throw new Error('Failed to return codegen job');
168
- };
169
-
170
- export const fetchWithRetries = async (url: string, retries = 3, delay = 300) => {
171
- let retryCount = 0;
172
- let retryDelay = delay;
173
-
174
- while (retryCount < retries) {
175
- try {
176
- const response = await fetch(url);
177
- return response;
178
- } catch (error) {
179
- printer.debug(`Error fetching ${url}: ${error}`);
180
- retryCount = retryCount + 1;
181
- await new Promise((res) => setTimeout(res, delay));
182
- retryDelay = retryDelay * 2;
183
- }
184
- }
185
- throw new Error('Fetch reached max number of retries without succeeding');
186
- };
187
-
188
- export const extractUIComponents = async (url: string, uiBuilderComponentsPath: string) => {
189
- try {
190
- if (!fs.existsSync(uiBuilderComponentsPath)) {
191
- fs.mkdirSync(uiBuilderComponentsPath, { recursive: true });
192
- }
193
-
194
- const response = await fetchWithRetries(url);
195
- if (!response.ok) {
196
- throw new Error('Failed to download component manifest file');
197
- }
198
- const manifestFile = await (<
199
- Promise<{ Output: { downloadUrl: string | undefined; fileName: string; schemaName: string; error: string | undefined }[] }>
200
- >response.json());
201
-
202
- const downloadComponent = async (output: { fileName: string; downloadUrl: string | undefined; error: string | undefined }) => {
203
- if (output.downloadUrl && !output.error) {
204
- try {
205
- const response = await fetchWithRetries(output.downloadUrl);
206
- if (!response.ok) {
207
- printer.debug(`Failed to download ${output.fileName}`);
208
- throw new Error(`Failed to download ${output.fileName}`);
209
- }
210
- return { content: await response.text(), error: undefined, fileName: output.fileName };
211
- } catch (error) {
212
- printer.debug(`Skipping ${output.fileName} because of an error downloading the component`);
213
- return { error: `Failed to download ${output.fileName}`, content: undefined, fileName: output.fileName };
214
- }
215
- } else {
216
- printer.debug(`Skipping ${output.fileName} because of an error generating the component`);
217
- return { error: output.error, content: undefined, fileName: output.fileName };
218
- }
219
- };
220
-
221
- for await (const downloaded of asyncPool(5, manifestFile.Output, downloadComponent)) {
222
- if (downloaded.content) {
223
- fs.writeFileSync(path.join(uiBuilderComponentsPath, downloaded.fileName), downloaded.content);
224
- printer.debug(`Downloaded ${downloaded.fileName}`);
225
- }
226
- }
227
- printer.debug('ui-components downloaded successfully');
228
- } catch (error) {
229
- printer.error('failed to download ui-components');
230
- throw error;
231
- }
232
- };
@@ -1,9 +0,0 @@
1
- import { printer } from '@aws-amplify/amplify-prompts';
2
- import path from 'path';
3
-
4
- /**
5
- * runs version command
6
- */
7
- export const run = async (): Promise<void> => {
8
- printer.info((await import(path.join(__dirname, '..', '..', 'package.json'))).version);
9
- };
@@ -1,16 +0,0 @@
1
- import { $TSContext } from '@aws-amplify/amplify-cli-core';
2
- import { printer } from '@aws-amplify/amplify-prompts';
3
- import { run as cloneComponentsFromEnv } from '../commands/cloneComponentsFromEnv';
4
-
5
- /**
6
- *
7
- * runs after adding an environment
8
- */
9
- export const run = async (context: $TSContext): Promise<void> => {
10
- try {
11
- await cloneComponentsFromEnv(context);
12
- } catch (e) {
13
- // Swallow all errors from the uibuilder plugin
14
- printer.debug(e);
15
- }
16
- };
@@ -1,15 +0,0 @@
1
- import { $TSContext } from '@aws-amplify/amplify-cli-core';
2
- import { printer } from '@aws-amplify/amplify-prompts';
3
- import { run as generateComponents } from '../commands/generateComponents';
4
-
5
- /**
6
- * The code to run after a pull.
7
- */
8
- export const run = async (context: $TSContext): Promise<void> => {
9
- try {
10
- await generateComponents(context, 'PostPull');
11
- } catch (e) {
12
- // Swallow all errors from the uibuilder plugin
13
- printer.debug(e);
14
- }
15
- };
@@ -1,15 +0,0 @@
1
- import { $TSContext } from '@aws-amplify/amplify-cli-core';
2
- import { printer } from '@aws-amplify/amplify-prompts';
3
- import { run as generateComponents } from '../commands/generateComponents';
4
-
5
- /**
6
- * The code to run after a push
7
- */
8
- export const run = async (context: $TSContext): Promise<void> => {
9
- try {
10
- await generateComponents(context, 'PostPush');
11
- } catch (e) {
12
- // Swallow all errors from the uibuilder plugin
13
- printer.debug(e);
14
- }
15
- };
@@ -1,15 +0,0 @@
1
- import { $TSContext } from '@aws-amplify/amplify-cli-core';
2
- import { printer } from '@aws-amplify/amplify-prompts';
3
- import { prePushHandler } from '../utils/prePushHandler';
4
-
5
- /**
6
- * The code to run before a push.
7
- */
8
- export const run = async (context: $TSContext): Promise<void> => {
9
- try {
10
- await prePushHandler(context);
11
- } catch (e) {
12
- // Swallow all errors from the uibuilder plugin
13
- printer.debug(e);
14
- }
15
- };
package/src/index.ts DELETED
@@ -1,26 +0,0 @@
1
- import { $TSContext } from '@aws-amplify/amplify-cli-core';
2
- import path from 'path';
3
-
4
- // TODO: remove dynamic require
5
-
6
- /**
7
- * executes main amplify command into uibuilder
8
- */
9
- export const executeAmplifyCommand = async (context: $TSContext, cmd: string): Promise<void> => {
10
- const commandsDirPath = path.normalize(path.join(__dirname, 'commands'));
11
- const commandPath = path.join(commandsDirPath, cmd || context.input.command);
12
- // eslint-disable-next-line import/no-dynamic-require, global-require, @typescript-eslint/no-var-requires
13
- const commandModule = require(commandPath);
14
- await commandModule.run(context);
15
- };
16
-
17
- /**
18
- * runs event based command
19
- */
20
- export const handleAmplifyEvent = async (context: $TSContext, { event }: { event: string }): Promise<void> => {
21
- const eventHandlersDirPath = path.normalize(path.join(__dirname, 'event-handlers'));
22
- const eventHandlerPath = path.join(eventHandlersDirPath, `handle-${event}`);
23
- // eslint-disable-next-line import/no-dynamic-require, global-require, @typescript-eslint/no-var-requires
24
- const eventHandlerModule = require(eventHandlerPath);
25
- await eventHandlerModule.run(context);
26
- };
@@ -1,51 +0,0 @@
1
- import { $TSContext } from '@aws-amplify/amplify-cli-core';
2
- import { printer } from '@aws-amplify/amplify-prompts';
3
- import AmplifyUIBuilder from 'aws-sdk/clients/amplifyuibuilder';
4
- import { AmplifyStudioClient } from '../clients';
5
- import { isFormDetachedFromModel, isFormSchemaCustomized, shouldRenderComponents } from '../commands/utils';
6
- import { ModelIntrospectionSchema } from '@aws-amplify/appsync-modelgen-plugin';
7
-
8
- /**
9
- * Handles showing a warning for detached forms pre-push.
10
- */
11
- export const prePushHandler = async (context: $TSContext): Promise<void> => {
12
- if (!(await shouldRenderComponents(context))) {
13
- return;
14
- }
15
- const studioClient = await AmplifyStudioClient.setClientInfo(context);
16
- const [formSchemas, localSchema] = await Promise.all<
17
- [
18
- Promise<{
19
- entities: AmplifyUIBuilder.Form[];
20
- }>,
21
- Promise<ModelIntrospectionSchema>,
22
- ]
23
- >([studioClient.listForms(), context.amplify.invokePluginMethod(context, 'codegen', undefined, 'getModelIntrospection', [context])]);
24
-
25
- if (!localSchema) {
26
- printer.debug('Local schema not found');
27
- return;
28
- }
29
- printDetachedFormsWarning(formSchemas, localSchema);
30
- };
31
-
32
- const printDetachedFormsWarning = (formSchemas: { entities: AmplifyUIBuilder.Form[] }, localSchema: ModelIntrospectionSchema): void => {
33
- const modelNames = new Set(Object.keys(localSchema.models));
34
- const detachedCustomForms: string[] = [];
35
-
36
- formSchemas.entities.forEach((form) => {
37
- // Only show warnings for schema's that have customization, otherwise it's the same as
38
- // an autogenerated form.
39
- if (isFormDetachedFromModel(form, modelNames) && isFormSchemaCustomized(form)) {
40
- detachedCustomForms.push(form.name);
41
- }
42
- });
43
-
44
- if (detachedCustomForms.length > 0) {
45
- printer.warn(
46
- `The following form${
47
- detachedCustomForms.length === 1 ? '' : 's'
48
- } will no longer be available because the connected data model no longer exists: ${detachedCustomForms.join(', ')}`,
49
- );
50
- }
51
- };
package/tsconfig.json DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "outDir": "./lib",
5
- "rootDir": "./src",
6
- "strict": true,
7
- "skipLibCheck": true
8
- }
9
- }