@aws-amplify/amplify-util-uibuilder 1.5.0-studio-forms.0 → 1.6.0-beta.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 (37) hide show
  1. package/CHANGELOG.md +44 -2
  2. package/lib/clients/amplify-studio-client.d.ts +2 -2
  3. package/lib/clients/amplify-studio-client.d.ts.map +1 -1
  4. package/lib/clients/amplify-studio-client.js +30 -30
  5. package/lib/clients/amplify-studio-client.js.map +1 -1
  6. package/lib/commands/generateComponents.d.ts.map +1 -1
  7. package/lib/commands/generateComponents.js +2 -5
  8. package/lib/commands/generateComponents.js.map +1 -1
  9. package/lib/commands/utils/codegenResources.d.ts +2 -1
  10. package/lib/commands/utils/codegenResources.d.ts.map +1 -1
  11. package/lib/commands/utils/codegenResources.js +3 -3
  12. package/lib/commands/utils/codegenResources.js.map +1 -1
  13. package/lib/commands/utils/featureFlags.d.ts +1 -2
  14. package/lib/commands/utils/featureFlags.d.ts.map +1 -1
  15. package/lib/commands/utils/featureFlags.js +5 -4
  16. package/lib/commands/utils/featureFlags.js.map +1 -1
  17. package/lib/commands/utils/shouldRenderComponents.d.ts +1 -1
  18. package/lib/commands/utils/shouldRenderComponents.d.ts.map +1 -1
  19. package/lib/commands/utils/shouldRenderComponents.js +14 -8
  20. package/lib/commands/utils/shouldRenderComponents.js.map +1 -1
  21. package/lib/commands/utils/syncAmplifyUiBuilderComponents.d.ts.map +1 -1
  22. package/lib/commands/utils/syncAmplifyUiBuilderComponents.js +15 -0
  23. package/lib/commands/utils/syncAmplifyUiBuilderComponents.js.map +1 -1
  24. package/package.json +7 -7
  25. package/src/__tests__/cloneComponentsFromEnv.test.ts +11 -11
  26. package/src/__tests__/createUiBuilderComponent.test.ts +7 -2
  27. package/src/__tests__/generateComponents.test.ts +27 -32
  28. package/src/__tests__/getAmplifyDataSchema.test.ts +17 -25
  29. package/src/__tests__/shouldRenderComponents.test.ts +51 -4
  30. package/src/__tests__/syncAmplifyUiComponents.test.ts +19 -4
  31. package/src/clients/amplify-studio-client.ts +31 -26
  32. package/src/commands/generateComponents.ts +2 -5
  33. package/src/commands/utils/codegenResources.ts +8 -3
  34. package/src/commands/utils/featureFlags.ts +6 -5
  35. package/src/commands/utils/shouldRenderComponents.ts +20 -8
  36. package/src/commands/utils/syncAmplifyUiBuilderComponents.ts +25 -3
  37. package/tsconfig.tsbuildinfo +1 -1
@@ -6,7 +6,7 @@ const extractArgsDependencyMock = extractArgsDependency as any;
6
6
  const awsMock = aws as any;
7
7
 
8
8
  jest.mock('../commands/utils/featureFlags', () => ({
9
- getTransformerVersion: jest.fn().mockImplementation(() => 2)
9
+ getTransformerVersion: jest.fn().mockReturnValue(2),
10
10
  }));
11
11
  jest.mock('../commands/utils/extractArgs');
12
12
  jest.mock('amplify-cli-core');
@@ -21,7 +21,7 @@ const mockedComponentExport = jest.fn((envName: string) => {
21
21
  entities: [{}],
22
22
  };
23
23
  });
24
- const mockedComponentCreate = jest.fn(() => ({ entity: {} }));
24
+ const mockedComponentCreate = jest.fn().mockReturnValue({ entity: {} });
25
25
 
