@aws-amplify/amplify-util-uibuilder 1.4.1-beta.0 → 1.4.2-rc.cf54accdc.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 (59) hide show
  1. package/CHANGELOG.md +92 -1
  2. package/lib/clients/amplify-studio-client.d.ts +17 -0
  3. package/lib/clients/amplify-studio-client.d.ts.map +1 -0
  4. package/lib/clients/amplify-studio-client.js +145 -0
  5. package/lib/clients/amplify-studio-client.js.map +1 -0
  6. package/lib/clients/index.d.ts +2 -0
  7. package/lib/clients/index.d.ts.map +1 -0
  8. package/lib/clients/index.js +9 -0
  9. package/lib/clients/index.js.map +1 -0
  10. package/lib/commands/cloneComponentsFromEnv.d.ts +1 -1
  11. package/lib/commands/cloneComponentsFromEnv.d.ts.map +1 -1
  12. package/lib/commands/cloneComponentsFromEnv.js +15 -31
  13. package/lib/commands/cloneComponentsFromEnv.js.map +1 -1
  14. package/lib/commands/generateComponents.d.ts.map +1 -1
  15. package/lib/commands/generateComponents.js +14 -12
  16. package/lib/commands/generateComponents.js.map +1 -1
  17. package/lib/commands/utils/{createUiBuilderComponent.d.ts → codegenResources.d.ts} +5 -3
  18. package/lib/commands/utils/codegenResources.d.ts.map +1 -0
  19. package/lib/commands/utils/{createUiBuilderComponent.js → codegenResources.js} +26 -4
  20. package/lib/commands/utils/codegenResources.js.map +1 -0
  21. package/lib/commands/utils/environmentHelpers.d.ts +5 -0
  22. package/lib/commands/utils/environmentHelpers.d.ts.map +1 -0
  23. package/lib/commands/utils/environmentHelpers.js +25 -0
  24. package/lib/commands/utils/environmentHelpers.js.map +1 -0
  25. package/lib/commands/utils/index.d.ts +8 -0
  26. package/lib/commands/utils/index.d.ts.map +1 -0
  27. package/lib/commands/utils/index.js +20 -0
  28. package/lib/commands/utils/index.js.map +1 -0
  29. package/lib/commands/utils/syncAmplifyUiBuilderComponents.d.ts +9 -18
  30. package/lib/commands/utils/syncAmplifyUiBuilderComponents.d.ts.map +1 -1
  31. package/lib/commands/utils/syncAmplifyUiBuilderComponents.js +8 -80
  32. package/lib/commands/utils/syncAmplifyUiBuilderComponents.js.map +1 -1
  33. package/lib/index.d.ts +3 -3
  34. package/lib/index.d.ts.map +1 -1
  35. package/lib/index.js +5 -5
  36. package/lib/index.js.map +1 -1
  37. package/package.json +15 -8
  38. package/src/__tests__/cloneComponentsFromEnv.test.ts +33 -26
  39. package/src/__tests__/createUiBuilderComponent.test.ts +14 -13
  40. package/src/__tests__/generateComponents.test.ts +40 -30
  41. package/src/__tests__/getAmplifyDataSchema.test.ts +102 -0
  42. package/src/__tests__/syncAmplifyUiComponents.test.ts +55 -33
  43. package/src/clients/amplify-studio-client.ts +161 -0
  44. package/src/clients/index.ts +1 -0
  45. package/src/commands/cloneComponentsFromEnv.ts +26 -29
  46. package/src/commands/generateComponents.ts +19 -12
  47. package/src/commands/utils/{createUiBuilderComponent.ts → codegenResources.ts} +39 -11
  48. package/src/commands/utils/environmentHelpers.ts +32 -0
  49. package/src/commands/utils/index.ts +7 -0
  50. package/src/commands/utils/syncAmplifyUiBuilderComponents.ts +38 -81
  51. package/src/index.ts +15 -5
  52. package/tsconfig.tsbuildinfo +1 -1
  53. package/lib/commands/utils/amplifyUiBuilderService.d.ts +0 -5
  54. package/lib/commands/utils/amplifyUiBuilderService.d.ts.map +0 -1
  55. package/lib/commands/utils/amplifyUiBuilderService.js +0 -20
  56. package/lib/commands/utils/amplifyUiBuilderService.js.map +0 -1
  57. package/lib/commands/utils/createUiBuilderComponent.d.ts.map +0 -1
  58. package/lib/commands/utils/createUiBuilderComponent.js.map +0 -1
  59. package/src/commands/utils/amplifyUiBuilderService.ts +0 -22
