cli/new: more strict input separation and types
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
collectPortableTemplateParams,
|
||||
collectPortableTemplateInput,
|
||||
loadPortableTemplate,
|
||||
loadPortableTemplateConfig,
|
||||
selectTemplateInteractively,
|
||||
@@ -40,7 +40,8 @@ export async function createNewPackage(options: CreateNewPackageOptions) {
|
||||
);
|
||||
const template = await loadPortableTemplate(selectedTemplate);
|
||||
|
||||
const params = await collectPortableTemplateParams({
|
||||
const input = await collectPortableTemplateInput({
|
||||
config,
|
||||
template,
|
||||
prefilledParams: options.prefilledParams,
|
||||
});
|
||||
@@ -48,6 +49,6 @@ export async function createNewPackage(options: CreateNewPackageOptions) {
|
||||
await executePortableTemplate({
|
||||
config,
|
||||
template,
|
||||
params,
|
||||
input,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -27,19 +27,19 @@ import { createDirName, resolvePackageName } from './utils';
|
||||
import { runAdditionalActions } from './additionalActions';
|
||||
import { executePluginPackageTemplate } from './executePluginPackageTemplate';
|
||||
import { TemporaryDirectoryManager } from './TemporaryDirectoryManager';
|
||||
import { PortableTemplateConfig, PortableTemplateParams } from '../types';
|
||||
import { PortableTemplateConfig, PortableTemplateInput } from '../types';
|
||||
import { PortableTemplate } from '../types';
|
||||
|
||||
type ExecuteNewTemplateOptions = {
|
||||
config: PortableTemplateConfig;
|
||||
template: PortableTemplate;
|
||||
params: PortableTemplateParams;
|
||||
input: PortableTemplateInput;
|
||||
};
|
||||
|
||||
export async function executePortableTemplate(
|
||||
options: ExecuteNewTemplateOptions,
|
||||
) {
|
||||
const { template, params } = options;
|
||||
const { config, template, input } = options;
|
||||
|
||||
const tmpDirManager = TemporaryDirectoryManager.create();
|
||||
|
||||
|
||||
+28
-9
@@ -16,7 +16,7 @@
|
||||
|
||||
import inquirer from 'inquirer';
|
||||
import { PortableTemplateConfig } from '../types';
|
||||
import { collectPortableTemplateParams } from './collectPortableTemplateParams';
|
||||
import { collectPortableTemplateInput } from './collectPortableTemplateInput';
|
||||
|
||||
describe('collectTemplateParams', () => {
|
||||
const baseOptions = {
|
||||
@@ -33,15 +33,24 @@ describe('collectTemplateParams', () => {
|
||||
},
|
||||
prefilledParams: {
|
||||
pluginId: 'test',
|
||||
owner: '',
|
||||
owner: 'me',
|
||||
},
|
||||
};
|
||||
|
||||
it('should return default values if not provided', async () => {
|
||||
await expect(collectPortableTemplateParams(baseOptions)).resolves.toEqual({
|
||||
pluginId: 'test',
|
||||
owner: '',
|
||||
targetPath: '/example',
|
||||
await expect(collectPortableTemplateInput(baseOptions)).resolves.toEqual({
|
||||
roleParams: {
|
||||
role: 'frontend-plugin',
|
||||
pluginId: 'test',
|
||||
},
|
||||
builtInParams: {
|
||||
owner: 'me',
|
||||
},
|
||||
params: {
|
||||
pluginId: 'test',
|
||||
owner: 'me',
|
||||
},
|
||||
globals: {},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -49,13 +58,23 @@ describe('collectTemplateParams', () => {
|
||||
jest.spyOn(inquirer, 'prompt').mockResolvedValueOnce({ pluginId: 'other' });
|
||||
|
||||
await expect(
|
||||
collectPortableTemplateParams({
|
||||
collectPortableTemplateInput({
|
||||
...baseOptions,
|
||||
prefilledParams: {},
|
||||
}),
|
||||
).resolves.toEqual({
|
||||
pluginId: 'other',
|
||||
targetPath: '/example',
|
||||
roleParams: {
|
||||
role: 'frontend-plugin',
|
||||
pluginId: 'other',
|
||||
},
|
||||
builtInParams: {
|
||||
owner: undefined,
|
||||
},
|
||||
params: {
|
||||
pluginId: 'other',
|
||||
owner: undefined,
|
||||
},
|
||||
globals: {},
|
||||
});
|
||||
});
|
||||
});
|
||||
+36
-12
@@ -18,32 +18,38 @@ import inquirer, { DistinctQuestion } from 'inquirer';
|
||||
import { getCodeownersFilePath, parseOwnerIds } from '../../codeowners';
|
||||
import { paths } from '../../paths';
|
||||
import {
|
||||
PortableTemplateConfig,
|
||||
PortableTemplateInput,
|
||||
PortableTemplateInputBuiltInParams,
|
||||
PortableTemplateInputRoleParams,
|
||||
PortableTemplateParams,
|
||||
PortableTemplatePrompt,
|
||||
PortableTemplateRole,
|
||||
} from '../types';
|
||||
import { PortableTemplate } from '../types';
|
||||
|
||||
const RESERVED_PROMPT_NAMES = ['name', 'pluginId', 'moduleId', 'owner'];
|
||||
|
||||
type CollectTemplateParamsOptions = {
|
||||
config: PortableTemplateConfig;
|
||||
template: PortableTemplate;
|
||||
prefilledParams: PortableTemplateParams;
|
||||
};
|
||||
|
||||
export async function collectPortableTemplateParams(
|
||||
export async function collectPortableTemplateInput(
|
||||
options: CollectTemplateParamsOptions,
|
||||
): Promise<PortableTemplateParams> {
|
||||
const { template, prefilledParams } = options;
|
||||
): Promise<PortableTemplateInput> {
|
||||
const { config, template, prefilledParams } = options;
|
||||
|
||||
const codeOwnersFilePath = await getCodeownersFilePath(paths.targetRoot);
|
||||
|
||||
const prompts = getPromptsForRole(template.role);
|
||||
const rolePrompts = getPromptsForRole(template.role);
|
||||
|
||||
if (codeOwnersFilePath) {
|
||||
prompts.push(ownerPrompt());
|
||||
}
|
||||
if (template.prompts) {
|
||||
prompts.push(...template.prompts.map(customPrompt));
|
||||
}
|
||||
const buildInPrompts = codeOwnersFilePath ? [ownerPrompt()] : [];
|
||||
|
||||
const templatePrompts = template.prompts?.map(customPrompt) ?? [];
|
||||
|
||||
const prompts = [...rolePrompts, ...buildInPrompts, ...templatePrompts];
|
||||
|
||||
const needsAnswer = [];
|
||||
const prefilledAnswers = {} as PortableTemplateParams;
|
||||
@@ -59,10 +65,23 @@ export async function collectPortableTemplateParams(
|
||||
needsAnswer,
|
||||
);
|
||||
|
||||
return {
|
||||
const answers = {
|
||||
...prefilledAnswers,
|
||||
...promptAnswers,
|
||||
targetPath: template.targetPath,
|
||||
};
|
||||
|
||||
return {
|
||||
roleParams: {
|
||||
role: template.role,
|
||||
name: answers.name,
|
||||
pluginId: answers.pluginId,
|
||||
moduleId: answers.moduleId,
|
||||
} as PortableTemplateInputRoleParams,
|
||||
builtInParams: {
|
||||
owner: answers.owner,
|
||||
} as PortableTemplateInputBuiltInParams,
|
||||
params: answers,
|
||||
globals: config.globals,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -157,6 +176,11 @@ export function ownerPrompt(): DistinctQuestion {
|
||||
}
|
||||
|
||||
export function customPrompt(prompt: PortableTemplatePrompt): DistinctQuestion {
|
||||
if (RESERVED_PROMPT_NAMES.includes(prompt.id)) {
|
||||
throw new Error(
|
||||
`Prompt ID '${prompt.id}' is reserved and cannot be used in a template`,
|
||||
);
|
||||
}
|
||||
return {
|
||||
type: 'input',
|
||||
name: prompt.id,
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { collectPortableTemplateParams } from './collectPortableTemplateParams';
|
||||
export { collectPortableTemplateInput } from './collectPortableTemplateInput';
|
||||
export { loadPortableTemplateConfig } from './loadPortableTemplateConfig';
|
||||
export { selectTemplateInteractively } from './selectTemplateInteractively';
|
||||
export { loadPortableTemplate } from './loadPortableTemplate';
|
||||
|
||||
@@ -78,3 +78,34 @@ export type PortableTemplateGlobals = {
|
||||
private?: boolean;
|
||||
scope?: string;
|
||||
};
|
||||
|
||||
export type PortableTemplateInputRoleParams =
|
||||
| {
|
||||
role: 'web-library' | 'node-library' | 'common-library';
|
||||
name: string;
|
||||
}
|
||||
| {
|
||||
role:
|
||||
| 'plugin-web-library'
|
||||
| 'plugin-node-library'
|
||||
| 'plugin-common-library'
|
||||
| 'frontend-plugin'
|
||||
| 'backend-plugin';
|
||||
pluginId: string;
|
||||
}
|
||||
| {
|
||||
role: 'frontend-plugin-module' | 'backend-plugin-module';
|
||||
pluginId: string;
|
||||
moduleId: string;
|
||||
};
|
||||
|
||||
export type PortableTemplateInputBuiltInParams = {
|
||||
owner?: string;
|
||||
};
|
||||
|
||||
export type PortableTemplateInput = {
|
||||
roleParams: PortableTemplateInputRoleParams;
|
||||
builtInParams: PortableTemplateInputBuiltInParams;
|
||||
params: PortableTemplateParams;
|
||||
globals: PortableTemplateParams;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user