26
26
  describe('can clone components to new environment', () => {
27
27
  let context: any;
@@ -37,26 +37,26 @@ describe('can clone components to new environment', () => {
37
37
  },
38
38
  },
39
39
  };
40
- extractArgsDependencyMock.extractArgs = jest.fn().mockImplementation(() => ({
40
+ extractArgsDependencyMock.extractArgs = jest.fn().mockReturnValue({
41
41
  sourceEnvName: 'sourceEnvName',
42
42
  newEnvName: 'newEnvName',
43
43
  appId: 'appId',
44
44
  environmentName: 'environmentName',
45
- }));
46
- awsMock.AmplifyUIBuilder = jest.fn(() => ({
45
+ });
46
+ awsMock.AmplifyUIBuilder = jest.fn().mockReturnValue({
47
47
  exportComponents: jest.fn(({ environmentName }) => ({
48
48
  promise: () => mockedComponentExport(environmentName),
49
49
  })),
50
- createComponent: jest.fn(() => ({ promise: () => mockedComponentCreate() })),
51
- getMetadata: jest.fn(() => ({
52
- promise: jest.fn(() => ({
50
+ createComponent: jest.fn().mockReturnValue({ promise: () => mockedComponentCreate() }),
51
+ getMetadata: jest.fn().mockReturnValue({
52
+ promise: jest.fn().mockReturnValue({
53
53
  features: {
54
54
  autoGenerateForms: 'true',
55
55
  autoGenerateViews: 'true',
56
56
  },
57
- })),
58
- })),
59
- }));
57
+ }),
58
+ }),
59
+ });
60
60
  });
61
61
 