@@ -1,3 +1,5 @@
1
+ /* eslint-disable spellcheck/spell-checker*/
2
+ // You have a misspelled word: Renderer on Identifier
1
3
  import {
2
4
  StudioTemplateRendererManager,
3
5
  StudioComponent,
@@ -6,6 +8,8 @@ import {
6
8
  StudioTemplateRenderer,
7
9
  FrameworkOutputManager,
8
10
  RenderTextComponentResponse,
11
+ GenericDataSchema,
12
+ getGenericFromDataStore,
9
13
  } from '@aws-amplify/codegen-ui';
10
14
  import {
11
15
  AmplifyRenderer,
@@ -15,10 +19,12 @@ import {
15
19
  ScriptTarget,
16
20
  ScriptKind,
17
21
  } from '@aws-amplify/codegen-ui-react';
18
-
19
22
  import { printer } from 'amplify-prompts';
20
- import { $TSContext } from 'amplify-cli-core';
23
+ import {
24
+ $TSContext, AmplifyCategories, AmplifySupportedService, stateManager,
25
+ } from 'amplify-cli-core';
21
26
  import { getUiBuilderComponentsPath } from './getUiBuilderComponentsPath';
27
+ import { AmplifyStudioClient } from '../../clients';
22
28
 
23
29
  const config = {
24
30
  module: ModuleKind.ES2020,
@@ -30,15 +36,10 @@ const config = {
30
36
  /**
31
37
  * Writes component file to the work space
32
38
  */
33
- export const createUiBuilderComponent = (context: $TSContext, schema: StudioComponent): StudioComponent => {
39
+ export const createUiBuilderComponent = (context: $TSContext, schema: StudioComponent, dataSchema?: GenericDataSchema): StudioComponent => {
34
40
  const uiBuilderComponentsPath = getUiBuilderComponentsPath(context);
35
41
  const rendererFactory = new StudioTemplateRendererFactory(
36
- (component: StudioComponent) => new AmplifyRenderer(component as StudioComponent, config) as unknown as StudioTemplateRenderer<
37
- unknown,
38
- StudioComponent,
39
- FrameworkOutputManager<unknown>,
40
- RenderTextComponentResponse
41
- >,
42
+ (component: StudioComponent) => new AmplifyRenderer(component as StudioComponent, config, dataSchema),
42
43
  );
43
44
 
44
45
  const outputPathDir = uiBuilderComponentsPath;
@@ -57,7 +58,7 @@ export const createUiBuilderComponent = (context: $TSContext, schema: StudioComp
57
58
  export const createUiBuilderTheme = (context: $TSContext, schema: StudioTheme): StudioTheme => {
58
59
  const uiBuilderComponentsPath = getUiBuilderComponentsPath(context);
59
60
  const rendererFactory = new StudioTemplateRendererFactory(
60
- (component: StudioTheme) => new ReactThemeStudioTemplateRenderer(component, config) as unknown as StudioTemplateRenderer<
61
+ (component: StudioTheme) => (new ReactThemeStudioTemplateRenderer(component, config) as unknown) as StudioTemplateRenderer<
61
62
  unknown,
62
63
  StudioTheme,
63
64
  FrameworkOutputManager<unknown>,
@@ -88,7 +89,7 @@ export const createUiBuilderTheme = (context: $TSContext, schema: StudioTheme):
88
89
  export const generateAmplifyUiBuilderIndexFile = (context: $TSContext, schemas: StudioComponent[]): RenderTextComponentResponse => {
89
90
  const uiBuilderComponentsPath = getUiBuilderComponentsPath(context);
90
91
  const rendererFactory = new StudioTemplateRendererFactory(
91
- (component: StudioComponent[]) => new ReactIndexStudioTemplateRenderer(component, config) as unknown as StudioTemplateRenderer<
92
+ (component: StudioComponent[]) => (new ReactIndexStudioTemplateRenderer(component, config) as unknown) as StudioTemplateRenderer<
92
93
  unknown,
93
94
  StudioComponent[],
94
95
  FrameworkOutputManager<unknown>,
@@ -110,3 +111,30 @@ export const generateAmplifyUiBuilderIndexFile = (context: $TSContext, schemas:
110
111
  throw e;
111
112
  }
112
113
  };
114
+
115
+ /**
116
+ * If models are available, they will be populated in the models field of the returned object.
117
+ * If they're not available, it will return undefined
118
+ */
119
+ export const getAmplifyDataSchema = async (
120
+ studioClient: AmplifyStudioClient,
121
+ ): Promise<GenericDataSchema | undefined> => {
122
+ try {
123
+ const meta = stateManager.getMeta();
124
+ const resourceName = Object.entries(meta[AmplifyCategories.API]).find(
125
+ ([, value]) => (value as { service: string }).service === AmplifySupportedService.APPSYNC,
126
+ )?.[0];
127
+ if (resourceName) {
128
+ const model = await studioClient.getModels(resourceName);
129
+ if (model) {
130
+ const source = model.replace(model.substring(0, model.indexOf(`{`) - 1), ``).replace(/;/g, ``);
131
+ return getGenericFromDataStore(JSON.parse(source));
132
+ }
133
+ }
134
+ printer.debug(`Provided ResourceName: ${resourceName} did not yield Models.`);
135
+ return undefined;
136
+ } catch (error) {
137
+ printer.debug(error.toString());
138
+ return undefined;
139
+ }
140
+ };
@@ -0,0 +1,32 @@
1
+ import { $TSContext, stateManager } from 'amplify-cli-core';
2
+ import { extractArgs } from './extractArgs';
3
+
4
+ /**
5
+ * Get's the environment name from the given name or the context
6
+ */
7
+ export const getEnvName = (context: $TSContext, envName?: string): string => {
8
+ const args = extractArgs(context);
9
+ return envName || args?.environmentName || context.exeInfo.localEnvInfo.envName;
10
+ };
11
+
12
+ /**
13
+ * Returns the appId from the context
14
+ */
15
+ export const resolveAppId = (): string | undefined => {
16
+ const meta = stateManager.getMeta();
17
+ return meta?.providers?.awscloudformation?.AmplifyAppId;
18
+ };
19
+
20
+ /**
21
+ * Returns the appId or throws an error if it's not found.
22
+ */
23
+ export const getAppId = (context: $TSContext, appId?: string): string => {
24
+ const resolvedAppId = appId || extractArgs(context).appId || resolveAppId();
25
+
26
+ if (!resolvedAppId) {
27
+ throw new Error(
28
+ 'Unable to sync Studio components since appId could not be determined. This can happen when you hit the soft limit of number of apps that you can have in Amplify console.',
29
+ );
30
+ }
31
+ return resolvedAppId;
32
+ };
@@ -0,0 +1,7 @@
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';
@@ -1,86 +1,29 @@
1
- import { getAmplifyUIBuilderService, Component, Theme } from './amplifyUiBuilderService';
2
1
  import { printer } from 'amplify-prompts';
3
- import { createUiBuilderComponent, createUiBuilderTheme } from './createUiBuilderComponent';
4
- import { getUiBuilderComponentsPath } from './getUiBuilderComponentsPath';
5
- import { extractArgs } from './extractArgs';
6
2
  import { $TSContext } from 'amplify-cli-core';
7
- export const getEnvName = (context: $TSContext, envName?: string) => {
8
- const args = extractArgs(context);
9
- return envName ? envName : args.environmentName ? args.environmentName : context.exeInfo.localEnvInfo.envName;
10
- };
11
-
12
- export const resolveAppId = async (context: $TSContext) => {
13
- return await context.amplify.invokePluginMethod(context, 'awscloudformation', undefined, 'resolveAppId', [context]);
14
- };
15
-
16
- export const getAppId = async (context: $TSContext) => {
17
- const appId = extractArgs(context).appId || (await resolveAppId(context));
18
-
19
- if (!appId) {
20
- throw new Error(
21
- 'Unable to sync Studio components since appId could not be determined. This can happen when you hit the soft limit of number of apps that you can have in Amplify console.',
22
- );
23
- }
24
- return appId;
25
- };
26
-
27
- export async function listUiBuilderComponents(context: $TSContext, envName?: string): Promise<{ entities: Component[] }> {
28
- const environmentName = getEnvName(context, envName);
29
- const appId = await getAppId(context);
30
-
31
- try {
32
- const amplifyUIBuilder = await getAmplifyUIBuilderService(context, environmentName, appId);
33
- let nextToken: string | undefined;
34
- const uiBuilderComponents: Component[] = [];
35
- do {
36
- const response = await amplifyUIBuilder
37
- .exportComponents({
38
- appId,
39
- environmentName,
40
- nextToken
41
- })
42
- .promise();
43
- uiBuilderComponents.push(...response.entities);
44
- nextToken = response.nextToken;
45
- } while (nextToken);
46
- printer.debug(JSON.stringify(uiBuilderComponents, null, 2));
47
- return { entities: uiBuilderComponents };
48
- } catch (e) {
49
- printer.debug(e);
50
- throw e;
51
- }
52
- }
53
-
54
- export async function listUiBuilderThemes(context: $TSContext, envName?: string): Promise<{ entities: Theme[] }> {
55
- const environmentName = getEnvName(context, envName);
56
- const appId = await getAppId(context);
57
-
58
- try {
59
- const amplifyUIBuilder = await getAmplifyUIBuilderService(context, environmentName, appId);
60
- let nextToken: string | undefined;
61
- const uiBuilderThemes: Theme[] = [];
62
- do {
63
- const response = await amplifyUIBuilder
64
- .exportThemes({
65
- appId,
66
- environmentName,
67
- })
68
- .promise();
69
- uiBuilderThemes.push(...response.entities);
70
- nextToken = response.nextToken;
71
- } while (nextToken);
72
- printer.debug(JSON.stringify(uiBuilderThemes, null, 2));
73
- return { entities: uiBuilderThemes };
74
- } catch (e) {
75
- printer.debug(e);
76
- throw e;
77
- }
78
- }
3
+ import {
4
+ StudioComponent, StudioTheme, GenericDataSchema,
5
+ } from '@aws-amplify/codegen-ui';
6
+ import { createUiBuilderComponent, createUiBuilderTheme } from './codegenResources';
7
+ import { getUiBuilderComponentsPath } from './getUiBuilderComponentsPath';
79
8
 
80
- export function generateUiBuilderComponents(context: $TSContext, componentSchemas: any[]) {
9
+ /**
10
+ * Returns instances of StudioComponent from the component schemas
11
+ */
12
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
+ export const generateUiBuilderComponents = (context: $TSContext, componentSchemas: any[], dataSchema?: GenericDataSchema): ({
14
+ resultType: string;
15
+ component: StudioComponent;
16
+ schemaName?: undefined;
17
+ error?: undefined;
18
+ } | {
19
+ resultType: string;
20
+ schemaName: string;
21
+ error: Error;
22
+ component?: undefined;
23
+ })[] => {
81
24
  const componentResults = componentSchemas.map(schema => {
82
25
  try {
83
- const component = createUiBuilderComponent(context, schema);
26
+ const component = createUiBuilderComponent(context, schema, dataSchema);
84
27
  return { resultType: 'SUCCESS', component };
85
28
  } catch (e) {
86
29
  printer.debug(`Failure caught processing ${schema.name}`);
@@ -95,9 +38,23 @@ export function generateUiBuilderComponents(context: $TSContext, componentSchema
95
38
  )}`,
96
39
  );
97
40
  return componentResults;
98
- }
41
+ };
99
42
 
100
- export function generateUiBuilderThemes(context: $TSContext, themeSchemas: any[]) {
43
+ /**
44
+ * Returns instances of StudioTheme from theme schemas
45
+ */
46
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
+ export const generateUiBuilderThemes = (context: $TSContext, themeSchemas: any[]): ({
48
+ resultType: string;
49
+ theme: StudioTheme;
50
+ schemaName?: undefined;
51
+ error?: undefined;
52
+ } | {
53
+ resultType: string;
54
+ schemaName: string;
55
+ error: Error;
56
+ theme?: undefined;
57
+ })[] => {
101
58
  const themeResults = themeSchemas.map(schema => {
102
59
  try {
103
60
  const theme = createUiBuilderTheme(context, schema);
@@ -113,4 +70,4 @@ export function generateUiBuilderThemes(context: $TSContext, themeSchemas: any[]
113
70
  `Generated ${themeResults.filter(result => result.resultType === 'SUCCESS').length} themes in ${getUiBuilderComponentsPath(context)}`,
114
71
  );
115
72
  return themeResults;
116
- }
73
+ };
package/src/index.ts CHANGED
@@ -1,16 +1,26 @@
1
1
  import { $TSContext } from 'amplify-cli-core';
2
2
  import path from 'path';
3
3
 
4
- export async function executeAmplifyCommand(context: $TSContext, cmd: string) {
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> => {
5
10
  const commandsDirPath = path.normalize(path.join(__dirname, 'commands'));
6
- const commandPath = path.join(commandsDirPath, cmd ? cmd : context.input.command);
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
7
13
  const commandModule = require(commandPath);
8
14
  await commandModule.run(context);
9
- }
15
+ };
10
16
 
11
- export async function handleAmplifyEvent(context: $TSContext, { event }: { event: string }) {
17
+ /**
18
+ * runs event based command
19
+ */
20
+ export const handleAmplifyEvent = async (context: $TSContext, { event }: { event: string }): Promise<void> => {
12
21
  const eventHandlersDirPath = path.normalize(path.join(__dirname, 'event-handlers'));
13
22
  const eventHandlerPath = path.join(eventHandlersDirPath, `handle-${event}`);
23
+ // eslint-disable-next-line import/no-dynamic-require, global-require, @typescript-eslint/no-var-requires
14
24
  const eventHandlerModule = require(eventHandlerPath);
15
25
  await eventHandlerModule.run(context);
16
- }
26
+ };