@contentful/create-contentful-app 1.16.1 → 1.16.3

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.
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
4
  };
@@ -21,97 +12,88 @@ const logger_1 = require("./logger");
21
12
  const constants_1 = require("./constants");
22
13
  const utils_1 = require("./utils");
23
14
  const CONTENTFUL_APPS_EXAMPLE_FOLDER = 'https://api.github.com/repos/contentful/apps/contents/examples';
24
- function getGithubFolderNames() {
25
- return __awaiter(this, void 0, void 0, function* () {
26
- const response = yield (0, node_fetch_1.default)(CONTENTFUL_APPS_EXAMPLE_FOLDER);
27
- const contents = yield response.json();
28
- return contents
29
- .filter((content) => content.type === 'dir' && !constants_1.IGNORED_EXAMPLE_FOLDERS.includes(content.name))
30
- .map((content) => content.name);
31
- });
15
+ async function getGithubFolderNames() {
16
+ const response = await (0, node_fetch_1.default)(CONTENTFUL_APPS_EXAMPLE_FOLDER);
17
+ const contents = await response.json();
18
+ return contents
19
+ .filter((content) => content.type === 'dir' && !constants_1.IGNORED_EXAMPLE_FOLDERS.includes(content.name))
20
+ .map((content) => content.name);
32
21
  }
33
- function promptExampleSelection() {
34
- return __awaiter(this, void 0, void 0, function* () {
35
- let template = 'typescript';
36
- // ask user whether to start with a blank template or use an example
37
- const { starter } = yield inquirer_1.default.prompt([
22
+ async function promptExampleSelection() {
23
+ let template = 'typescript';
24
+ // ask user whether to start with a blank template or use an example
25
+ const { starter } = await inquirer_1.default.prompt([
26
+ {
27
+ name: 'starter',
28
+ message: 'Do you want to start with a blank template or use one of our examples?',
29
+ type: 'list',
30
+ choices: [
31
+ { name: 'Template', value: 'template' },
32
+ { name: 'Example', value: 'example' },
33
+ ],
34
+ default: 'template',
35
+ },
36
+ ]);
37
+ // if the user chose to use a template, ask which language they prefer
38
+ if (starter === 'template') {
39
+ const { language } = await inquirer_1.default.prompt([
38
40
  {
39
- name: 'starter',
40
- message: 'Do you want to start with a blank template or use one of our examples?',
41
+ name: 'language',
42
+ message: 'Pick a template',
41
43
  type: 'list',
42
44
  choices: [
43
- { name: 'Template', value: 'template' },
44
- { name: 'Example', value: 'example' },
45
+ { name: 'TypeScript', value: 'typescript' },
46
+ { name: 'JavaScript', value: 'javascript' },
47
+ { name: 'Next.js', value: 'nextjs' },
48
+ { name: 'React + Vite', value: 'vite-react' },
49
+ { name: 'Vue', value: 'vue' },
45
50
  ],
46
- default: 'template',
51
+ default: 'typescript',
52
+ },
53
+ ]);
54
+ template = language;
55
+ }
56
+ else {
57
+ // get available templates from examples
58
+ const availableTemplates = await getGithubFolderNames();
59
+ // ask user to select a template from the available examples
60
+ const { example } = await inquirer_1.default.prompt([
61
+ {
62
+ name: 'example',
63
+ message: 'Select a template',
64
+ type: 'list',
65
+ choices: availableTemplates,
47
66
  },
48
67
  ]);
49
- // if the user chose to use a template, ask which language they prefer
50
- if (starter === 'template') {
51
- const { language } = yield inquirer_1.default.prompt([
52
- {
53
- name: 'language',
54
- message: 'Pick a template',
55
- type: 'list',
56
- choices: [
57
- { name: 'TypeScript', value: 'typescript' },
58
- { name: 'JavaScript', value: 'javascript' },
59
- { name: 'Next.js', value: 'nextjs' },
60
- { name: 'React + Vite', value: 'vite-react' },
61
- { name: 'Vue', value: 'vue' },
62
- ],
63
- default: 'typescript',
64
- },
65
- ]);
66
- template = language;
67
- }
68
- else {
69
- // get available templates from examples
70
- const availableTemplates = yield getGithubFolderNames();
71
- // ask user to select a template from the available examples
72
- const { example } = yield inquirer_1.default.prompt([
73
- {
74
- name: 'example',
75
- message: 'Select a template',
76
- type: 'list',
77
- choices: availableTemplates,
78
- },
79
- ]);
80
- template = example;
81
- }
82
- // return the selected template
83
- return selectTemplate(template);
84
- });
68
+ template = example;
69
+ }
70
+ // return the selected template
71
+ return selectTemplate(template);
85
72
  }
86
73
  function selectTemplate(template) {
87
74
  (0, logger_1.wrapInBlanks)((0, logger_1.highlight)(`---- Cloning the ${chalk_1.default.cyan(template)} template...`));
88
75
  return constants_1.EXAMPLES_PATH + template;
89
76
  }
90
- function makeContentfulExampleSource(options) {
91
- return __awaiter(this, void 0, void 0, function* () {
92
- if (options.example) {
93
- return selectTemplate(options.example);
94
- }
95
- if (options.javascript) {
96
- return selectTemplate(types_1.ContentfulExample.Javascript);
97
- }
98
- if (options.typescript) {
99
- return selectTemplate(types_1.ContentfulExample.Typescript);
100
- }
101
- if (options.function || options.action) {
102
- return selectTemplate(types_1.ContentfulExample.Typescript);
103
- }
104
- return yield promptExampleSelection();
105
- });
77
+ async function makeContentfulExampleSource(options) {
78
+ if (options.example) {
79
+ return selectTemplate(options.example);
80
+ }
81
+ if (options.javascript) {
82
+ return selectTemplate(types_1.ContentfulExample.Javascript);
83
+ }
84
+ if (options.typescript) {
85
+ return selectTemplate(types_1.ContentfulExample.Typescript);
86
+ }
87
+ if (options.function || options.action) {
88
+ return selectTemplate(types_1.ContentfulExample.Typescript);
89
+ }
90
+ return await promptExampleSelection();
106
91
  }
107
- function getTemplateSource(options) {
108
- var _a;
109
- return __awaiter(this, void 0, void 0, function* () {
110
- const source = (_a = options.source) !== null && _a !== void 0 ? _a : (yield makeContentfulExampleSource(options));
111
- if (options.source && !(0, utils_1.isContentfulTemplate)(source)) {
112
- (0, logger_1.warn)(`Template at ${(0, logger_1.highlight)(source)} is not an official Contentful app template!`);
113
- }
114
- return source;
115
- });
92
+ async function getTemplateSource(options) {
93
+ const source = options.source ?? (await makeContentfulExampleSource(options));
94
+ if (options.source && !(0, utils_1.isContentfulTemplate)(source)) {
95
+ (0, logger_1.warn)(`Template at ${(0, logger_1.highlight)(source)} is not an official Contentful app template!`);
96
+ }
97
+ return source;
116
98
  }
117
99
  exports.getTemplateSource = getTemplateSource;
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
4
  };
@@ -17,7 +8,7 @@ const inquirer_1 = __importDefault(require("inquirer"));
17
8
  const promises_1 = require("fs/promises");
18
9
  const path_1 = require("path");
19
10
  const constants_1 = require("./constants");
20
- const degit_1 = __importDefault(require("degit"));
11
+ const tiged_1 = __importDefault(require("tiged"));
21
12
  const logger_1 = require("./logger");
22
13
  const package_1 = require("./utils/package");
23
14
  const file_1 = require("./utils/file");
@@ -25,46 +16,44 @@ const addBuildCommand = (0, package_1.getAddBuildCommandFn)({
25
16
  name: 'build:actions',
26
17
  command: 'node build-actions.js',
27
18
  });
28
- function cloneAppAction(destination, templateIsJavascript) {
29
- return __awaiter(this, void 0, void 0, function* () {
30
- try {
31
- console.log((0, logger_1.highlight)('---- Cloning hosted app action.'));
32
- // Clone the app actions template to the created directory under the folder 'actions'
33
- const templateSource = (0, path_1.join)('contentful/apps/examples/hosted-app-action-templates', templateIsJavascript ? 'javascript' : 'typescript');
34
- const appActionDirectoryPath = (0, path_1.resolve)(`${destination}/actions`);
35
- const d = yield (0, degit_1.default)(templateSource, { mode: 'tar', cache: false });
36
- yield d.clone(appActionDirectoryPath);
37
- // move the manifest from the actions folder to the root folder
38
- const writeAppManifest = yield (0, file_1.mergeJsonIntoFile)({
39
- source: `${appActionDirectoryPath}/${constants_1.CONTENTFUL_APP_MANIFEST}`,
40
- destination: `${destination}/${constants_1.CONTENTFUL_APP_MANIFEST}`,
41
- });
42
- // move the build file from the actions folder to the root folder
43
- const copyBuildFile = yield (0, promises_1.rename)(`${appActionDirectoryPath}/build-actions.js`, `${destination}/build-actions.js`);
44
- // modify package.json build commands
45
- const packageJsonLocation = (0, path_1.resolve)(`${destination}/package.json`);
46
- const packageJsonExists = yield (0, file_1.exists)(packageJsonLocation);
47
- if (!packageJsonExists) {
48
- console.error(`Failed to add app action build commands: ${packageJsonLocation} does not exist.`);
49
- return;
50
- }
51
- const writeBuildCommand = yield (0, file_1.mergeJsonIntoFile)({
52
- source: `${appActionDirectoryPath}/package.json`,
53
- destination: packageJsonLocation,
54
- mergeFn: addBuildCommand,
55
- });
56
- yield Promise.all([writeAppManifest, copyBuildFile, writeBuildCommand]);
57
- yield d.remove(appActionDirectoryPath, destination, { action: 'remove', files: constants_1.IGNORED_CLONED_FILES.map(fileName => `${appActionDirectoryPath}/${fileName}`) });
58
- }
59
- catch (e) {
60
- console.log(e);
61
- process.exit(1);
19
+ async function cloneAppAction(destination, templateIsJavascript) {
20
+ try {
21
+ console.log((0, logger_1.highlight)('---- Cloning hosted app action.'));
22
+ // Clone the app actions template to the created directory under the folder 'actions'
23
+ const templateSource = (0, path_1.join)('contentful/apps/examples/hosted-app-action-templates', templateIsJavascript ? 'javascript' : 'typescript');
24
+ const appActionDirectoryPath = (0, path_1.resolve)(`${destination}/actions`);
25
+ const d = await (0, tiged_1.default)(templateSource, { mode: 'tar', cache: false });
26
+ await d.clone(appActionDirectoryPath);
27
+ // move the manifest from the actions folder to the root folder
28
+ const writeAppManifest = await (0, file_1.mergeJsonIntoFile)({
29
+ source: `${appActionDirectoryPath}/${constants_1.CONTENTFUL_APP_MANIFEST}`,
30
+ destination: `${destination}/${constants_1.CONTENTFUL_APP_MANIFEST}`,
31
+ });
32
+ // move the build file from the actions folder to the root folder
33
+ const copyBuildFile = await (0, promises_1.rename)(`${appActionDirectoryPath}/build-actions.js`, `${destination}/build-actions.js`);
34
+ // modify package.json build commands
35
+ const packageJsonLocation = (0, path_1.resolve)(`${destination}/package.json`);
36
+ const packageJsonExists = await (0, file_1.exists)(packageJsonLocation);
37
+ if (!packageJsonExists) {
38
+ console.error(`Failed to add app action build commands: ${packageJsonLocation} does not exist.`);
39
+ return;
62
40
  }
63
- });
41
+ const writeBuildCommand = await (0, file_1.mergeJsonIntoFile)({
42
+ source: `${appActionDirectoryPath}/package.json`,
43
+ destination: packageJsonLocation,
44
+ mergeFn: addBuildCommand,
45
+ });
46
+ await Promise.all([writeAppManifest, copyBuildFile, writeBuildCommand]);
47
+ await d.remove(appActionDirectoryPath, destination, { action: 'remove', files: constants_1.IGNORED_CLONED_FILES.map(fileName => `${appActionDirectoryPath}/${fileName}`) });
48
+ }
49
+ catch (e) {
50
+ console.log(e);
51
+ process.exit(1);
52
+ }
64
53
  }
65
54
  exports.cloneAppAction = cloneAppAction;
66
- const promptIncludeActionInTemplate = ({ fullAppFolder, templateSource, }) => __awaiter(void 0, void 0, void 0, function* () {
67
- const { includeAppAction } = yield inquirer_1.default.prompt([
55
+ const promptIncludeActionInTemplate = async ({ fullAppFolder, templateSource, }) => {
56
+ const { includeAppAction } = await inquirer_1.default.prompt([
68
57
  {
69
58
  name: 'includeAppAction',
70
59
  message: 'Do you want to include a hosted app action?',
@@ -77,5 +66,5 @@ const promptIncludeActionInTemplate = ({ fullAppFolder, templateSource, }) => __
77
66
  const templateIsTypescript = templateSource.includes('typescript');
78
67
  cloneAppAction(fullAppFolder, templateIsTypescript);
79
68
  }
80
- });
69
+ };
81
70
  exports.promptIncludeActionInTemplate = promptIncludeActionInTemplate;
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
4
  };
@@ -16,7 +7,7 @@ exports.cloneFunction = void 0;
16
7
  const promises_1 = require("fs/promises");
17
8
  const path_1 = require("path");
18
9
  const constants_1 = require("./constants");
19
- const degit_1 = __importDefault(require("degit"));
10
+ const tiged_1 = __importDefault(require("tiged"));
20
11
  const logger_1 = require("./logger");
21
12
  const file_1 = require("./utils/file");
22
13
  const package_1 = require("./utils/package");
@@ -25,59 +16,57 @@ const addBuildCommand = (0, package_1.getAddBuildCommandFn)({
25
16
  command: 'node build-functions.js',
26
17
  });
27
18
  const VALID_FUNCTION_TEMPLATES_DIRS = [
28
- 'templates',
19
+ 'external-references',
29
20
  'appevent-filter',
30
21
  'appevent-handler',
31
22
  'appevent-transformation',
32
23
  ];
33
24
  function functionTemplateFromName(functionName) {
34
25
  let dirName = functionName;
35
- if (functionName === 'external-references')
36
- dirName = 'templates'; // backwards compatible for the apps repo examples folder for delivery functions (external-references)
37
26
  if (!VALID_FUNCTION_TEMPLATES_DIRS.includes(dirName)) {
38
27
  console.error(`Invalid function template: ${functionName}. Must be one of ${VALID_FUNCTION_TEMPLATES_DIRS.join(', ')}.`);
39
28
  process.exit(1);
40
29
  }
30
+ if (functionName === 'external-references')
31
+ dirName = 'templates'; // backwards compatible for the apps repo examples folder for delivery functions (external-references)
41
32
  return dirName;
42
33
  }
43
- function cloneFunction(destination, templateIsJavascript, functionName) {
44
- return __awaiter(this, void 0, void 0, function* () {
45
- try {
46
- console.log((0, logger_1.highlight)(`---- Cloning function "${functionName}".`));
47
- // Clone the function template to the created directory under the folder 'actions'
48
- const templateSource = (0, path_1.join)(`contentful/apps/examples/function-${functionTemplateFromName(functionName)}`, templateIsJavascript ? 'javascript' : 'typescript');
49
- const functionDirectoryPath = (0, path_1.resolve)(`${destination}/functions`);
50
- const d = (0, degit_1.default)(templateSource, { mode: 'tar', cache: false });
51
- yield d.clone(functionDirectoryPath);
52
- // merge the manifest from the template folder to the root folder
53
- const writeAppManifest = (0, file_1.mergeJsonIntoFile)({
54
- source: `${functionDirectoryPath}/${constants_1.CONTENTFUL_APP_MANIFEST}`,
55
- destination: `${destination}/${constants_1.CONTENTFUL_APP_MANIFEST}`,
56
- });
57
- // move the build file from the actions folder to the root folder
58
- const copyBuildFile = (0, promises_1.rename)(`${functionDirectoryPath}/build-functions.js`, `${destination}/build-functions.js`);
59
- // modify package.json build commands
60
- const packageJsonLocation = (0, path_1.resolve)(`${destination}/package.json`);
61
- const packageJsonExists = yield (0, file_1.exists)(packageJsonLocation);
62
- if (!packageJsonExists) {
63
- console.error(`Failed to add function build commands: ${packageJsonLocation} does not exist.`);
64
- return;
65
- }
66
- const writeBuildCommand = (0, file_1.mergeJsonIntoFile)({
67
- source: `${functionDirectoryPath}/package.json`,
68
- destination: packageJsonLocation,
69
- mergeFn: addBuildCommand,
70
- });
71
- yield Promise.all([writeAppManifest, copyBuildFile, writeBuildCommand]);
72
- yield d.remove(functionDirectoryPath, destination, {
73
- action: 'remove',
74
- files: constants_1.IGNORED_CLONED_FILES.map((fileName) => `${functionDirectoryPath}/${fileName}`),
75
- });
34
+ async function cloneFunction(destination, templateIsJavascript, functionName) {
35
+ try {
36
+ console.log((0, logger_1.highlight)(`---- Cloning function "${functionName}".`));
37
+ // Clone the function template to the created directory under the folder 'actions'
38
+ const templateSource = (0, path_1.join)(`contentful/apps/examples/function-${functionTemplateFromName(functionName)}`, templateIsJavascript ? 'javascript' : 'typescript');
39
+ const functionDirectoryPath = (0, path_1.resolve)(`${destination}/functions`);
40
+ const d = (0, tiged_1.default)(templateSource, { mode: 'tar', cache: false });
41
+ await d.clone(functionDirectoryPath);
42
+ // merge the manifest from the template folder to the root folder
43
+ const writeAppManifest = (0, file_1.mergeJsonIntoFile)({
44
+ source: `${functionDirectoryPath}/${constants_1.CONTENTFUL_APP_MANIFEST}`,
45
+ destination: `${destination}/${constants_1.CONTENTFUL_APP_MANIFEST}`,
46
+ });
47
+ // move the build file from the actions folder to the root folder
48
+ const copyBuildFile = (0, promises_1.rename)(`${functionDirectoryPath}/build-functions.js`, `${destination}/build-functions.js`);
49
+ // modify package.json build commands
50
+ const packageJsonLocation = (0, path_1.resolve)(`${destination}/package.json`);
51
+ const packageJsonExists = await (0, file_1.exists)(packageJsonLocation);
52
+ if (!packageJsonExists) {
53
+ console.error(`Failed to add function build commands: ${packageJsonLocation} does not exist.`);
54
+ return;
76
55
  }
77
- catch (e) {
78
- console.error(e);
79
- process.exit(1);
80
- }
81
- });
56
+ const writeBuildCommand = (0, file_1.mergeJsonIntoFile)({
57
+ source: `${functionDirectoryPath}/package.json`,
58
+ destination: packageJsonLocation,
59
+ mergeFn: addBuildCommand,
60
+ });
61
+ await Promise.all([writeAppManifest, copyBuildFile, writeBuildCommand]);
62
+ await d.remove(functionDirectoryPath, destination, {
63
+ action: 'remove',
64
+ files: constants_1.IGNORED_CLONED_FILES.map((fileName) => `${functionDirectoryPath}/${fileName}`),
65
+ });
66
+ }
67
+ catch (e) {
68
+ console.error(e);
69
+ process.exit(1);
70
+ }
82
71
  }
83
72
  exports.cloneFunction = cloneFunction;
package/lib/index.js CHANGED
@@ -1,14 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
4
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
5
- return new (P || (P = Promise))(function (resolve, reject) {
6
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
7
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
8
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
9
- step((generator = generator.apply(thisArg, _arguments || [])).next());
10
- });
11
- };
12
3
  var __importDefault = (this && this.__importDefault) || function (mod) {
13
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
14
5
  };
@@ -54,16 +45,14 @@ function updatePackageName(appFolder) {
54
45
  packageJson.name = (0, path_1.basename)(appFolder);
55
46
  (0, fs_1.writeFileSync)(packageJsonPath, JSON.stringify(packageJson, null, 2) + os_1.EOL);
56
47
  }
57
- function promptAppName() {
58
- return __awaiter(this, void 0, void 0, function* () {
59
- return yield inquirer_1.default.prompt([
60
- {
61
- name: 'name',
62
- message: 'App name',
63
- default: DEFAULT_APP_NAME,
64
- },
65
- ]);
66
- });
48
+ async function promptAppName() {
49
+ return await inquirer_1.default.prompt([
50
+ {
51
+ name: 'name',
52
+ message: 'App name',
53
+ default: DEFAULT_APP_NAME,
54
+ },
55
+ ]);
67
56
  }
68
57
  /**
69
58
  * Validates the user input and ensures it can be used as app name. If no app name is provided, shows a prompt.
@@ -71,102 +60,96 @@ function promptAppName() {
71
60
  * @param appName App name entered by the user
72
61
  * @returns Valid app name
73
62
  */
74
- function validateAppName(appName) {
75
- return __awaiter(this, void 0, void 0, function* () {
76
- if (appName === 'create-definition') {
77
- throw new Error(`The ${(0, logger_1.code)('create-definition')} command has been removed from ${(0, logger_1.code)('create-contentful-app')}.\nTo create a new app definition first run ${(0, logger_1.code)('npx create-contentful-app')} and then ${(0, logger_1.code)('npm run create-app-definition')} within the new folder.`);
78
- }
79
- if (appName === 'init') {
80
- (0, logger_1.warn)(`The ${(0, logger_1.code)('init')} command has been removed from ${(0, logger_1.code)('create-contentful-app')}. You can now create new apps running ${(0, logger_1.code)('npx create-contentful-app')} directly.`);
81
- appName = '';
82
- }
83
- if (!appName) {
84
- const prompt = yield promptAppName();
85
- appName = prompt.name;
86
- }
87
- if (!(0, validate_npm_package_name_1.default)(appName).validForNewPackages) {
88
- throw new Error(`Cannot create an app named "${appName}". Please choose a different name for your app.`);
89
- }
90
- return appName;
91
- });
63
+ async function validateAppName(appName) {
64
+ if (appName === 'create-definition') {
65
+ throw new Error(`The ${(0, logger_1.code)('create-definition')} command has been removed from ${(0, logger_1.code)('create-contentful-app')}.\nTo create a new app definition first run ${(0, logger_1.code)('npx create-contentful-app')} and then ${(0, logger_1.code)('npm run create-app-definition')} within the new folder.`);
66
+ }
67
+ if (appName === 'init') {
68
+ (0, logger_1.warn)(`The ${(0, logger_1.code)('init')} command has been removed from ${(0, logger_1.code)('create-contentful-app')}. You can now create new apps running ${(0, logger_1.code)('npx create-contentful-app')} directly.`);
69
+ appName = '';
70
+ }
71
+ if (!appName) {
72
+ const prompt = await promptAppName();
73
+ appName = prompt.name;
74
+ }
75
+ if (!(0, validate_npm_package_name_1.default)(appName).validForNewPackages) {
76
+ throw new Error(`Cannot create an app named "${appName}". Please choose a different name for your app.`);
77
+ }
78
+ return appName;
92
79
  }
93
- function initProject(appName, options) {
94
- return __awaiter(this, void 0, void 0, function* () {
95
- const normalizedOptions = (0, utils_1.normalizeOptions)(options);
96
- try {
97
- appName = yield validateAppName(appName);
98
- const fullAppFolder = (0, path_1.resolve)(process.cwd(), appName);
99
- console.log(`Creating a Contentful app in ${(0, logger_1.highlight)((0, tildify_1.default)(fullAppFolder))}.`);
100
- const isInteractive = !normalizedOptions.example &&
101
- !normalizedOptions.source &&
102
- !normalizedOptions.javascript &&
103
- !normalizedOptions.typescript &&
104
- !normalizedOptions.function &&
105
- !normalizedOptions.action;
106
- const templateSource = yield (0, getTemplateSource_1.getTemplateSource)(options);
107
- (0, analytics_1.track)({
108
- template: templateSource,
109
- manager: normalizedOptions.npm ? 'npm' : 'yarn',
110
- interactive: isInteractive,
111
- });
112
- yield (0, template_1.cloneTemplateIn)(fullAppFolder, templateSource);
113
- if (!isInteractive && (0, utils_1.isContentfulTemplate)(templateSource) && normalizedOptions.action) {
114
- yield (0, includeAppAction_1.cloneAppAction)(fullAppFolder, !!normalizedOptions.javascript);
115
- }
116
- if (!isInteractive && (0, utils_1.isContentfulTemplate)(templateSource) && normalizedOptions.function) {
117
- // If function flag is specified, but no function name is provided, we default to external-references
118
- // for legacy support.
119
- if (normalizedOptions.function === true) {
120
- normalizedOptions.function = 'external-references';
121
- }
122
- yield (0, includeFunction_1.cloneFunction)(fullAppFolder, !!normalizedOptions.javascript, normalizedOptions.function);
123
- }
124
- updatePackageName(fullAppFolder);
125
- const useYarn = normalizedOptions.yarn || (0, utils_1.detectManager)() === 'yarn';
126
- (0, logger_1.wrapInBlanks)((0, logger_1.highlight)(`---- Installing the dependencies for your app (using ${chalk_1.default.cyan(useYarn ? 'yarn' : 'npm')})...`));
127
- if (useYarn) {
128
- yield (0, utils_1.exec)('yarn', [], { cwd: fullAppFolder });
129
- }
130
- else {
131
- yield (0, utils_1.exec)('npm', ['install', '--no-audit', '--no-fund'], { cwd: fullAppFolder });
80
+ async function initProject(appName, options) {
81
+ const normalizedOptions = (0, utils_1.normalizeOptions)(options);
82
+ try {
83
+ appName = await validateAppName(appName);
84
+ const fullAppFolder = (0, path_1.resolve)(process.cwd(), appName);
85
+ console.log(`Creating a Contentful app in ${(0, logger_1.highlight)((0, tildify_1.default)(fullAppFolder))}.`);
86
+ const isInteractive = !normalizedOptions.example &&
87
+ !normalizedOptions.source &&
88
+ !normalizedOptions.javascript &&
89
+ !normalizedOptions.typescript &&
90
+ !normalizedOptions.function &&
91
+ !normalizedOptions.action;
92
+ const templateSource = await (0, getTemplateSource_1.getTemplateSource)(options);
93
+ (0, analytics_1.track)({
94
+ template: templateSource,
95
+ manager: normalizedOptions.npm ? 'npm' : 'yarn',
96
+ interactive: isInteractive,
97
+ });
98
+ await (0, template_1.cloneTemplateIn)(fullAppFolder, templateSource);
99
+ if (!isInteractive && (0, utils_1.isContentfulTemplate)(templateSource) && normalizedOptions.action) {
100
+ await (0, includeAppAction_1.cloneAppAction)(fullAppFolder, !!normalizedOptions.javascript);
101
+ }
102
+ if (!isInteractive && (0, utils_1.isContentfulTemplate)(templateSource) && normalizedOptions.function) {
103
+ // If function flag is specified, but no function name is provided, we default to external-references
104
+ // for legacy support.
105
+ if (normalizedOptions.function === true) {
106
+ normalizedOptions.function = 'external-references';
132
107
  }
133
- successMessage(fullAppFolder, useYarn);
108
+ await (0, includeFunction_1.cloneFunction)(fullAppFolder, !!normalizedOptions.javascript, normalizedOptions.function);
109
+ }
110
+ updatePackageName(fullAppFolder);
111
+ const useYarn = normalizedOptions.yarn || (0, utils_1.detectManager)() === 'yarn';
112
+ (0, logger_1.wrapInBlanks)((0, logger_1.highlight)(`---- Installing the dependencies for your app (using ${chalk_1.default.cyan(useYarn ? 'yarn' : 'npm')})...`));
113
+ if (useYarn) {
114
+ await (0, utils_1.exec)('yarn', [], { cwd: fullAppFolder });
134
115
  }
135
- catch (err) {
136
- (0, logger_1.error)(`Failed to create ${appName}`, err);
137
- process.exit(1);
116
+ else {
117
+ await (0, utils_1.exec)('npm', ['install', '--no-audit', '--no-fund'], { cwd: fullAppFolder });
138
118
  }
139
- });
119
+ successMessage(fullAppFolder, useYarn);
120
+ }
121
+ catch (err) {
122
+ (0, logger_1.error)(`Failed to create ${appName}`, err);
123
+ process.exit(1);
124
+ }
140
125
  }
141
- (function main() {
142
- return __awaiter(this, void 0, void 0, function* () {
143
- commander_1.program
144
- .name(`npx ${(0, logger_1.code)('create-contentful-app')}`)
145
- .helpOption(true, 'shows all available CLI options')
146
- .description([
147
- 'Bootstrap your app inside a new folder `my-app`',
148
- '',
149
- (0, logger_1.code)(' create-contentful-app my-app'),
150
- '',
151
- 'or specify your own template',
152
- '',
153
- (0, logger_1.code)(' create-contentful-app my-app --source "github:user/repo"'),
154
- '',
155
- `Official Contentful templates and examples are hosted at ${(0, logger_1.highlight)(constants_1.EXAMPLES_REPO_URL)}.`,
156
- ].join('\n'))
157
- .argument('[app-name]', 'app name')
158
- .option('--npm', 'use npm')
159
- .option('--yarn', 'use Yarn')
160
- .option('-ts, --typescript', 'use TypeScript template (default)')
161
- .option('-js, --javascript', 'use JavaScript template')
162
- .option('-e, --example <example-name>', `bootstrap an example app from ${constants_1.EXAMPLES_REPO_URL}`)
163
- .option('-s, --source <url>', [
164
- `provide a template by its source repository.`,
165
- `format: URL (HTTPS or SSH) or ${(0, logger_1.code)('vendor:user/repo')} (e.g., ${(0, logger_1.code)('github:user/repo')})`,
166
- ].join('\n'))
167
- .option('-a, --action', 'include a hosted app action in the ts or js template')
168
- .option('-f, --function [function-template-name]', 'include the specified function template')
169
- .action(initProject);
170
- yield commander_1.program.parseAsync();
171
- });
126
+ (async function main() {
127
+ commander_1.program
128
+ .name(`npx ${(0, logger_1.code)('create-contentful-app')}`)
129
+ .helpOption(true, 'shows all available CLI options')
130
+ .description([
131
+ 'Bootstrap your app inside a new folder `my-app`',
132
+ '',
133
+ (0, logger_1.code)(' create-contentful-app my-app'),
134
+ '',
135
+ 'or specify your own template',
136
+ '',
137
+ (0, logger_1.code)(' create-contentful-app my-app --source "github:user/repo"'),
138
+ '',
139
+ `Official Contentful templates and examples are hosted at ${(0, logger_1.highlight)(constants_1.EXAMPLES_REPO_URL)}.`,
140
+ ].join('\n'))
141
+ .argument('[app-name]', 'app name')
142
+ .option('--npm', 'use npm')
143
+ .option('--yarn', 'use Yarn')
144
+ .option('-ts, --typescript', 'use TypeScript template (default)')
145
+ .option('-js, --javascript', 'use JavaScript template')
146
+ .option('-e, --example <example-name>', `bootstrap an example app from ${constants_1.EXAMPLES_REPO_URL}`)
147
+ .option('-s, --source <url>', [
148
+ `provide a template by its source repository.`,
149
+ `format: URL (HTTPS or SSH) or ${(0, logger_1.code)('vendor:user/repo')} (e.g., ${(0, logger_1.code)('github:user/repo')})`,
150
+ ].join('\n'))
151
+ .option('-a, --action', 'include a hosted app action in the ts or js template')
152
+ .option('-f, --function [function-template-name]', 'include the specified function template')
153
+ .action(initProject);
154
+ await commander_1.program.parseAsync();
172
155
  })();
package/lib/template.js CHANGED
@@ -22,15 +22,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
- return new (P || (P = Promise))(function (resolve, reject) {
28
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
- step((generator = generator.apply(thisArg, _arguments || [])).next());
32
- });
33
- };
34
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
35
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
36
27
  };
@@ -38,27 +29,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
38
29
  exports.cloneTemplateIn = void 0;
39
30
  const path_1 = require("path");
40
31
  const fs_1 = require("fs");
41
- const degit_1 = __importDefault(require("degit"));
32
+ const tiged_1 = __importDefault(require("tiged"));
42
33
  const rimraf = __importStar(require("rimraf"));
43
34
  const logger_1 = require("./logger");
44
35
  const utils_1 = require("./utils");
45
- function clone(source, destination) {
46
- return __awaiter(this, void 0, void 0, function* () {
47
- const d = (0, degit_1.default)(source, { mode: 'tar', cache: false });
48
- try {
49
- yield d.clone(destination);
50
- }
51
- catch (e) {
52
- if (e.code === 'DEST_NOT_EMPTY') {
53
- // In this case, we know that degit will suggest users
54
- // provide a 'force' flag - this is a flag for degit though
55
- // and not CCA. So we swallow the details of this error
56
- // to avoid confusing people.
57
- throw new Error('Destination directory is not empty.');
58
- }
59
- throw e;
36
+ async function clone(source, destination) {
37
+ const d = (0, tiged_1.default)(source, { mode: 'tar', cache: false });
38
+ try {
39
+ await d.clone(destination);
40
+ }
41
+ catch (e) {
42
+ if (e.code === 'DEST_NOT_EMPTY') {
43
+ // In this case, we know that tiged will suggest users
44
+ // provide a 'force' flag - this is a flag for tiged though
45
+ // and not CCA. So we swallow the details of this error
46
+ // to avoid confusing people.
47
+ throw new Error('Destination directory is not empty.');
60
48
  }
61
- });
49
+ throw e;
50
+ }
62
51
  }
63
52
  function validate(destination) {
64
53
  const packageJSONLocation = `${destination}/package.json`;
@@ -76,19 +65,17 @@ function cleanUp(destination) {
76
65
  (0, utils_1.rmIfExists)((0, path_1.resolve)(destination, 'package-lock.json'));
77
66
  (0, utils_1.rmIfExists)((0, path_1.resolve)(destination, 'yarn.lock'));
78
67
  }
79
- function cloneTemplateIn(destination, source) {
80
- return __awaiter(this, void 0, void 0, function* () {
81
- yield clone(source, destination);
82
- console.log((0, logger_1.success)('Done!'));
83
- try {
84
- validate(destination);
85
- }
86
- catch (e) {
87
- // cleanup in case of invalid example
88
- rimraf.sync(destination);
89
- throw e;
90
- }
91
- cleanUp(destination);
92
- });
68
+ async function cloneTemplateIn(destination, source) {
69
+ await clone(source, destination);
70
+ console.log((0, logger_1.success)('Done!'));
71
+ try {
72
+ validate(destination);
73
+ }
74
+ catch (e) {
75
+ // cleanup in case of invalid example
76
+ rimraf.sync(destination);
77
+ throw e;
78
+ }
79
+ cleanUp(destination);
93
80
  }
94
81
  exports.cloneTemplateIn = cloneTemplateIn;
package/lib/utils/file.js CHANGED
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
4
  };
@@ -16,26 +7,22 @@ exports.exists = exports.mergeJsonIntoFile = exports.getJsonData = void 0;
16
7
  const merge_options_1 = __importDefault(require("merge-options"));
17
8
  const promises_1 = require("fs/promises");
18
9
  const path_1 = require("path");
19
- function getJsonData(path) {
20
- return __awaiter(this, void 0, void 0, function* () {
21
- if (!path) {
22
- return undefined;
23
- }
24
- const normalizedPath = (0, path_1.resolve)(path);
25
- if (!(yield exists(normalizedPath))) {
26
- return undefined;
27
- }
28
- return JSON.parse(yield (0, promises_1.readFile)(normalizedPath, { encoding: 'utf-8' }));
29
- });
10
+ async function getJsonData(path) {
11
+ if (!path) {
12
+ return undefined;
13
+ }
14
+ const normalizedPath = (0, path_1.resolve)(path);
15
+ if (!(await exists(normalizedPath))) {
16
+ return undefined;
17
+ }
18
+ return JSON.parse(await (0, promises_1.readFile)(normalizedPath, { encoding: 'utf-8' }));
30
19
  }
31
20
  exports.getJsonData = getJsonData;
32
- function mergeJsonIntoFile({ source, destination, mergeFn = merge_options_1.default.bind({ concatArrays: false }), }) {
33
- return __awaiter(this, void 0, void 0, function* () {
34
- const sourceJson = yield getJsonData(source);
35
- const destinationJson = yield getJsonData(destination);
36
- const mergedJson = mergeFn(destinationJson, sourceJson);
37
- yield (0, promises_1.writeFile)((0, path_1.resolve)(destination), JSON.stringify(mergedJson, null, ' '));
38
- });
21
+ async function mergeJsonIntoFile({ source, destination, mergeFn = merge_options_1.default.bind({ concatArrays: false }), }) {
22
+ const sourceJson = await getJsonData(source);
23
+ const destinationJson = await getJsonData(destination);
24
+ const mergedJson = mergeFn(destinationJson, sourceJson);
25
+ await (0, promises_1.writeFile)((0, path_1.resolve)(destination), JSON.stringify(mergedJson, null, ' '));
39
26
  }
40
27
  exports.mergeJsonIntoFile = mergeJsonIntoFile;
41
28
  function exists(path) {
@@ -7,8 +7,7 @@ exports.getAddBuildCommandFn = void 0;
7
7
  const merge_options_1 = __importDefault(require("merge-options"));
8
8
  function getAddBuildCommandFn({ name, command }) {
9
9
  return (packageJson, additionalProperties) => {
10
- var _a, _b;
11
- let buildCommand = (_b = (_a = packageJson === null || packageJson === void 0 ? void 0 : packageJson.scripts) === null || _a === void 0 ? void 0 : _a.build) !== null && _b !== void 0 ? _b : '';
10
+ let buildCommand = packageJson?.scripts?.build ?? '';
12
11
  const triggerCommand = `npm run ${name}`;
13
12
  if (buildCommand === '') {
14
13
  buildCommand = triggerCommand;
package/lib/utils.js CHANGED
@@ -10,7 +10,7 @@ const constants_1 = require("./constants");
10
10
  const MUTUALLY_EXCLUSIVE_OPTIONS = ['source', 'example', 'typescript', 'javascript'];
11
11
  function exec(command, args, options) {
12
12
  return new Promise((resolve, reject) => {
13
- const process = (0, child_process_1.spawn)(command, args, Object.assign({ stdio: 'inherit', shell: true }, options));
13
+ const process = (0, child_process_1.spawn)(command, args, { stdio: 'inherit', shell: true, ...options });
14
14
  process.on('exit', (exitCode) => {
15
15
  if (exitCode === 0) {
16
16
  resolve();
@@ -40,7 +40,7 @@ function detectManager() {
40
40
  }
41
41
  exports.detectManager = detectManager;
42
42
  function normalizeOptions(options) {
43
- const normalizedOptions = Object.assign({}, options);
43
+ const normalizedOptions = { ...options };
44
44
  if (normalizedOptions.npm && normalizedOptions.yarn) {
45
45
  (0, logger_1.warn)(`Provided both ${(0, logger_1.highlight)('--yarn')} and ${(0, logger_1.highlight)('--npm')} flags, using ${(0, logger_1.choice)('--npm')}.`);
46
46
  delete normalizedOptions.yarn;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/create-contentful-app",
3
- "version": "1.16.1",
3
+ "version": "1.16.3",
4
4
  "description": "A template for building Contentful Apps",
5
5
  "keywords": [
6
6
  "contentful",
@@ -40,11 +40,11 @@
40
40
  "analytics-node": "^6.2.0",
41
41
  "chalk": "4.1.2",
42
42
  "commander": "12.0.0",
43
- "degit": "2.8.4",
44
43
  "inquirer": "8.2.6",
45
44
  "merge-options": "^3.0.4",
46
45
  "node-fetch": "2.6.7",
47
46
  "rimraf": "5.0.5",
47
+ "tiged": "^2.12.7",
48
48
  "tildify": "2.0.0",
49
49
  "validate-npm-package-name": "5.0.0"
50
50
  },
@@ -59,11 +59,10 @@
59
59
  "access": "public"
60
60
  },
61
61
  "devDependencies": {
62
- "@tsconfig/node16": "16.1.3",
62
+ "@tsconfig/node20": "^20.1.4",
63
63
  "@types/analytics-node": "^3.1.9",
64
64
  "@types/chai-as-promised": "^7.1.5",
65
65
  "@types/chalk": "2.2.0",
66
- "@types/degit": "2.8.6",
67
66
  "@types/inquirer": "8.2.1",
68
67
  "@types/mocha": "^10.0.1",
69
68
  "@types/node": "14.18.63",
@@ -75,11 +74,11 @@
75
74
  "@types/validate-npm-package-name": "4.0.2",
76
75
  "chai": "^4.3.7",
77
76
  "chai-as-promised": "^7.1.1",
78
- "contentful-management": "11.25.0",
77
+ "contentful-management": "11.25.2",
79
78
  "mocha": "^10.2.0",
80
79
  "sinon": "^17.0.0",
81
80
  "sinon-chai": "^3.7.0",
82
- "ts-node": "^10.9.1"
81
+ "ts-node": "^10.9.2"
83
82
  },
84
- "gitHead": "a4a02a44a4231bfe52c093625a356889f53e5859"
83
+ "gitHead": "8d95686d58b8ee84bb79baf5361d1984e8005866"
85
84
  }