@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.
- package/CHANGELOG.md +92 -1
- package/lib/clients/amplify-studio-client.d.ts +17 -0
- package/lib/clients/amplify-studio-client.d.ts.map +1 -0
- package/lib/clients/amplify-studio-client.js +145 -0
- package/lib/clients/amplify-studio-client.js.map +1 -0
- package/lib/clients/index.d.ts +2 -0
- package/lib/clients/index.d.ts.map +1 -0
- package/lib/clients/index.js +9 -0
- package/lib/clients/index.js.map +1 -0
- package/lib/commands/cloneComponentsFromEnv.d.ts +1 -1
- package/lib/commands/cloneComponentsFromEnv.d.ts.map +1 -1
- package/lib/commands/cloneComponentsFromEnv.js +15 -31
- package/lib/commands/cloneComponentsFromEnv.js.map +1 -1
- package/lib/commands/generateComponents.d.ts.map +1 -1
- package/lib/commands/generateComponents.js +14 -12
- package/lib/commands/generateComponents.js.map +1 -1
- package/lib/commands/utils/{createUiBuilderComponent.d.ts → codegenResources.d.ts} +5 -3
- package/lib/commands/utils/codegenResources.d.ts.map +1 -0
- package/lib/commands/utils/{createUiBuilderComponent.js → codegenResources.js} +26 -4
- package/lib/commands/utils/codegenResources.js.map +1 -0
- package/lib/commands/utils/environmentHelpers.d.ts +5 -0
- package/lib/commands/utils/environmentHelpers.d.ts.map +1 -0
- package/lib/commands/utils/environmentHelpers.js +25 -0
- package/lib/commands/utils/environmentHelpers.js.map +1 -0
- package/lib/commands/utils/index.d.ts +8 -0
- package/lib/commands/utils/index.d.ts.map +1 -0
- package/lib/commands/utils/index.js +20 -0
- package/lib/commands/utils/index.js.map +1 -0
- package/lib/commands/utils/syncAmplifyUiBuilderComponents.d.ts +9 -18
- package/lib/commands/utils/syncAmplifyUiBuilderComponents.d.ts.map +1 -1
- package/lib/commands/utils/syncAmplifyUiBuilderComponents.js +8 -80
- package/lib/commands/utils/syncAmplifyUiBuilderComponents.js.map +1 -1
- package/lib/index.d.ts +3 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +5 -5
- package/lib/index.js.map +1 -1
- package/package.json +15 -8
- package/src/__tests__/cloneComponentsFromEnv.test.ts +33 -26
- package/src/__tests__/createUiBuilderComponent.test.ts +14 -13
- package/src/__tests__/generateComponents.test.ts +40 -30
- package/src/__tests__/getAmplifyDataSchema.test.ts +102 -0
- package/src/__tests__/syncAmplifyUiComponents.test.ts +55 -33
- package/src/clients/amplify-studio-client.ts +161 -0
- package/src/clients/index.ts +1 -0
- package/src/commands/cloneComponentsFromEnv.ts +26 -29
- package/src/commands/generateComponents.ts +19 -12
- package/src/commands/utils/{createUiBuilderComponent.ts → codegenResources.ts} +39 -11
- package/src/commands/utils/environmentHelpers.ts +32 -0
- package/src/commands/utils/index.ts +7 -0
- package/src/commands/utils/syncAmplifyUiBuilderComponents.ts +38 -81
- package/src/index.ts +15 -5
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/commands/utils/amplifyUiBuilderService.d.ts +0 -5
- package/lib/commands/utils/amplifyUiBuilderService.d.ts.map +0 -1
- package/lib/commands/utils/amplifyUiBuilderService.js +0 -20
- package/lib/commands/utils/amplifyUiBuilderService.js.map +0 -1
- package/lib/commands/utils/createUiBuilderComponent.d.ts.map +0 -1
- package/lib/commands/utils/createUiBuilderComponent.js.map +0 -1
- 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 {
|
|
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)
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
+
};
|