62
62
  it('clones components to a new env', async () => {
@@ -1,3 +1,4 @@
1
+ /* eslint-disable spellcheck/spell-checker */
1
2
  import * as codegen from '@aws-amplify/codegen-ui'; // eslint-disable-line import/no-extraneous-dependencies
2
3
  import {
3
4
  generateAmplifyUiBuilderIndexFile,
@@ -44,9 +45,9 @@ describe('can create a ui builder component', () => {
44
45
  variants: [],
45
46
  };
46
47
  const renderSchemaToTemplateMock = jest.fn();
47
- codegenMock.StudioTemplateRendererManager = jest.fn().mockImplementation(() => ({
48
+ codegenMock.StudioTemplateRendererManager = jest.fn().mockReturnValue({
48
49
  renderSchemaToTemplate: renderSchemaToTemplateMock,
49
- }));
50
+ });
50
51
  });
51
52
  it('calls the renderManager', () => {
52
53
  createUiBuilderComponent(context, schema);
@@ -56,6 +57,10 @@ describe('can create a ui builder component', () => {
56
57
  createUiBuilderTheme(context, schema);
57
58
  expect(new codegenMock.StudioTemplateRendererManager().renderSchemaToTemplate).toBeCalled();
58
59
  });
60
+ it('calls the renderManager for default theme', () => {
61
+ createUiBuilderTheme(context, schema, { renderDefaultTheme: true });
62
+ expect(new codegenMock.StudioTemplateRendererManager().renderSchemaToTemplate).toBeCalled();
63
+ });
59
64
  it('calls the renderManager for forms', () => {
60
65
  createUiBuilderForm(context, schema);
61
66
  expect(new codegenMock.StudioTemplateRendererManager().renderSchemaToTemplate).toBeCalled();
@@ -1,5 +1,4 @@
1
1
  import aws from 'aws-sdk'; // eslint-disable-line import/no-extraneous-dependencies
2
- import { CloudformationProviderFacade } from 'amplify-cli-core';
3
2
  import * as utils from '../commands/utils';
4
3
  import { run } from '../commands/generateComponents';
5
4
 
@@ -8,13 +7,10 @@ jest.mock('amplify-cli-core');
8
7
  const awsMock = aws as any;
9
8
  const utilsMock = utils as any;
10
9
 
11
- utilsMock.shouldRenderComponents = jest.fn().mockImplementation(() => true);
12
- utilsMock.notifyMissingPackages = jest.fn().mockImplementation(() => true);
13
- CloudformationProviderFacade.isAmplifyAdminApp = jest.fn().mockImplementation(() => ({
14
- isAdminApp: true,
15
- }));
10
+ utilsMock.shouldRenderComponents = jest.fn().mockReturnValue(true);
11
+ utilsMock.notifyMissingPackages = jest.fn().mockReturnValue(true);
16
12
  jest.mock('../commands/utils/featureFlags', () => ({
17
- getTransformerVersion: jest.fn().mockImplementation(() => 2)
13
+ getTransformerVersion: jest.fn().mockImplementation(() => 2),
18
14
  }));
19
15
 
20
16
  describe('can generate components', () => {
@@ -43,37 +39,37 @@ describe('can generate components', () => {
43
39
  },
44
40
  ],
45
41
  };
46
- mockedExport = jest.fn(() => ({
42
+ mockedExport = jest.fn().mockReturnValue({
47
43
  entities: schemas.entities,
48
- }));
49
- awsMock.AmplifyUIBuilder = jest.fn(() => ({
50
- exportComponents: jest.fn(() => ({
44
+ });
45
+ awsMock.AmplifyUIBuilder = jest.fn().mockReturnValue({
46
+ exportComponents: jest.fn().mockReturnValue({
51
47
  promise: () => mockedExport(),
52
- })),
53
- exportThemes: jest.fn(() => ({
48
+ }),
49
+ exportThemes: jest.fn().mockReturnValue({
54
50
  promise: () => mockedExport(),
55
- })),
56
- exportForms: jest.fn(() => ({
51
+ }),
52
+ exportForms: jest.fn().mockReturnValue({
57
53
  promise: () => mockedExport(),
58
- })),
59
- exportViews: jest.fn(() => ({
54
+ }),
55
+ exportViews: jest.fn().mockReturnValue({
60
56
  promise: () => mockedExport(),
61
- })),
62
- getMetadata: jest.fn(() => ({
63
- promise: jest.fn(() => ({
57
+ }),
58
+ getMetadata: jest.fn().mockReturnValue({
59
+ promise: jest.fn().mockReturnValue({
64
60
  features: {
65
61
  autoGenerateForms: 'true',
66
62
  autoGenerateViews: 'true',
67
63
  },
68
- })),
69
- })),
70
- }));
71
- utilsMock.generateUiBuilderComponents = jest.fn().mockImplementation(() => schemas.entities);
72
- utilsMock.generateUiBuilderThemes = jest.fn().mockImplementation(() => schemas.entities);
73
- utilsMock.generateUiBuilderForms = jest.fn().mockImplementation(() => schemas.entities);
74
- utilsMock.getAmplifyDataSchema = jest.fn().mockImplementation(() => undefined);
75
- utilsMock.generateAmplifyUiBuilderIndexFile = jest.fn().mockImplementation(() => true);
76
- utilsMock.generateAmplifyUiBuilderUtilFile = jest.fn().mockImplementation(() => true);
64
+ }),
65
+ }),
66
+ });
67
+ utilsMock.generateUiBuilderComponents = jest.fn().mockReturnValue(schemas.entities);
68
+ utilsMock.generateUiBuilderThemes = jest.fn().mockReturnValue(schemas.entities);
69
+ utilsMock.generateUiBuilderForms = jest.fn().mockReturnValue(schemas.entities);
70
+ utilsMock.getAmplifyDataSchema = jest.fn().mockReturnValue(undefined);
71
+ utilsMock.generateAmplifyUiBuilderIndexFile = jest.fn().mockReturnValue(true);
72
+ utilsMock.generateAmplifyUiBuilderUtilFile = jest.fn().mockReturnValue(true);
77
73
  });
78
74
 
79
75
  it('runs generateComponents', async () => {
@@ -83,10 +79,9 @@ describe('can generate components', () => {
83
79
  expect(utilsMock.generateUiBuilderThemes).toBeCalledTimes(1);
84
80
  expect(utilsMock.generateUiBuilderForms).toBeCalledTimes(1);
85
81
  });
82
+
86
83
  it('does not run generateComponents if not Amplify Admin app', async () => {
87
- CloudformationProviderFacade.isAmplifyAdminApp = jest.fn().mockImplementationOnce(() => ({
88
- isAdminApp: false,
89
- }));
84
+ utilsMock.shouldRenderComponents = jest.fn().mockReturnValue(false);
90
85
  await run(context);
91
86
  expect(mockedExport).toBeCalledTimes(0);
92
87
  expect(utilsMock.generateUiBuilderComponents).toBeCalledTimes(0);
@@ -81,16 +81,16 @@ describe('should sync amplify backend models', () => {
81
81
 
82
82
  mockedFeatureFlags.getNumber.mockReturnValue(2);
83
83
  getMockedSchema.mockClear();
84
- });
85
-
86
- it('should getAmplifyBackendModels', async () => {
87
- awsMock.AmplifyBackend = jest.fn(() => ({
88
- getBackendAPIModels: jest.fn(() => ({
84
+ awsMock.AmplifyBackend = jest.fn().mockReturnValue({
85
+ getBackendAPIModels: jest.fn().mockReturnValue({
89
86
  promise: () => ({
90
87
  Models: getMockedSchema(),
91
88
  }),
92
- })),
93
- }));
89
+ }),
90
+ });
91
+ });
92
+
93
+ it('should getAmplifyBackendModels', async () => {
94
94
  const client = await AmplifyStudioClient.setClientInfo(context);
95
95
  const dataSchema = await getAmplifyDataSchema(client);
96
96
  expect(getMockedSchema).toBeCalled();
@@ -100,14 +100,6 @@ describe('should sync amplify backend models', () => {
100
100
 
101
101
  it('should not getAmplifyBackendModels and return undefined if graphQLTransformer version not supported', async () => {
102
102
  mockedFeatureFlags.getNumber.mockReturnValue(1);
103
-
104
- awsMock.AmplifyBackend = jest.fn(() => ({
105
- getBackendAPIModels: jest.fn(() => ({
106
- promise: () => ({
107
- Models: getMockedSchema(),
108
- }),
109
- })),
110
- }));
111
103
  const client = await AmplifyStudioClient.setClientInfo(context);
112
104
  const dataSchema = await getAmplifyDataSchema(client);
113
105
  expect(getMockedSchema).not.toBeCalled();
@@ -115,13 +107,13 @@ describe('should sync amplify backend models', () => {
115
107
  });
116
108
 
117
109
  it('should handle Models not found', async () => {
118
- awsMock.AmplifyBackend = jest.fn(() => ({
119
- getBackendAPIModels: jest.fn(() => ({
120
- promise: jest.fn(() => ({
110
+ awsMock.AmplifyBackend = jest.fn().mockReturnValue({
111
+ getBackendAPIModels: jest.fn().mockReturnValue({
112
+ promise: () => ({
121
113
  Models: undefined,
122
- })),
123
- })),
124
- }));
114
+ }),
115
+ }),
116
+ });
125
117
  const client = await AmplifyStudioClient.setClientInfo(context);
126
118
  const dataSchema = await getAmplifyDataSchema(client);
127
119
  expect(dataSchema).toBeUndefined();
@@ -129,11 +121,11 @@ describe('should sync amplify backend models', () => {
129
121
  });
130
122
 
131
123
  it('should handle network error', async () => {
132
- awsMock.AmplifyBackend = jest.fn(() => ({
133
- getBackendAPIModels: jest.fn(() => ({
124
+ awsMock.AmplifyBackend = jest.fn().mockReturnValue({
125
+ getBackendAPIModels: jest.fn().mockReturnValue({
134
126
  promise: jest.fn().mockRejectedValue(new Error('Network Error')),
135
- })),
136
- }));
127
+ }),
128
+ });
137
129
  const client = await AmplifyStudioClient.setClientInfo(context);
138
130
  const dataSchema = await getAmplifyDataSchema(client);
139
131
  expect(dataSchema).toBeUndefined();
@@ -1,13 +1,60 @@
1
- import { $TSContext } from 'amplify-cli-core';
1
+ // eslint-disable-next-line import/no-extraneous-dependencies
2
+ import {
3
+ $TSContext, AmplifyCategories, AmplifySupportedService, CloudformationProviderFacade,
4
+ } from 'amplify-cli-core';
5
+ import aws from 'aws-sdk'; // eslint-disable-line import/no-extraneous-dependencies
2
6
  import { shouldRenderComponents } from '../commands/utils/shouldRenderComponents';
3
7
 
8
+ const awsMock = aws as any;
9
+
10
+ jest.mock('amplify-cli-core', () => ({
11
+ ...jest.requireActual('amplify-cli-core'),
12
+ stateManager: {
13
+ getMeta: jest.fn(() => ({
14
+ [AmplifyCategories.API]: {
15
+ MyResourceName: {
16
+ service: AmplifySupportedService.APPSYNC,
17
+ },
18
+ },
19
+ })),
20
+ // eslint-disable-next-line spellcheck/spell-checker
21
+ getCLIJSON: jest.fn().mockReturnValue({ features: { graphqltransformer: { transformerversion: 2 } } }),
22
+ setCLIJSON: jest.fn(),
23
+ },
24
+ FeatureFlags: {
25
+ getBoolean: () => true,
26
+ getNumber: jest.fn().mockReturnValue(2),
27
+ reloadValues: jest.fn(),
28
+ },
29
+ }));
30
+ CloudformationProviderFacade.isAmplifyAdminApp = jest.fn().mockReturnValue({
31
+ isAdminApp: true,
32
+ });
33
+
4
34
  describe('should render components', () => {
5
35
  let context: $TSContext | any;
6
- beforeEach(() => {
36
+
37
+ beforeAll(async () => {
38
+ // set metadata response
39
+ awsMock.AmplifyUIBuilder = jest.fn(() => ({
40
+ getMetadata: jest.fn(() => ({
41
+ promise: jest.fn(() => ({
42
+ features: {
43
+ autoGenerateForms: 'true',
44
+ autoGenerateViews: 'true',
45
+ },
46
+ })),
47
+ })),
48
+ }));
7
49
  context = {
50
+ amplify: {
51
+ invokePluginMethod: () => ({}),
52
+ },
8
53
  input: {
9
54
  options: {
10
55
  'no-codegen': false,
56
+ appId: 'testAppId',
57
+ envName: 'testEnvName',
11
58
  },
12
59
  },
13
60
  exeInfo: {
@@ -35,12 +82,12 @@ describe('should render components', () => {
35
82
  const shouldIt = await shouldRenderComponents(context);
36
83
  expect(shouldIt).toBe(false);
37
84
  });
38
- it("doesn't work if the frontend is not javascript", async () => {
85
+ it('should return false if frontend is ios', async () => {
39
86
  context.exeInfo.projectConfig.frontend = 'ios';
40
87
  const shouldIt = await shouldRenderComponents(context);
41
88
  expect(shouldIt).toBe(false);
42
89
  });
43
- it("doesn't work if the frontend is not javascript", async () => {
90
+ it('should return false if frontend is vue', async () => {
44
91
  context.exeInfo.projectConfig.javascript.framework = 'vue';
45
92
  const shouldIt = await shouldRenderComponents(context);
46
93
  expect(shouldIt).toBe(false);
@@ -1,3 +1,4 @@
1
+ /* eslint-disable spellcheck/spell-checker */
1
2
  import { AmplifyCategories, AmplifySupportedService, stateManager } from 'amplify-cli-core'; // eslint-disable-line import/no-extraneous-dependencies
2
3
  import aws from 'aws-sdk'; // eslint-disable-line import/no-extraneous-dependencies
3
4
  import {
@@ -11,7 +12,6 @@ import {
11
12
  import { AmplifyStudioClient } from '../clients';
12
13
  import * as createUiBuilderComponentDependency from '../commands/utils/codegenResources';
13
14
  import { exampleSchema } from './utils';
14
- import { GenericDataModel, GenericDataSchema } from '@aws-amplify/codegen-ui';
15
15
 
16
16
  jest.mock('amplify-cli-core', () => ({
17
17
  ...jest.requireActual('amplify-cli-core'),
@@ -21,7 +21,7 @@ jest.mock('amplify-cli-core', () => ({
21
21
  },
22
22
  }));
23
23
  jest.mock('../commands/utils/featureFlags', () => ({
24
- getTransformerVersion: jest.fn().mockImplementation(() => 2)
24
+ getTransformerVersion: jest.fn().mockReturnValue(2),
25
25
  }));
26
26
 
27
27
  const awsMock = aws as any;
@@ -238,6 +238,18 @@ describe('should sync amplify ui builder components', () => {
238
238
  const themes = generateUiBuilderThemes(context, [{}, {}]);
239
239
  expect(themes.every(theme => theme.resultType === 'FAILURE')).toBeTruthy();
240
240
  });
241
+ it('can generate ui builder default theme when no themes are passed', async () => {
242
+ createUiBuilderComponentDependencyMock.createUiBuilderTheme = jest.fn().mockImplementation(() => ({}));
243
+ const themes = generateUiBuilderThemes(context, []);
244
+ expect(themes.every(theme => theme.resultType === 'SUCCESS')).toBeTruthy();
245
+ });
246
+ it('can handle failed generation generate ui builder default theme when no themes are passed', async () => {
247
+ createUiBuilderComponentDependencyMock.createUiBuilderTheme = jest.fn().mockImplementation(() => {
248
+ throw new Error('ahh!');
249
+ });
250
+ const themes = generateUiBuilderThemes(context, []);
251
+ expect(themes.every(theme => theme.resultType === 'FAILURE')).toBeTruthy();
252
+ });
241
253
  it('can generate ui builder forms', async () => {
242
254
  createUiBuilderComponentDependencyMock.createUiBuilderForm = jest.fn().mockImplementation(() => ({}));
243
255
  const forms = generateUiBuilderForms(context, [{}, {}]);
@@ -259,8 +271,11 @@ describe('should sync amplify ui builder components', () => {
259
271
  });
260
272
 
261
273
  it('should not autogen forms for join tables or unsupported models', async () => {
262
- expect(Object.keys(exampleSchema.models)).toStrictEqual(['Author', 'JoinTable', 'EmptyModel' ])
263
- createUiBuilderComponentDependencyMock.createUiBuilderForm = jest.fn().mockImplementation((context, schema, dataSchema) => ({name: schema.dataType.dataTypeName}));
274
+ expect(Object.keys(exampleSchema.models)).toStrictEqual(['Author', 'JoinTable', 'EmptyModel']);
275
+ createUiBuilderComponentDependencyMock.createUiBuilderForm = jest.fn().mockImplementation(
276
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
277
+ (_ctx, schema, _dataSchema) => ({ name: schema.dataType.dataTypeName }),
278
+ );
264
279
  const forms = generateUiBuilderForms(context, [], exampleSchema, true);
265
280
  expect(forms.every(form => form.resultType === 'SUCCESS')).toBeTruthy();
266
281
  // only create & update form for author model
@@ -57,7 +57,23 @@ export default class AmplifyStudioClient {
57
57
  #appId: string;
58
58
  #envName: string;
59
59
  metadata: StudioMetadata;
60
- isSupportedGraphQL = false;
60
+ isGraphQLSupported = false;
61
+
62
+ /**
63
+ * static function meant to check if given appId is studio enabled
64
+ */
65
+ static isAmplifyApp = async (context: $TSContext, appId: string): Promise<boolean> => {
66
+ try {
67
+ const { isAdminApp } = await CloudformationProviderFacade.isAmplifyAdminApp(context, appId);
68
+ return isAdminApp;
69
+ } catch (err) {
70
+ // return false is admin app failed check
71
+ // this means we wont run codegen-ui
72
+ printer.debug(`Failed admin app check: ${err.message}`);
73
+ return false;
74
+ }
75
+ }
76
+
61
77
  /**
62
78
  * Used to configure the AWS Amplify clients.
63
79
  */
@@ -72,11 +88,11 @@ export default class AmplifyStudioClient {
72
88
 
73
89
  const client = new AmplifyStudioClient(awsConfigInfo, resolvedAppId, resolvedEnvName);
74
90
 
75
- if ((await getTransformerVersion(context)) === 2) {
91
+ if ((await getTransformerVersion()) === 2) {
76
92
  await client.loadMetadata();
77
- client.isSupportedGraphQL = true;
93
+ client.isGraphQLSupported = true;
78
94
  } else {
79
- client.isSupportedGraphQL = false;
95
+ client.isGraphQLSupported = false;
80
96
  }
81
97
 
82
98
  return client;
@@ -113,9 +129,8 @@ export default class AmplifyStudioClient {
113
129
  autoGenerateForms: response.features?.autoGenerateForms === 'true',
114
130
  autoGenerateViews: response.features?.autoGenerateViews === 'true',
115
131
  };
116
- } catch (e) {
117
- printer.debug(e.toString());
118
- throw e;
132
+ } catch (err) {
133
+ throw new Error(`Failed to load metadata: ${err.message}`);
119
134
  }
120
135
  };
121
136
 
@@ -141,9 +156,8 @@ export default class AmplifyStudioClient {
141
156
  } while (nextToken);
142
157
  printer.debug(JSON.stringify(uiBuilderComponents, null, 2));
143
158
  return { entities: uiBuilderComponents };
144
- } catch (e) {
145
- printer.debug(e);
146
- throw e;
159
+ } catch (err) {
160
+ throw new Error(`Failed to list components: ${err.message}`);
147
161
  }
148
162
  };
149
163
 
@@ -170,9 +184,8 @@ export default class AmplifyStudioClient {
170
184
  } while (nextToken);
171
185
  printer.debug(JSON.stringify(uiBuilderThemes, null, 2));
172
186
  return { entities: uiBuilderThemes };
173
- } catch (e) {
174
- printer.debug(e);
175
- throw e;
187
+ } catch (err) {
188
+ throw new Error(`Failed to list themes: ${err.message}`);
176
189
  }
177
190
  };
178
191
 
@@ -195,9 +208,8 @@ export default class AmplifyStudioClient {
195
208
  } while (nextToken);
196
209
  printer.debug(JSON.stringify(uibuilderForms, null, 2));
197
210
  return { entities: uibuilderForms };
198
- } catch (e) {
199
- printer.debug(e);
200
- throw e;
211
+ } catch (err) {
212
+ throw new Error(`Failed to list forms: ${err.message}`);
201
213
  }
202
214
  };
203
215
 
@@ -214,8 +226,7 @@ export default class AmplifyStudioClient {
214
226
  .promise();
215
227
  return response.entity;
216
228
  } catch (err) {
217
- printer.debug(err.toString());
218
- throw err;
229
+ throw new Error(`Failed to create component: ${err.message}`);
219
230
  }
220
231
  };
221
232
 
@@ -231,14 +242,8 @@ export default class AmplifyStudioClient {
231
242
  })
232
243
  .promise();
233
244
  return Models;
234
- } catch (e) {
235
- printer.debug(e);
236
- throw new Error(`Models not found in AmplifyBackend:GetBackendAPIModels response: ${e.message}`);
245
+ } catch (err) {
246
+ throw new Error(`Models not found in AmplifyBackend:GetBackendAPIModels response: ${err.message}`);
237
247
  }
238
248
  };
239
-
240
- isAmplifyApp = async (context: $TSContext): Promise<boolean> => {
241
- const { isAdminApp } = await CloudformationProviderFacade.isAmplifyAdminApp(context, this.#appId);
242
- return isAdminApp;
243
- }
244
249
  }
@@ -25,9 +25,6 @@ export const run = async (context: $TSContext): Promise<void> => {
25
25
  const spinner = ora('');
26
26
  try {
27
27
  const studioClient = await AmplifyStudioClient.setClientInfo(context);
28
- if (!(await studioClient.isAmplifyApp(context))) {
29
- return;
30
- }
31
28
  const [componentSchemas, themeSchemas, formSchemas, dataSchema] = await Promise.all([
32
29
  studioClient.listComponents(),
33
30
  studioClient.listThemes(),
@@ -35,7 +32,7 @@ export const run = async (context: $TSContext): Promise<void> => {
35
32
  getAmplifyDataSchema(studioClient),
36
33
  ]);
37
34
 
38
- const nothingWouldAutogen = !dataSchema || !studioClient.metadata.autoGenerateForms || !studioClient.isSupportedGraphQL;
35
+ const nothingWouldAutogen = !dataSchema || !studioClient.metadata.autoGenerateForms || !studioClient.isGraphQLSupported;
39
36
 
40
37
  if (nothingWouldAutogen && [componentSchemas, themeSchemas, formSchemas].every(group => !group.entities.length)) {
41
38
  printer.debug('Skipping UI component generation since none are found.');
@@ -47,7 +44,7 @@ export const run = async (context: $TSContext): Promise<void> => {
47
44
  component: generateUiBuilderComponents(context, componentSchemas.entities, dataSchema),
48
45
  theme: generateUiBuilderThemes(context, themeSchemas.entities),
49
46
  form: generateUiBuilderForms(
50
- context, formSchemas.entities, dataSchema, studioClient.metadata.autoGenerateForms && studioClient.isSupportedGraphQL,
47
+ context, formSchemas.entities, dataSchema, studioClient.metadata.autoGenerateForms && studioClient.isGraphQLSupported,
51
48
  ),
52
49
  };
53
50
 
@@ -23,6 +23,7 @@ import {
23
23
  ScriptKind,
24
24
  UtilTemplateType,
25
25
  ReactUtilsStudioTemplateRenderer,
26
+ ReactThemeStudioTemplateRendererOptions,
26
27
  } from '@aws-amplify/codegen-ui-react';
27
28
  import { printer } from 'amplify-prompts';
28
29
  import {
@@ -60,10 +61,14 @@ export const createUiBuilderComponent = (context: $TSContext, schema: StudioComp
60
61
  /**
61
62
  * Writes theme file to the work space
62
63
  */
63
- export const createUiBuilderTheme = (context: $TSContext, schema: StudioTheme): StudioTheme => {
64
+ export const createUiBuilderTheme = (
65
+ context: $TSContext,
66
+ schema: StudioTheme,
67
+ options?: ReactThemeStudioTemplateRendererOptions,
68
+ ): StudioTheme => {
64
69
  const uiBuilderComponentsPath = getUiBuilderComponentsPath(context);
65
70
  const rendererFactory = new StudioTemplateRendererFactory(
66
- (component: StudioTheme) => (new ReactThemeStudioTemplateRenderer(component, config) as unknown) as StudioTemplateRenderer<
71
+ (component: StudioTheme) => (new ReactThemeStudioTemplateRenderer(component, config, options) as unknown) as StudioTemplateRenderer<
67
72
  unknown,
68
73
  StudioTheme,
69
74
  FrameworkOutputManager<unknown>,
@@ -198,7 +203,7 @@ export const generateAmplifyUiBuilderUtilFile = (context: $TSContext, { hasForms
198
203
  export const getAmplifyDataSchema = async (
199
204
  studioClient: AmplifyStudioClient,
200
205
  ): Promise<GenericDataSchema | undefined> => {
201
- if (!studioClient.isSupportedGraphQL) {
206
+ if (!studioClient.isGraphQLSupported) {
202
207
  return undefined;
203
208
  }
204
209
  try {
@@ -1,7 +1,8 @@
1
1
  /* eslint-disable spellcheck/spell-checker */
2
2
  import {
3
- $TSContext, FeatureFlags, pathManager, stateManager,
3
+ FeatureFlags, pathManager, stateManager,
4
4
  } from 'amplify-cli-core';
5
+ import { printer } from 'amplify-prompts';
5
6
 
6
7
  // This is copy-pasta from the category api until they can expose the method to plugins
7
8
 
@@ -15,13 +16,13 @@ const transformerVersionFF = (): number => FeatureFlags.getNumber('graphQLTransf
15
16
  * Inspect feature flags for the project and determine if this particular project should be using graphql v2 or v1.
16
17
  * Coerces feature flags into a sane state if they are out of, and throws error on invalid configuration.
17
18
  */
18
- export const getTransformerVersion = async (context: $TSContext): Promise<number> => {
19
+ export const getTransformerVersion = async (): Promise<number> => {
19
20
  if (useExperimentalPipelinedTransformerFF() === false) {
20
21
  return 1;
21
22
  }
22
23
 
23
24
  if (isLegacyFeatureFlagConfiguration()) {
24
- await migrateToTransformerVersionFeatureFlag(context);
25
+ await migrateToTransformerVersionFeatureFlag();
25
26
  }
26
27
 
27
28
  const transformerVersion = transformerVersionFF();
@@ -40,7 +41,7 @@ const isLegacyFeatureFlagConfiguration = (): boolean => useExperimentalPipelined
40
41
  /**
41
42
  * Update project feature flags and alert the user if they have a deprecated set of feature flags.
42
43
  */
43
- const migrateToTransformerVersionFeatureFlag = async (context: $TSContext): Promise<void> => {
44
+ const migrateToTransformerVersionFeatureFlag = async (): Promise<void> => {
44
45
  const projectPath = pathManager.findProjectRoot() ?? process.cwd();
45
46
 
46
47
  const config = stateManager.getCLIJSON(projectPath, undefined, {
@@ -53,7 +54,7 @@ const migrateToTransformerVersionFeatureFlag = async (context: $TSContext): Prom
53
54
  stateManager.setCLIJSON(projectPath, config);
54
55
  await FeatureFlags.reloadValues();
55
56
  // eslint-disable-next-line spellcheck/spell-checker
56
- context.print.warning(
57
+ printer.warn(
57
58
  `\nThe project is configured with 'transformerVersion': ${transformerVersionFF()}, but 'useExperimentalPipelinedTransformer': ${useExperimentalPipelinedTransformerFF()}. Setting the 'transformerVersion': ${
58
59
  config.features.graphqltransformer.transformerversion
59
60
  }. 'useExperimentalPipelinedTransformer' is deprecated.`,
@@ -1,34 +1,46 @@
1
+ /* eslint-disable prefer-arrow/prefer-arrow-functions */
1
2
  import { $TSContext } from 'amplify-cli-core';
2
3
  import { printer } from 'amplify-prompts';
3
- export async function shouldRenderComponents(context: $TSContext) {
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> => {
4
11
  if (process.env.FORCE_RENDER) {
5
12
  printer.debug('Forcing component render since environment variable flag is set.');
6
13
  return true;
7
14
  }
8
15
  if (context?.input?.options?.['no-codegen']) {
9
- printer.debug('Not pulling components because --no-codegen flag is set');
16
+ printer.debug('Not pulling components because --no-codegen flag is set.');
10
17
  return false;
11
18
  }
12
19
 
13
20
  if (!context?.exeInfo?.projectConfig) {
14
- printer.debug('Not pulling components because there is no projectConfig set for this project');
21
+ printer.debug('Not pulling components because there is no projectConfig set for this project.');
15
22
  return false;
16
23
  }
17
24
 
18
25
  if (!context.exeInfo.projectConfig.providers.includes('awscloudformation')) {
19
- printer.debug('Not pulling components because there is no "awscloudformation" provider');
26
+ printer.debug('Not pulling components because there is no "awscloudformation" provider.');
20
27
  return false;
21
28
  }
22
29
 
23
30
  if (context.exeInfo.projectConfig.frontend !== 'javascript') {
24
- printer.debug('Not pulling components because this project is not configured as a javascript frontend');
31
+ printer.debug('Not pulling components because this project is not configured as a javascript frontend.');
32
+ return false;
33
+ }
34
+
35
+ if (context.exeInfo.projectConfig.javascript.framework !== 'react') {
36
+ printer.debug('Not pulling components because this project is not configured with the "react" framework.');
25
37
  return false;
26
38
  }
27
39
 
28
- if (context.exeInfo.projectConfig['javascript'].framework !== 'react') {
29
- printer.debug('Not pulling components because this project is not configured with the "react" framework');
40
+ if (!(await AmplifyStudioClient.isAmplifyApp(context, getAppId(context)))) {
41
+ printer.debug('Not pulling components because this project is not Amplify Studio enabled.');
30
42
  return false;
31
43
  }
32
44
 
33
45
  return true;
34
- }
46
+ };