Skip to content

Commit 7574af9

Browse files
fix: add frontendless flag [EXT-6292] (#2423)
* fix: add frontendless flag [ext-6292] - added frontendless flag (short circuits function-template generation) fix: add frontendless flag [ext-6292] fix: Wording and renamed flag to `--skip-ui` * fix: remove console log * fix: add frontendless flag [ext-6292] - added frontendless flag (short circuits function-template generation) fix: add frontendless flag [ext-6292] fix: Wording and renamed flag to `--skip-ui` * fix: remove console log * fix: app-scripts version * chore: Update README's for CCA and added generate-function to app-scripts README
1 parent 571371b commit 7574af9

File tree

6 files changed

+98
-41
lines changed

6 files changed

+98
-41
lines changed

packages/contentful--app-scripts/README.md

+34
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,40 @@ interface Script<Result, Options> {
6060
>
6161
> Both interactive and nonInteractive version of the same script is meant to return the same result.
6262
63+
### Generate Function
64+
Allows generating a new function template from our [function examples](https://github.com/contentful/apps/tree/master/function-examples). Automatically updates `contentful-app-manifest.json` and merges scripts/dependencies from `package.json` into existing project.
65+
66+
#### Interactive mode:
67+
68+
In the interactive mode, the CLI will ask for all required options.
69+
70+
> **Example**
71+
>
72+
> ```shell
73+
> $ npx --no-install @contentful/app-scripts generate-function
74+
> ```
75+
76+
#### Non-interactive mode:
77+
78+
When passing the `--ci` argument the command will fail when the required variables are not set as arguments.
79+
80+
> **Example**
81+
>
82+
> ```shell
83+
> $ npx --no-install @contentful/app-scripts generate-function --ci \
84+
> --name <name> \
85+
> --example <example> \
86+
> --language <javascript/typescript> \
87+
> ```
88+
89+
**Options:**
90+
91+
| Argument | Description | Default value |
92+
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- |
93+
| `--name` | The name of your function. | |
94+
| `--example` | The name of the example as listed in our [function examples](https://github.com/contentful/apps/tree/master/function-examples) | |
95+
| `--language` | Choice of javascript or typescript | |
96+
6397
### Create App Definition
6498
6599
Allows creating a new [AppDefinition](https://www.contentful.com/developers/docs/extensibility/app-framework/app-definition/)

packages/contentful--create-contentful-app/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ Options:
9696
-s, --source <url> provide a template by its source repository.
9797
format: URL (HTTPS or SSH) or vendor:user/repo (e.g., github:user/repo)
9898
-f, --function <function-template-name> include the specified function template
99+
--skip-ui use with --function to clone the template without a user interface (UI).
99100
-h, --help shows all available CLI options
100101
```
101102

packages/contentful--create-contentful-app/package-lock.json

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/contentful--create-contentful-app/src/index.ts

+58-38
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { CREATE_APP_DEFINITION_GUIDE_URL, EXAMPLES_REPO_URL } from './constants'
1515
import { getTemplateSource } from './getTemplateSource';
1616
import { track } from './analytics';
1717
import { generateFunction } from '@contentful/app-scripts';
18+
import fs from 'fs';
1819

1920
const DEFAULT_APP_NAME = 'contentful-app';
2021

@@ -99,16 +100,43 @@ async function validateAppName(appName: string): Promise<string> {
99100

100101
async function initProject(appName: string, options: CLIOptions) {
101102
const normalizedOptions = normalizeOptions(options);
102-
103103
try {
104104
appName = await validateAppName(appName);
105105

106106
const fullAppFolder = resolve(process.cwd(), appName);
107107

108108
console.log(`Creating a Contentful app in ${highlight(tildify(fullAppFolder))}.`);
109109

110-
const isInteractive =
111-
!normalizedOptions.example &&
110+
if (normalizedOptions.function && normalizedOptions.skipUi) {
111+
await addFunctionTemplate(fullAppFolder);
112+
} else {
113+
await addAppExample(fullAppFolder);
114+
}
115+
116+
updatePackageName(fullAppFolder);
117+
118+
const useYarn = normalizedOptions.yarn || detectManager() === 'yarn';
119+
120+
wrapInBlanks(
121+
highlight(
122+
`---- Installing the dependencies for your app (using ${chalk.cyan(
123+
useYarn ? 'yarn' : 'npm'
124+
)})...`
125+
)
126+
);
127+
if (useYarn) {
128+
await exec('yarn', [], { cwd: fullAppFolder });
129+
} else {
130+
await exec('npm', ['install', '--no-audit', '--no-fund'], { cwd: fullAppFolder });
131+
}
132+
successMessage(fullAppFolder, useYarn);
133+
} catch (err) {
134+
error(`Failed to create ${highlight(chalk.cyan(appName))}`, err);
135+
process.exit(1);
136+
}
137+
138+
async function addAppExample(fullAppFolder: string) {
139+
const isInteractive = !normalizedOptions.example &&
112140
!normalizedOptions.source &&
113141
!normalizedOptions.javascript &&
114142
!normalizedOptions.typescript &&
@@ -130,47 +158,38 @@ async function initProject(appName: string, options: CLIOptions) {
130158
if (normalizedOptions.function === true) {
131159
normalizedOptions.function = 'external-references';
132160
}
133-
process.chdir(fullAppFolder);
134-
wrapInBlanks(
135-
`To add additional function templates to your app, use ${highlight(
136-
chalk.green(`
137-
npx @contentful/app-scripts@latest generate-function \\
138-
--ci \\
139-
--name <name> \\
140-
--example <example> \\
141-
--language <typescript/javascript>`)
142-
)}`
143-
);
144-
const functionName = normalizedOptions.function
145-
.toLowerCase()
146-
.replace(/-([a-z])/g, (match, letter) => letter.toUpperCase());
147-
await generateFunction.nonInteractive({
148-
example: normalizedOptions.function,
149-
language: normalizedOptions.javascript ? 'javascript' : 'typescript',
150-
name: functionName,
151-
});
161+
await addFunctionTemplate(fullAppFolder);
152162
}
163+
}
153164

154-
updatePackageName(fullAppFolder);
155-
156-
const useYarn = normalizedOptions.yarn || detectManager() === 'yarn';
165+
async function addFunctionTemplate(fullAppFolder: string) {
166+
if (!fs.existsSync(fullAppFolder)) {
167+
fs.mkdirSync(fullAppFolder, { recursive: true });
168+
}
157169

170+
process.chdir(fullAppFolder);
158171
wrapInBlanks(
159-
highlight(
160-
`---- Installing the dependencies for your app (using ${chalk.cyan(
161-
useYarn ? 'yarn' : 'npm'
162-
)})...`
163-
)
172+
`To add additional function templates to your app, use ${highlight(
173+
chalk.green(`
174+
npx @contentful/app-scripts@latest generate-function \\
175+
--ci \\
176+
--name <n> \\
177+
--example <example> \\
178+
--language <typescript/javascript>`)
179+
)}`
164180
);
165-
if (useYarn) {
166-
await exec('yarn', [], { cwd: fullAppFolder });
167-
} else {
168-
await exec('npm', ['install', '--no-audit', '--no-fund'], { cwd: fullAppFolder });
181+
if (typeof normalizedOptions.function !== 'string') {
182+
throw new Error('Function template name is required');
169183
}
170-
successMessage(fullAppFolder, useYarn);
171-
} catch (err) {
172-
error(`Failed to create ${highlight(chalk.cyan(appName))}`, err);
173-
process.exit(1);
184+
const functionName = normalizedOptions.function
185+
.toLowerCase()
186+
.replace(/-([a-z])/g, (match, letter) => letter.toUpperCase());
187+
await generateFunction.nonInteractive({
188+
example: normalizedOptions.function,
189+
language: normalizedOptions.javascript ? 'javascript' : 'typescript',
190+
name: functionName,
191+
keepPackageJson: normalizedOptions.skipUi === true
192+
} as any);
174193
}
175194
}
176195

@@ -207,6 +226,7 @@ async function initProject(appName: string, options: CLIOptions) {
207226
].join('\n')
208227
)
209228
.option('-f, --function [function-template-name]', 'include the specified function template')
229+
.option('--skip-ui', 'use with --function to clone the template without a user interface (UI).')
210230
.action(initProject);
211231
await program.parseAsync();
212232
})();

packages/contentful--create-contentful-app/src/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export type CLIOptions = Partial<{
66
source: string;
77
example: string;
88
function: string | boolean;
9+
skipUi: boolean;
910
}>;
1011

1112
export const ContentfulExample = {

packages/create-contentful-app/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -86,5 +86,6 @@ Options:
8686
-s, --source <url> provide a template by its source repository.
8787
format: URL (HTTPS or SSH) or vendor:user/repo (e.g., github:user/repo)
8888
-f, --function <function-template-name> include the specified function template
89+
--skip-ui use with --function to clone the template without a user interface (UI).
8990
-h, --help shows all available CLI options
9091
```

0 commit comments

Comments
 (0)