@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,309 +0,0 @@
1
- import { AmplifyCategories, AmplifySupportedService, stateManager } from '@aws-amplify/amplify-cli-core';
2
- import aws from 'aws-sdk';
3
- import {
4
- getEnvName,
5
- getAppId,
6
- resolveAppId,
7
- mapGenericDataSchemaToCodegen,
8
- waitForSucceededJob,
9
- extractUIComponents,
10
- fetchWithRetries,
11
- } from '../commands/utils';
12
- import { AmplifyStudioClient } from '../clients';
13
- import { isDataStoreEnabled } from '@aws-amplify/amplify-category-api';
14
- import type { GenericDataSchema } from '@aws-amplify/codegen-ui';
15
- import fetch, { Response } from 'node-fetch';
16
- import { existsSync, writeFileSync } from 'fs';
17
-
18
- jest.mock('@aws-amplify/amplify-cli-core', () => ({
19
- ...jest.requireActual('@aws-amplify/amplify-cli-core'),
20
- FeatureFlags: {
21
- getBoolean: () => false,
22
- getNumber: () => 0,
23
- },
24
- }));
25
- jest.mock('../commands/utils/featureFlags', () => ({
26
- getTransformerVersion: jest.fn().mockReturnValue(2),
27
- }));
28
- jest.mock('@aws-amplify/amplify-category-api', () => ({
29
- isDataStoreEnabled: jest.fn(),
30
- }));
31
- jest.mock('fs');
32
- jest.mock('node-fetch');
33
-
34
- const awsMock = aws as any;
35
- const stateManagerMock = stateManager as any;
36
- const isDataStoreEnabledMocked = jest.mocked(isDataStoreEnabled);
37
- const mockWriteFileSync = jest.mocked(writeFileSync);
38
- const mockExistsSync = jest.mocked(existsSync);
39
- const mockNodeFetch = jest.mocked(fetch);
40
-
41
- describe('should sync amplify ui builder components', () => {
42
- let context: any;
43
- const env = process.env;
44
-
45
- const mockGenericDataSchema: GenericDataSchema = {
46
- dataSourceType: 'DataStore',
47
- models: {
48
- Blog: {
49
- fields: {
50
- id: { dataType: 'ID', required: true, readOnly: false, isArray: false },
51
- },
52
- primaryKeys: ['id'],
53
- },
54
- },
55
- enums: {
56
- Status: { values: ['ENABLED', 'DISABLED', 'HIDDEN'] },
57
- },
58
- nonModels: {
59
- Metadata: {
60
- fields: {
61
- name: {
62
- dataType: 'String',
63
- required: false,
64
- readOnly: false,
65
- isArray: false,
66
- },
67
- },
68
- },
69
- },
70
- };
71
-
72
- beforeEach(() => {
73
- mockNodeFetch.mockReset();
74
- process.env = { ...env };
75
-
76
- isDataStoreEnabledMocked.mockResolvedValue(true);
77
- mockExistsSync.mockReturnValue(false);
78
- context = {
79
- exeInfo: {
80
- projectConfig: {
81
- javascript: {
82
- config: {
83
- SourceDir: 'src',
84
- },
85
- },
86
- },
87
- },
88
- amplify: {
89
- invokePluginMethod: () => ({}),
90
- },
91
- parameters: {
92
- argv: [],
93
- },
94
- input: {
95
- options: {
96
- appId: 'testAppId',
97
- envName: 'testEnvName',
98
- },
99
- },
100
- };
101
-
102
- stateManagerMock.getMeta = jest.fn(() => ({
103
- [AmplifyCategories.API]: {
104
- MyResourceName: {
105
- service: AmplifySupportedService.APPSYNC,
106
- },
107
- },
108
- providers: {
109
- awscloudformation: { AmplifyAppId: 'testAppId' },
110
- },
111
- }));
112
-
113
- awsMock.AmplifyUIBuilder = jest.fn(() => ({
114
- exportComponents: jest.fn(() => ({
115
- promise: jest.fn(() => ({
116
- entities: [
117
- {
118
- appId: 'd37nrm8rzt3oek', // eslint-disable-line spellcheck/spell-checker
119
- bindingProperties: {},
120
- componentType: 'Box',
121
- environmentName: 'staging',
122
- id: 's-s4mU579Ycf6JGHwhqT', // eslint-disable-line spellcheck/spell-checker
123
- name: 'aawwdd', // eslint-disable-line spellcheck/spell-checker
124
- overrides: {},
125
- properties: {},
126
- variants: [],
127
- },
128
- ],
129
- })),
130
- })),
131
- exportThemes: jest.fn(() => ({
132
- promise: jest.fn(() => ({
133
- entities: [{}],
134
- })),
135
- })),
136
- exportForms: jest.fn(() => ({
137
- promise: jest.fn(() => ({
138
- entities: [
139
- {
140
- name: 'BasicFormCreate',
141
- formActionType: 'create',
142
- dataType: {
143
- dataSourceType: 'Custom',
144
- dataTypeName: 'Post',
145
- },
146
- fields: {
147
- name: {
148
- inputType: {
149
- required: true,
150
- type: 'TextField',
151
- name: 'name',
152
- defaultValue: 'John Doe',
153
- },
154
- label: 'name',
155
- },
156
- },
157
- sectionalElements: {},
158
- style: {},
159
- },
160
- ],
161
- })),
162
- })),
163
- exportViews: jest.fn(() => ({
164
- promise: jest.fn(() => ({
165
- entities: [
166
- {
167
- appId: '23342',
168
- dataSource: { type: 'Custom' },
169
- environmentName: 'staging',
170
- id: 'id',
171
- name: 'ProductTable',
172
- // TODO: replace with export when Codegen updated
173
- schemaVersion: '1.0',
174
- style: {},
175
- viewConfiguration: {
176
- type: 'Table',
177
- },
178
- },
179
- ],
180
- })),
181
- })),
182
- getMetadata: jest.fn(() => ({
183
- promise: jest.fn(() => ({
184
- features: {
185
- autoGenerateForms: 'true',
186
- autoGenerateViews: 'true',
187
- formFeatureFlags: {
188
- isRelationshipSupported: 'false',
189
- isNonModelSupported: 'false',
190
- },
191
- },
192
- })),
193
- })),
194
- }));
195
- });
196
-
197
- afterEach(() => {
198
- process.env = env;
199
- });
200
-
201
- it('can getAmplifyUIBuilderService', async () => {
202
- process.env.UI_BUILDER_ENDPOINT = 'https://mock-endpoint.com';
203
- process.env.UI_BUILDER_REGION = 'mock-region';
204
- const client = await AmplifyStudioClient.setClientInfo(context);
205
- expect(Object.keys(client)).toEqual(
206
- expect.arrayContaining(['listComponents', 'listThemes', 'listForms', 'getModels', 'loadMetadata', 'createComponent']),
207
- );
208
- expect(client.metadata).toEqual(
209
- expect.objectContaining({
210
- autoGenerateForms: true,
211
- autoGenerateViews: true,
212
- formFeatureFlags: {
213
- isRelationshipSupported: false,
214
- isNonModelSupported: false,
215
- },
216
- }),
217
- );
218
- });
219
-
220
- it('can list components', async () => {
221
- const client = await AmplifyStudioClient.setClientInfo(context);
222
- const components = await client.listComponents();
223
- expect(components.entities).toHaveLength(1);
224
- });
225
-
226
- it('can list themes', async () => {
227
- const client = await AmplifyStudioClient.setClientInfo(context);
228
- const themes = await client.listThemes();
229
- expect(themes.entities).toHaveLength(1);
230
- });
231
-
232
- it('can list forms', async () => {
233
- const client = await AmplifyStudioClient.setClientInfo(context);
234
- const forms = await client.listForms();
235
- expect(forms.entities).toHaveLength(1);
236
- });
237
-
238
- it('can getAppId', async () => {
239
- const appId = getAppId(context);
240
- expect(appId).toBe('testAppId');
241
- });
242
-
243
- it('can getEnvName', () => {
244
- const envName = getEnvName(context);
245
- expect(envName).toBe('testEnvName');
246
- });
247
-
248
- it('can resolveAppId', async () => {
249
- const appId = resolveAppId();
250
- expect(appId).toBe('testAppId');
251
- });
252
-
253
- it('can throw on getAppId', async () => {
254
- context.input.options.appId = null;
255
- context.amplify.invokePluginMethod = () => null;
256
- stateManagerMock.getMeta = () => ({});
257
- expect(() => getAppId(context)).toThrowError();
258
- });
259
-
260
- it('can map generic data schema to start codegen job request', () => {
261
- expect(mapGenericDataSchemaToCodegen(mockGenericDataSchema)).toMatchSnapshot();
262
- });
263
-
264
- it('can wait for a succeeded job', async () => {
265
- const succeededJob = { status: 'succeeded' };
266
- const getJob = jest.fn().mockResolvedValueOnce({ status: 'in_progress' }).mockResolvedValueOnce(succeededJob);
267
- const job = await waitForSucceededJob(getJob, { pollInterval: 1 });
268
- expect(job).toEqual(succeededJob);
269
- });
270
-
271
- it('can throw if job failed', async () => {
272
- const statusMessage = 'failed status';
273
- const getJob = jest.fn().mockResolvedValueOnce({ status: 'in_progress' }).mockResolvedValueOnce({ status: 'failed', statusMessage });
274
- await expect(waitForSucceededJob(getJob, { pollInterval: 2 })).rejects.toThrow(statusMessage);
275
- });
276
-
277
- it('can throw after timeout when waiting for a succeeded job', async () => {
278
- process.env.UI_BUILDER_CODEGENJOB_TIMEOUT = '1';
279
- const succeededJob = { status: 'succeeded' };
280
- const getJob = jest.fn().mockResolvedValueOnce({ status: 'in_progress' }).mockResolvedValueOnce(succeededJob);
281
- await expect(waitForSucceededJob(getJob, { pollInterval: 2 })).rejects.toThrow('Failed to return codegen job');
282
- });
283
-
284
- it('can extract ui components from archive', async () => {
285
- const mockedFetchResponse = {
286
- ok: true,
287
- json: jest.fn().mockResolvedValue({
288
- Output: [
289
- {
290
- downloadUrl: 'https://s3.com',
291
- fileName: 'MyComponent.jsx',
292
- schemaName: 'MyComponent',
293
- },
294
- ],
295
- }),
296
- text: jest.fn().mockResolvedValue('source code'),
297
- } as unknown as Response;
298
- mockNodeFetch.mockResolvedValue(mockedFetchResponse);
299
- mockExistsSync.mockReturnValue(true);
300
- await extractUIComponents('https:://example.aws', 'tmp/ui-components');
301
- expect(mockWriteFileSync).toHaveBeenCalledWith('tmp/ui-components/MyComponent.jsx', 'source code');
302
- });
303
-
304
- it('fetchWithRetries retries 3 times', async () => {
305
- mockNodeFetch.mockRejectedValue(new Error('Server dropped the connection'));
306
- await expect(fetchWithRetries('https://amazon.com')).rejects.toThrowError('Fetch reached max number of retries without succeeding');
307
- expect(mockNodeFetch).toHaveBeenCalledTimes(3);
308
- });
309
- });
@@ -1,41 +0,0 @@
1
- import { $TSContext } from '@aws-amplify/amplify-cli-core';
2
- import { relativeToComponentsPath } from '../../commands/utils/getApiConfiguration';
3
- import { getUiBuilderComponentsPath } from '../../commands/utils/getUiBuilderComponentsPath';
4
- import path from 'path';
5
-
6
- jest.mock('../../commands/utils/getUiBuilderComponentsPath', () => ({
7
- ...jest.requireActual('../../commands/utils/getUiBuilderComponentsPath'),
8
- getUiBuilderComponentsPath: jest.fn(),
9
- }));
10
-
11
- jest.mock('path', () => ({
12
- ...jest.requireActual('path'),
13
- }));
14
-
15
- const pathMocked = path as any;
16
-
17
- const getUiBuilderComponentsPathMocked = getUiBuilderComponentsPath as any;
18
-
19
- describe('relativeToComponentsPath', () => {
20
- it('should return posix relative path when run in a windows-like environment', () => {
21
- pathMocked.relative = path.win32.relative;
22
- pathMocked.sep = path.win32.sep;
23
- const projectPath = 'c:\\dev\\test\\test-project';
24
- const toImport = projectPath + '\\src\\graphql\\queries.js';
25
- getUiBuilderComponentsPathMocked.mockReturnValue(projectPath + '\\src\\ui-components');
26
-
27
- const response = relativeToComponentsPath(toImport, {} as $TSContext);
28
-
29
- expect(response).toBe('../graphql/queries.js');
30
- });
31
-
32
- it('should return expected relative path', () => {
33
- const projectPath = '/dev/test/test-project';
34
- const toImport = projectPath + '/src/graphql/queries.js';
35
- getUiBuilderComponentsPathMocked.mockReturnValue(projectPath + '/src/ui-components');
36
-
37
- const response = relativeToComponentsPath(toImport, {} as $TSContext);
38
-
39
- expect(response).toBe('../graphql/queries.js');
40
- });
41
- });
@@ -1,72 +0,0 @@
1
- import type { GenericDataSchema } from '@aws-amplify/codegen-ui';
2
-
3
- export const exampleSchema: GenericDataSchema = {
4
- dataSourceType: 'DataStore',
5
- models: {
6
- Author: {
7
- primaryKeys: ['id'],
8
- fields: {
9
- id: {
10
- dataType: 'ID',
11
- required: true,
12
- readOnly: false,
13
- isArray: false,
14
- },
15
- name: {
16
- dataType: 'String',
17
- required: false,
18
- readOnly: false,
19
- isArray: false,
20
- },
21
- profileImageSrc: {
22
- dataType: 'AWSURL',
23
- required: false,
24
- readOnly: false,
25
- isArray: false,
26
- },
27
- description: {
28
- dataType: 'String',
29
- required: false,
30
- readOnly: false,
31
- isArray: false,
32
- },
33
- books: {
34
- dataType: 'String',
35
- required: false,
36
- readOnly: false,
37
- isArray: true,
38
- },
39
- createdAt: {
40
- dataType: 'AWSDateTime',
41
- required: false,
42
- readOnly: true,
43
- isArray: false,
44
- },
45
- updatedAt: {
46
- dataType: 'AWSDateTime',
47
- required: false,
48
- readOnly: true,
49
- isArray: false,
50
- },
51
- },
52
- },
53
- JoinTable: {
54
- primaryKeys: ['id'],
55
- fields: {
56
- id: {
57
- dataType: 'ID',
58
- required: true,
59
- readOnly: false,
60
- isArray: false,
61
- },
62
- },
63
- isJoinTable: true,
64
- },
65
- EmptyModel: {
66
- primaryKeys: ['id'],
67
- fields: {},
68
- },
69
- },
70
- enums: {}, // eslint-disable-line spellcheck/spell-checker
71
- nonModels: {},
72
- };
@@ -1,10 +0,0 @@
1
- import { printer } from '@aws-amplify/amplify-prompts';
2
- import { run } from '../commands/version';
3
- jest.mock('@aws-amplify/amplify-prompts');
4
- printer.info = jest.fn();
5
- describe('can run version script', () => {
6
- it('runs version script', async () => {
7
- await run();
8
- expect(printer.info).toBeCalledTimes(1);
9
- });
10
- });