@aws-amplify/amplify-util-uibuilder 1.1.4 → 1.2.0-geo.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 +11 -0
- package/lib/commands/cloneComponentsFromEnv.d.ts +3 -0
- package/lib/commands/cloneComponentsFromEnv.d.ts.map +1 -0
- package/lib/commands/cloneComponentsFromEnv.js +68 -0
- package/lib/commands/cloneComponentsFromEnv.js.map +1 -0
- package/lib/commands/generateComponents.d.ts +3 -0
- package/lib/commands/generateComponents.d.ts.map +1 -0
- package/lib/commands/generateComponents.js +50 -0
- package/lib/commands/generateComponents.js.map +1 -0
- package/lib/commands/help.d.ts +2 -0
- package/lib/commands/help.d.ts.map +1 -0
- package/lib/commands/help.js +9 -0
- package/lib/commands/help.js.map +1 -0
- package/lib/commands/utils/createUiBuilderComponent.d.ts +5 -0
- package/lib/commands/utils/createUiBuilderComponent.d.ts.map +1 -0
- package/lib/commands/utils/createUiBuilderComponent.js +64 -0
- package/lib/commands/utils/createUiBuilderComponent.js.map +1 -0
- package/lib/commands/utils/extractArgs.d.ts +11 -0
- package/lib/commands/utils/extractArgs.d.ts.map +1 -0
- package/lib/commands/utils/extractArgs.js +26 -0
- package/lib/commands/utils/extractArgs.js.map +1 -0
- package/lib/commands/utils/getUiBuilderComponentsPath.d.ts +3 -0
- package/lib/commands/utils/getUiBuilderComponentsPath.d.ts.map +1 -0
- package/lib/commands/utils/getUiBuilderComponentsPath.js +20 -0
- package/lib/commands/utils/getUiBuilderComponentsPath.js.map +1 -0
- package/lib/commands/utils/notifyMissingPackages.d.ts +3 -0
- package/lib/commands/utils/notifyMissingPackages.d.ts.map +1 -0
- package/lib/commands/utils/notifyMissingPackages.js +45 -0
- package/lib/commands/utils/notifyMissingPackages.js.map +1 -0
- package/lib/commands/utils/shouldRenderComponents.d.ts +3 -0
- package/lib/commands/utils/shouldRenderComponents.d.ts.map +1 -0
- package/lib/commands/utils/shouldRenderComponents.js +34 -0
- package/lib/commands/utils/shouldRenderComponents.js.map +1 -0
- package/lib/commands/utils/syncAmplifyUiBuilderComponents.d.ts +31 -0
- package/lib/commands/utils/syncAmplifyUiBuilderComponents.d.ts.map +1 -0
- package/lib/commands/utils/syncAmplifyUiBuilderComponents.js +116 -0
- package/lib/commands/utils/syncAmplifyUiBuilderComponents.js.map +1 -0
- package/lib/commands/version.d.ts +2 -0
- package/lib/commands/version.d.ts.map +1 -0
- package/lib/commands/version.js +32 -0
- package/lib/commands/version.js.map +1 -0
- package/lib/event-handlers/handle-PostEnvAdd.d.ts +3 -0
- package/lib/event-handlers/handle-PostEnvAdd.d.ts.map +1 -0
- package/lib/event-handlers/handle-PostEnvAdd.js +17 -0
- package/lib/event-handlers/handle-PostEnvAdd.js.map +1 -0
- package/lib/event-handlers/handle-PostPull.d.ts +3 -0
- package/lib/event-handlers/handle-PostPull.d.ts.map +1 -0
- package/lib/event-handlers/handle-PostPull.js +14 -0
- package/lib/event-handlers/handle-PostPull.js.map +1 -0
- package/lib/index.d.ts +6 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +22 -0
- package/lib/index.js.map +1 -0
- package/package.json +37 -7
- package/src/__tests__/cloneComponentsFromEnv.test.ts +49 -0
- package/src/__tests__/createUiBuilderComponent.test.ts +60 -0
- package/src/__tests__/generateComponents.test.ts +50 -0
- package/src/__tests__/handleEvents.test.ts +21 -0
- package/src/__tests__/help.test.ts +10 -0
- package/src/__tests__/mock.json +1 -0
- package/src/__tests__/notifyMissingPackages.test.ts +89 -0
- package/src/__tests__/package.json +3 -0
- package/{commands/utils/__tests__/shouldRenderComponents.test.js → src/__tests__/shouldRenderComponents.test.ts} +3 -2
- package/src/__tests__/syncAmplifyUiComponents.test.ts +150 -0
- package/src/__tests__/version.test.ts +10 -0
- package/src/commands/cloneComponentsFromEnv.ts +72 -0
- package/{commands/generateComponents.js → src/commands/generateComponents.ts} +13 -15
- package/src/commands/help.ts +5 -0
- package/src/commands/utils/createUiBuilderComponent.ts +75 -0
- package/{commands/utils/extractArgs.js → src/commands/utils/extractArgs.ts} +3 -5
- package/{commands/utils/getUiBuilderComponentsPath.js → src/commands/utils/getUiBuilderComponentsPath.ts} +5 -8
- package/src/commands/utils/notifyMissingPackages.ts +40 -0
- package/src/commands/utils/shouldRenderComponents.ts +34 -0
- package/{commands/utils/syncAmplifyUiBuilderComponents.js → src/commands/utils/syncAmplifyUiBuilderComponents.ts} +37 -43
- package/src/commands/version.ts +6 -0
- package/{event-handlers/handle-PostEnvAdd.js → src/event-handlers/handle-PostEnvAdd.ts} +4 -7
- package/{event-handlers/handle-PostPull.js → src/event-handlers/handle-PostPull.ts} +4 -7
- package/{index.js → src/index.ts} +6 -10
- package/tsconfig.json +9 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/commands/cloneComponentsFromEnv.js +0 -79
- package/commands/help.js +0 -7
- package/commands/utils/__tests__/createUiComponents.test.js +0 -46
- package/commands/utils/__tests__/syncAmplifyUiComponents.test.js +0 -67
- package/commands/utils/createUiBuilderComponent.js +0 -85
- package/commands/utils/logger.js +0 -24
- package/commands/utils/mockUiBuilderData.js +0 -149
- package/commands/utils/notifyMissingPackages.js +0 -27
- package/commands/utils/shouldRenderComponents.js +0 -38
- package/commands/version.js +0 -10
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { $TSContext } from 'amplify-cli-core';
|
|
2
|
+
import {
|
|
3
|
+
generateUiBuilderComponents,
|
|
4
|
+
getEnvName,
|
|
5
|
+
getAppId,
|
|
6
|
+
listUiBuilderComponents,
|
|
7
|
+
listUiBuilderThemes,
|
|
8
|
+
getAmplifyUIBuilderService,
|
|
9
|
+
resolveAppId,
|
|
10
|
+
generateUiBuilderThemes,
|
|
11
|
+
} from '../commands/utils/syncAmplifyUiBuilderComponents';
|
|
12
|
+
import aws from 'aws-sdk';
|
|
13
|
+
import * as CLICore from 'amplify-cli-core';
|
|
14
|
+
import * as createUiBuilderComponentDependency from '../commands/utils/createUiBuilderComponent';
|
|
15
|
+
const aws_mock = aws as any;
|
|
16
|
+
const createUiBuilderComponentDependency_mock = createUiBuilderComponentDependency as any;
|
|
17
|
+
describe('should sync amplify ui builder components', () => {
|
|
18
|
+
let context: $TSContext | any;
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
CLICore.FeatureFlags.getBoolean = () => false;
|
|
21
|
+
CLICore.FeatureFlags.getNumber = () => 0;
|
|
22
|
+
context = {
|
|
23
|
+
exeInfo: {
|
|
24
|
+
projectConfig: {
|
|
25
|
+
javascript: {
|
|
26
|
+
config: {
|
|
27
|
+
SourceDir: 'src',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
amplify: {
|
|
33
|
+
invokePluginMethod: () => ({}),
|
|
34
|
+
},
|
|
35
|
+
parameters: {
|
|
36
|
+
argv: [],
|
|
37
|
+
},
|
|
38
|
+
input: {
|
|
39
|
+
options: {
|
|
40
|
+
appId: 'testAppId',
|
|
41
|
+
envName: 'testEnvName',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
aws_mock.AmplifyUIBuilder = jest.fn(() => ({
|
|
47
|
+
exportComponents: jest.fn(() => ({
|
|
48
|
+
promise: jest.fn(() => ({
|
|
49
|
+
entities: [
|
|
50
|
+
{
|
|
51
|
+
appId: 'd37nrm8rzt3oek',
|
|
52
|
+
bindingProperties: {},
|
|
53
|
+
componentType: 'Box',
|
|
54
|
+
environmentName: 'staging',
|
|
55
|
+
id: 's-s4mU579Ycf6JGHwhqT',
|
|
56
|
+
name: 'aawwdd',
|
|
57
|
+
overrides: {},
|
|
58
|
+
properties: {},
|
|
59
|
+
variants: [],
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
})),
|
|
63
|
+
})),
|
|
64
|
+
exportThemes: jest.fn(() => ({
|
|
65
|
+
promise: jest.fn(() => ({
|
|
66
|
+
entities: [{}],
|
|
67
|
+
})),
|
|
68
|
+
})),
|
|
69
|
+
}));
|
|
70
|
+
|
|
71
|
+
createUiBuilderComponentDependency_mock.createUiBuilderComponent = jest.fn();
|
|
72
|
+
createUiBuilderComponentDependency_mock.createUiBuilderTheme = jest.fn();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('pulls components from aws-sdk and passes them to createUiBuilderComponent', () => {
|
|
76
|
+
generateUiBuilderComponents(context, []);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('does not throw an error when createUiBuilderComponent fails', () => {
|
|
80
|
+
createUiBuilderComponentDependency_mock.createUiBuilderComponent = jest.fn(() => {
|
|
81
|
+
throw new Error('ahhh!');
|
|
82
|
+
});
|
|
83
|
+
expect(async () => generateUiBuilderComponents(context, [])).not.toThrow();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('does not throw an error when createUiBuilderThemes fails', () => {
|
|
87
|
+
createUiBuilderComponentDependency_mock.createUiBuilderComponent = jest.fn(() => {
|
|
88
|
+
throw new Error('ahhh!');
|
|
89
|
+
});
|
|
90
|
+
expect(async () => generateUiBuilderThemes(context, [])).not.toThrow();
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('can getAmplifyUIBuilderService', async () => {
|
|
94
|
+
process.env.UI_BUILDER_ENDPOINT = 'https://mock-endpoint.com';
|
|
95
|
+
process.env.UI_BUILDER_REGION = 'mock-region';
|
|
96
|
+
const service = await getAmplifyUIBuilderService(context, 'testEnv', 'testAppId');
|
|
97
|
+
expect(Object.keys(service)).toContain('exportComponents');
|
|
98
|
+
expect(Object.keys(service)).toContain('exportThemes');
|
|
99
|
+
});
|
|
100
|
+
it('can listUiBuilderThemes', async () => {
|
|
101
|
+
const themes = await listUiBuilderThemes(context, 'testEnv');
|
|
102
|
+
expect(themes.entities).toHaveLength(1);
|
|
103
|
+
});
|
|
104
|
+
it('can listUiBuilderComponents', async () => {
|
|
105
|
+
const components = await listUiBuilderComponents(context, 'testEnv');
|
|
106
|
+
expect(components.entities).toHaveLength(1);
|
|
107
|
+
});
|
|
108
|
+
it('can getAppId', async () => {
|
|
109
|
+
const appId = await getAppId(context);
|
|
110
|
+
expect(appId).toBe('testAppId');
|
|
111
|
+
});
|
|
112
|
+
it('can getEnvName', () => {
|
|
113
|
+
const envName = getEnvName(context);
|
|
114
|
+
expect(envName).toBe('testEnvName');
|
|
115
|
+
});
|
|
116
|
+
it('can resolveAppId', async () => {
|
|
117
|
+
context.amplify.invokePluginMethod = () => 'testAppId';
|
|
118
|
+
const appId = await resolveAppId(context);
|
|
119
|
+
expect(appId).toBe('testAppId');
|
|
120
|
+
});
|
|
121
|
+
it('can throw on getAppId', async () => {
|
|
122
|
+
context.input.options.appId = null;
|
|
123
|
+
context.amplify.invokePluginMethod = () => null;
|
|
124
|
+
expect(async () => await getAppId(context)).rejects.toThrowError();
|
|
125
|
+
});
|
|
126
|
+
it('can generate ui builder components', async () => {
|
|
127
|
+
createUiBuilderComponentDependency_mock.createUiBuilderComponent = jest.fn().mockImplementation(() => ({}));
|
|
128
|
+
const components = generateUiBuilderComponents(context, [{}, {}]);
|
|
129
|
+
expect(components.every(component => component.resultType === 'SUCCESS')).toBeTruthy();
|
|
130
|
+
});
|
|
131
|
+
it('can handle failed generation generate ui builder components', async () => {
|
|
132
|
+
createUiBuilderComponentDependency_mock.createUiBuilderComponent = jest.fn().mockImplementation(() => {
|
|
133
|
+
throw new Error('ahh!');
|
|
134
|
+
});
|
|
135
|
+
const components = generateUiBuilderComponents(context, [{}, {}]);
|
|
136
|
+
expect(components.every(component => component.resultType === 'FAILURE')).toBeTruthy();
|
|
137
|
+
});
|
|
138
|
+
it('can generate ui builder themes', async () => {
|
|
139
|
+
createUiBuilderComponentDependency_mock.createUiBuilderTheme = jest.fn().mockImplementation(() => ({}));
|
|
140
|
+
const themes = generateUiBuilderThemes(context, [{}, {}]);
|
|
141
|
+
expect(themes.every(theme => theme.resultType === 'SUCCESS')).toBeTruthy();
|
|
142
|
+
});
|
|
143
|
+
it('can handle failed generation generate ui builder themes', async () => {
|
|
144
|
+
createUiBuilderComponentDependency_mock.createUiBuilderTheme = jest.fn().mockImplementation(() => {
|
|
145
|
+
throw new Error('ahh!');
|
|
146
|
+
});
|
|
147
|
+
const themes = generateUiBuilderThemes(context, [{}, {}]);
|
|
148
|
+
expect(themes.every(theme => theme.resultType === 'FAILURE')).toBeTruthy();
|
|
149
|
+
});
|
|
150
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { printer } from 'amplify-prompts';
|
|
2
|
+
import { run } from '../commands/version';
|
|
3
|
+
jest.mock('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
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import aws from 'aws-sdk';
|
|
2
|
+
import { extractArgs } from './utils/extractArgs';
|
|
3
|
+
import { listUiBuilderComponents } from './utils/syncAmplifyUiBuilderComponents';
|
|
4
|
+
import { printer } from 'amplify-prompts';
|
|
5
|
+
import { $TSAny, $TSContext } from 'amplify-cli-core';
|
|
6
|
+
|
|
7
|
+
export async function run(context: $TSContext) {
|
|
8
|
+
printer.debug('Running create components command in amplify-util-uibuilder');
|
|
9
|
+
const args = extractArgs(context);
|
|
10
|
+
const sourceEnvName = args.sourceEnvName ? args.sourceEnvName : context.exeInfo.sourceEnvName;
|
|
11
|
+
const newEnvName = args.newEnvName ? args.newEnvName : context.exeInfo.localEnvInfo.envName;
|
|
12
|
+
|
|
13
|
+
const existingComponents = await listUiBuilderComponents(context, sourceEnvName);
|
|
14
|
+
if (existingComponents.entities.length === 0) {
|
|
15
|
+
printer.debug(`${existingComponents.entities.length} components exist in source env. Skipping creation of local components.`);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const existingComponentsNewEnv = await listUiBuilderComponents(context, newEnvName);
|
|
19
|
+
|
|
20
|
+
if (existingComponentsNewEnv.entities.length > 0) {
|
|
21
|
+
printer.debug(
|
|
22
|
+
`${existingComponentsNewEnv.entities.length} components already exist in new env. Skipping creation of local components.`,
|
|
23
|
+
);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const environmentName = args.environmentName ?? context.exeInfo.localEnvInfo.envName;
|
|
28
|
+
const appId = args.appId ?? context.exeInfo.teamProviderInfo[environmentName].awscloudformation.AmplifyAppId;
|
|
29
|
+
const awsConfigInfo = (await context.amplify.invokePluginMethod(context, 'awscloudformation', undefined, 'loadConfigurationForEnv', [
|
|
30
|
+
context,
|
|
31
|
+
newEnvName,
|
|
32
|
+
appId,
|
|
33
|
+
])) as $TSAny;
|
|
34
|
+
|
|
35
|
+
if (process.env.UI_BUILDER_ENDPOINT) {
|
|
36
|
+
awsConfigInfo.endpoint = process.env.UI_BUILDER_ENDPOINT;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (process.env.UI_BUILDER_REGION) {
|
|
40
|
+
awsConfigInfo.region = process.env.UI_BUILDER_REGION;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const amplifyUIBuilder = new aws.AmplifyUIBuilder(awsConfigInfo);
|
|
44
|
+
const components = existingComponents.entities;
|
|
45
|
+
if (!components.length) {
|
|
46
|
+
printer.debug(`No UIBuilder components found in app ${appId} from env ${sourceEnvName}. Skipping component clone process.`);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const promises = components.map(async (component: any) => {
|
|
50
|
+
return await amplifyUIBuilder
|
|
51
|
+
.createComponent({
|
|
52
|
+
appId,
|
|
53
|
+
environmentName,
|
|
54
|
+
componentToCreate: {
|
|
55
|
+
bindingProperties: component.bindingProperties,
|
|
56
|
+
children: component.children,
|
|
57
|
+
componentType: component.componentType,
|
|
58
|
+
name: component.name,
|
|
59
|
+
overrides: component.overrides,
|
|
60
|
+
properties: component.properties,
|
|
61
|
+
sourceId: component.sourceId,
|
|
62
|
+
variants: component.variants,
|
|
63
|
+
},
|
|
64
|
+
})
|
|
65
|
+
.promise();
|
|
66
|
+
});
|
|
67
|
+
await Promise.all(promises);
|
|
68
|
+
|
|
69
|
+
printer.info(
|
|
70
|
+
`Successfully cloned ${components.length} UIBuilder components in app ${appId} from env ${sourceEnvName} to env ${newEnvName}.`,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { notifyMissingPackages } from './utils/notifyMissingPackages';
|
|
2
|
+
import { shouldRenderComponents } from './utils/shouldRenderComponents';
|
|
3
|
+
import {
|
|
4
4
|
listUiBuilderComponents,
|
|
5
5
|
listUiBuilderThemes,
|
|
6
6
|
generateUiBuilderComponents,
|
|
7
7
|
generateUiBuilderThemes,
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
} from './utils/syncAmplifyUiBuilderComponents';
|
|
9
|
+
import { generateAmplifyUiBuilderIndexFile } from './utils/createUiBuilderComponent';
|
|
10
|
+
import { printer } from 'amplify-prompts';
|
|
11
|
+
import ora from 'ora';
|
|
12
|
+
import { $TSContext } from 'amplify-cli-core';
|
|
13
|
+
|
|
14
|
+
export async function run(context: $TSContext) {
|
|
15
|
+
printer.debug('Running generate components command in amplify-util-uibuilder');
|
|
14
16
|
if (!(await shouldRenderComponents(context))) {
|
|
15
17
|
return;
|
|
16
18
|
}
|
|
@@ -18,7 +20,7 @@ async function run(context) {
|
|
|
18
20
|
try {
|
|
19
21
|
const [componentSchemas, themeSchemas] = await Promise.all([listUiBuilderComponents(context), listUiBuilderThemes(context)]);
|
|
20
22
|
if (componentSchemas.entities.length === 0 && themeSchemas.entities.length === 0) {
|
|
21
|
-
|
|
23
|
+
printer.debug('Skipping UI component generation since none are found.');
|
|
22
24
|
return;
|
|
23
25
|
}
|
|
24
26
|
|
|
@@ -42,13 +44,9 @@ async function run(context) {
|
|
|
42
44
|
spinner.succeed('Synced UI components.');
|
|
43
45
|
}
|
|
44
46
|
} catch (e) {
|
|
45
|
-
|
|
47
|
+
printer.debug(e);
|
|
46
48
|
spinner.fail('Failed to sync UI components');
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
notifyMissingPackages(context);
|
|
50
52
|
}
|
|
51
|
-
|
|
52
|
-
module.exports = {
|
|
53
|
-
run,
|
|
54
|
-
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { StudioTemplateRendererManager, StudioTemplateRendererFactory, StudioComponent } from '@aws-amplify/codegen-ui';
|
|
2
|
+
import {
|
|
3
|
+
AmplifyRenderer,
|
|
4
|
+
ReactThemeStudioTemplateRenderer,
|
|
5
|
+
ReactIndexStudioTemplateRenderer,
|
|
6
|
+
ModuleKind,
|
|
7
|
+
ScriptTarget,
|
|
8
|
+
ScriptKind,
|
|
9
|
+
} from '@aws-amplify/codegen-ui-react';
|
|
10
|
+
import { getUiBuilderComponentsPath } from './getUiBuilderComponentsPath';
|
|
11
|
+
import { printer } from 'amplify-prompts';
|
|
12
|
+
import { $TSContext } from 'amplify-cli-core';
|
|
13
|
+
const config = {
|
|
14
|
+
module: ModuleKind.ES2020,
|
|
15
|
+
target: ScriptTarget.ES2020,
|
|
16
|
+
script: ScriptKind.JSX,
|
|
17
|
+
renderTypeDeclarations: true,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const createUiBuilderComponent = (context: $TSContext, schema: any) => {
|
|
21
|
+
const uiBuilderComponentsPath = getUiBuilderComponentsPath(context);
|
|
22
|
+
const rendererFactory = new StudioTemplateRendererFactory((component: StudioComponent) => new AmplifyRenderer(component, config));
|
|
23
|
+
|
|
24
|
+
const outputPathDir = uiBuilderComponentsPath;
|
|
25
|
+
const outputConfig = {
|
|
26
|
+
outputPathDir,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const rendererManager = new StudioTemplateRendererManager(rendererFactory, outputConfig);
|
|
30
|
+
|
|
31
|
+
rendererManager.renderSchemaToTemplate(schema);
|
|
32
|
+
return schema;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const createUiBuilderTheme = (context: $TSContext, schema: any) => {
|
|
36
|
+
const uiBuilderComponentsPath = getUiBuilderComponentsPath(context);
|
|
37
|
+
const rendererFactory = new StudioTemplateRendererFactory((component: any) => new ReactThemeStudioTemplateRenderer(component, config));
|
|
38
|
+
|
|
39
|
+
const outputPathDir = uiBuilderComponentsPath;
|
|
40
|
+
const outputConfig = {
|
|
41
|
+
outputPathDir,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const rendererManager = new StudioTemplateRendererManager(rendererFactory, outputConfig);
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
rendererManager.renderSchemaToTemplate(schema);
|
|
48
|
+
return schema;
|
|
49
|
+
} catch (e) {
|
|
50
|
+
printer.debug(e);
|
|
51
|
+
printer.debug('Skipping invalid theme with schema');
|
|
52
|
+
printer.debug(JSON.stringify(schema, null, 2));
|
|
53
|
+
throw e;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const generateAmplifyUiBuilderIndexFile = (context: $TSContext, schemas: any[]) => {
|
|
58
|
+
const uiBuilderComponentsPath = getUiBuilderComponentsPath(context);
|
|
59
|
+
const rendererFactory = new StudioTemplateRendererFactory((component: any) => new ReactIndexStudioTemplateRenderer(component, config));
|
|
60
|
+
|
|
61
|
+
const outputPathDir = uiBuilderComponentsPath;
|
|
62
|
+
const outputConfig = {
|
|
63
|
+
outputPathDir,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const rendererManager = new StudioTemplateRendererManager(rendererFactory, outputConfig);
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
return rendererManager.renderSchemaToTemplate(schemas);
|
|
70
|
+
} catch (e) {
|
|
71
|
+
printer.debug(e);
|
|
72
|
+
printer.debug('Failed to generate component index file');
|
|
73
|
+
throw e;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { $TSContext } from 'amplify-cli-core';
|
|
2
|
+
|
|
3
|
+
export const extractArgs = (context: $TSContext) => {
|
|
2
4
|
if (!context.input.options) {
|
|
3
5
|
context.input.options = {};
|
|
4
6
|
}
|
|
@@ -21,7 +23,3 @@ const extractArgs = context => {
|
|
|
21
23
|
newEnvName,
|
|
22
24
|
};
|
|
23
25
|
};
|
|
24
|
-
|
|
25
|
-
module.exports = {
|
|
26
|
-
extractArgs,
|
|
27
|
-
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import { extractArgs } from './extractArgs';
|
|
4
|
+
import { $TSContext } from 'amplify-cli-core';
|
|
4
5
|
|
|
5
|
-
const getUiBuilderComponentsPath = context => {
|
|
6
|
+
export const getUiBuilderComponentsPath = (context: $TSContext) => {
|
|
6
7
|
const args = extractArgs(context);
|
|
7
8
|
const srcDir = args.srcDir ? args.srcDir : context.exeInfo.projectConfig.javascript.config.SourceDir;
|
|
8
9
|
const uiBuilderComponentsPath = path.resolve(path.join('.', srcDir, 'ui-components'));
|
|
@@ -13,7 +14,3 @@ const getUiBuilderComponentsPath = context => {
|
|
|
13
14
|
|
|
14
15
|
return uiBuilderComponentsPath;
|
|
15
16
|
};
|
|
16
|
-
|
|
17
|
-
module.exports = {
|
|
18
|
-
getUiBuilderComponentsPath,
|
|
19
|
-
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { pathManager, JSONUtilities, $TSContext, $TSAny } from 'amplify-cli-core';
|
|
2
|
+
import { printer } from 'amplify-prompts';
|
|
3
|
+
import fs from 'fs-extra';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { extractArgs } from './extractArgs';
|
|
6
|
+
const REQUIRED_PACKAGES: { [key: string]: string } = { '@aws-amplify/ui-react': '1.2.0', 'aws-amplify': '*' };
|
|
7
|
+
|
|
8
|
+
export const notifyMissingPackages = (context: $TSContext) => {
|
|
9
|
+
const args = extractArgs(context);
|
|
10
|
+
const localEnvFilePath = args.localEnvFilePath ?? pathManager.getLocalEnvFilePath();
|
|
11
|
+
if (!fs.existsSync(localEnvFilePath)) {
|
|
12
|
+
printer.debug('localEnvFilePath could not be determined - skipping dependency notification.');
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const localEnvJson = JSONUtilities.readJson(localEnvFilePath);
|
|
16
|
+
const packageJsonPath = path.join((localEnvJson as $TSAny).projectPath, 'package.json');
|
|
17
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
18
|
+
printer.debug('package.json file not found - skipping dependency notification.');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const packageJson = JSONUtilities.readJson(packageJsonPath) as { dependencies: { [key: string]: string } };
|
|
22
|
+
Object.keys(REQUIRED_PACKAGES).forEach(packageName => {
|
|
23
|
+
const packageIsInstalled = Object.keys(packageJson.dependencies).includes(packageName);
|
|
24
|
+
if (!packageIsInstalled) {
|
|
25
|
+
printer.warn(`UIBuilder components required "${packageName}" that is not in your package.json. Run \`npm install ${packageName}\``);
|
|
26
|
+
} else if (!packageVersionMatches(REQUIRED_PACKAGES[packageName], packageJson.dependencies[packageName])) {
|
|
27
|
+
printer.warn(
|
|
28
|
+
`UIBuilder components requires version "${REQUIRED_PACKAGES[packageName]}" of "${packageName}". You currently are on version "${packageJson.dependencies[packageName]}".`,
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const packageVersionMatches = (requiredVersion: string, existingVersion: string) => {
|
|
35
|
+
if (requiredVersion === '*') {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return requiredVersion === existingVersion;
|
|
40
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { $TSContext } from 'amplify-cli-core';
|
|
2
|
+
import { printer } from 'amplify-prompts';
|
|
3
|
+
export async function shouldRenderComponents(context: $TSContext) {
|
|
4
|
+
if (process.env.FORCE_RENDER) {
|
|
5
|
+
printer.debug('Forcing component render since environment variable flag is set.');
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
if (context?.input?.options?.['no-codegen']) {
|
|
9
|
+
printer.debug('Not pulling components because --no-codegen flag is set');
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (!context?.exeInfo?.projectConfig) {
|
|
14
|
+
printer.debug('Not pulling components because there is no projectConfig set for this project');
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!context.exeInfo.projectConfig.providers.includes('awscloudformation')) {
|
|
19
|
+
printer.debug('Not pulling components because there is no "awscloudformation" provider');
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (context.exeInfo.projectConfig.frontend !== 'javascript') {
|
|
24
|
+
printer.debug('Not pulling components because this project is not configured as a javascript frontend');
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (context.exeInfo.projectConfig['javascript'].framework !== 'react') {
|
|
29
|
+
printer.debug('Not pulling components because this project is not configured with the "react" framework');
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
@@ -1,26 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const getEnvName = (context, envName) => {
|
|
1
|
+
import aws from 'aws-sdk';
|
|
2
|
+
import { printer } from 'amplify-prompts';
|
|
3
|
+
import { createUiBuilderComponent, createUiBuilderTheme } from './createUiBuilderComponent';
|
|
4
|
+
import { getUiBuilderComponentsPath } from './getUiBuilderComponentsPath';
|
|
5
|
+
import { extractArgs } from './extractArgs';
|
|
6
|
+
import { $TSAny, $TSContext } from 'amplify-cli-core';
|
|
7
|
+
export const getEnvName = (context: $TSContext, envName?: string) => {
|
|
9
8
|
const args = extractArgs(context);
|
|
10
9
|
return envName ? envName : args.environmentName ? args.environmentName : context.exeInfo.localEnvInfo.envName;
|
|
11
10
|
};
|
|
12
11
|
|
|
13
|
-
const
|
|
14
|
-
return
|
|
12
|
+
export const resolveAppId = async (context: $TSContext) => {
|
|
13
|
+
return await context.amplify.invokePluginMethod(context, 'awscloudformation', undefined, 'resolveAppId', [context]);
|
|
15
14
|
};
|
|
16
15
|
|
|
17
|
-
async
|
|
18
|
-
|
|
19
|
-
|
|
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
|
+
);
|
|
20
23
|
}
|
|
24
|
+
return appId;
|
|
25
|
+
};
|
|
21
26
|
|
|
27
|
+
export async function listUiBuilderComponents(context: $TSContext, envName?: string) {
|
|
22
28
|
const environmentName = getEnvName(context, envName);
|
|
23
|
-
const appId = getAppId(context
|
|
29
|
+
const appId = await getAppId(context);
|
|
24
30
|
|
|
25
31
|
try {
|
|
26
32
|
const amplifyUIBuilder = await getAmplifyUIBuilderService(context, environmentName, appId);
|
|
@@ -30,21 +36,17 @@ async function listUiBuilderComponents(context, envName) {
|
|
|
30
36
|
environmentName,
|
|
31
37
|
})
|
|
32
38
|
.promise();
|
|
33
|
-
|
|
39
|
+
printer.debug(JSON.stringify(uiBuilderComponents, null, 2));
|
|
34
40
|
return uiBuilderComponents;
|
|
35
41
|
} catch (e) {
|
|
36
|
-
|
|
42
|
+
printer.debug(e);
|
|
37
43
|
throw e;
|
|
38
44
|
}
|
|
39
45
|
}
|
|
40
46
|
|
|
41
|
-
async function listUiBuilderThemes(context, envName) {
|
|
42
|
-
if (process.env.MOCK_UI_BUILDER_BACKEND) {
|
|
43
|
-
return mockUiBuilderThemes;
|
|
44
|
-
}
|
|
45
|
-
|
|
47
|
+
export async function listUiBuilderThemes(context: $TSContext, envName?: string) {
|
|
46
48
|
const environmentName = getEnvName(context, envName);
|
|
47
|
-
const appId = getAppId(context
|
|
49
|
+
const appId = await getAppId(context);
|
|
48
50
|
|
|
49
51
|
try {
|
|
50
52
|
const amplifyUIBuilder = await getAmplifyUIBuilderService(context, environmentName, appId);
|
|
@@ -54,27 +56,27 @@ async function listUiBuilderThemes(context, envName) {
|
|
|
54
56
|
environmentName,
|
|
55
57
|
})
|
|
56
58
|
.promise();
|
|
57
|
-
|
|
59
|
+
printer.debug(JSON.stringify(uiBuilderThemes, null, 2));
|
|
58
60
|
return uiBuilderThemes;
|
|
59
61
|
} catch (e) {
|
|
60
|
-
|
|
62
|
+
printer.debug(e);
|
|
61
63
|
throw e;
|
|
62
64
|
}
|
|
63
65
|
}
|
|
64
66
|
|
|
65
|
-
function generateUiBuilderComponents(context, componentSchemas) {
|
|
67
|
+
export function generateUiBuilderComponents(context: $TSContext, componentSchemas: any[]) {
|
|
66
68
|
const componentResults = componentSchemas.map(schema => {
|
|
67
69
|
try {
|
|
68
70
|
const component = createUiBuilderComponent(context, schema);
|
|
69
71
|
return { resultType: 'SUCCESS', component };
|
|
70
72
|
} catch (e) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
printer.debug(`Failure caught processing ${schema.name}`);
|
|
74
|
+
printer.debug(e);
|
|
73
75
|
return { resultType: 'FAILURE', schemaName: schema.name, error: e };
|
|
74
76
|
}
|
|
75
77
|
});
|
|
76
78
|
|
|
77
|
-
|
|
79
|
+
printer.debug(
|
|
78
80
|
`Generated ${componentResults.filter(result => result.resultType === 'SUCCESS').length} components in ${getUiBuilderComponentsPath(
|
|
79
81
|
context,
|
|
80
82
|
)}`,
|
|
@@ -82,30 +84,30 @@ function generateUiBuilderComponents(context, componentSchemas) {
|
|
|
82
84
|
return componentResults;
|
|
83
85
|
}
|
|
84
86
|
|
|
85
|
-
function generateUiBuilderThemes(context, themeSchemas) {
|
|
87
|
+
export function generateUiBuilderThemes(context: $TSContext, themeSchemas: any[]) {
|
|
86
88
|
const themeResults = themeSchemas.map(schema => {
|
|
87
89
|
try {
|
|
88
90
|
const theme = createUiBuilderTheme(context, schema);
|
|
89
91
|
return { resultType: 'SUCCESS', theme };
|
|
90
92
|
} catch (e) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
+
printer.debug(`Failure caught processing ${schema.name}`);
|
|
94
|
+
printer.debug(e);
|
|
93
95
|
return { resultType: 'FAILURE', schemaName: schema.name, error: e };
|
|
94
96
|
}
|
|
95
97
|
});
|
|
96
98
|
|
|
97
|
-
|
|
99
|
+
printer.debug(
|
|
98
100
|
`Generated ${themeResults.filter(result => result.resultType === 'SUCCESS').length} themes in ${getUiBuilderComponentsPath(context)}`,
|
|
99
101
|
);
|
|
100
102
|
return themeResults;
|
|
101
103
|
}
|
|
102
104
|
|
|
103
|
-
const getAmplifyUIBuilderService = async (context, environmentName, appId) => {
|
|
104
|
-
const awsConfigInfo = await context.amplify.invokePluginMethod(context, 'awscloudformation', undefined, 'loadConfigurationForEnv', [
|
|
105
|
+
export const getAmplifyUIBuilderService = async (context: $TSContext, environmentName: string, appId: string) => {
|
|
106
|
+
const awsConfigInfo = (await context.amplify.invokePluginMethod(context, 'awscloudformation', undefined, 'loadConfigurationForEnv', [
|
|
105
107
|
context,
|
|
106
108
|
environmentName,
|
|
107
109
|
appId,
|
|
108
|
-
]);
|
|
110
|
+
])) as $TSAny;
|
|
109
111
|
|
|
110
112
|
if (process.env.UI_BUILDER_ENDPOINT) {
|
|
111
113
|
awsConfigInfo.endpoint = process.env.UI_BUILDER_ENDPOINT;
|
|
@@ -117,11 +119,3 @@ const getAmplifyUIBuilderService = async (context, environmentName, appId) => {
|
|
|
117
119
|
|
|
118
120
|
return new aws.AmplifyUIBuilder(awsConfigInfo);
|
|
119
121
|
};
|
|
120
|
-
|
|
121
|
-
module.exports = {
|
|
122
|
-
getAmplifyUIBuilderService,
|
|
123
|
-
generateUiBuilderComponents,
|
|
124
|
-
generateUiBuilderThemes,
|
|
125
|
-
listUiBuilderComponents,
|
|
126
|
-
listUiBuilderThemes,
|
|
127
|
-
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import { $TSContext } from 'amplify-cli-core';
|
|
2
|
+
import { printer } from 'amplify-prompts';
|
|
2
3
|
|
|
3
|
-
async function run(context) {
|
|
4
|
+
export async function run(context: $TSContext) {
|
|
4
5
|
try {
|
|
5
6
|
await context.amplify.invokePluginMethod(context, 'ui-builder', undefined, 'executeAmplifyCommand', [
|
|
6
7
|
context,
|
|
@@ -8,10 +9,6 @@ async function run(context) {
|
|
|
8
9
|
]);
|
|
9
10
|
} catch (e) {
|
|
10
11
|
// Swallow all errors from the uibuilder plugin
|
|
11
|
-
|
|
12
|
+
printer.debug(e);
|
|
12
13
|
}
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
-
module.exports = {
|
|
16
|
-
run,
|
|
17
|
-
};
|