@contentful/create-contentful-app 1.5.0 → 1.6.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/lib/analytics.js +28 -0
- package/lib/getTemplateSource.js +110 -0
- package/lib/index.js +6 -1
- package/lib/template.js +1 -95
- package/package.json +7 -5
package/lib/analytics.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.track = void 0;
|
|
7
|
+
const analytics_node_1 = __importDefault(require("analytics-node"));
|
|
8
|
+
// Public write key scoped to data source
|
|
9
|
+
const SEGMENT_WRITE_KEY = 'IzCq3j4dQlTAgLdMykRW9oBHQKUy1xMm';
|
|
10
|
+
function track(properties) {
|
|
11
|
+
if (process.env.DISABLE_ANALYTICS) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const client = new analytics_node_1.default(SEGMENT_WRITE_KEY);
|
|
15
|
+
try {
|
|
16
|
+
client.track({
|
|
17
|
+
event: 'app-cli-cca-creation',
|
|
18
|
+
properties,
|
|
19
|
+
timestamp: new Date(),
|
|
20
|
+
anonymousId: Date.now() // generate a random id
|
|
21
|
+
});
|
|
22
|
+
// eslint-disable-next-line no-empty
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
// ignore any error, to not block the cca run
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.track = track;
|
|
@@ -0,0 +1,110 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.getTemplateSource = void 0;
|
|
16
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
17
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
18
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
19
|
+
const types_1 = require("./types");
|
|
20
|
+
const logger_1 = require("./logger");
|
|
21
|
+
const EXAMPLES_PATH = 'contentful/apps/examples/';
|
|
22
|
+
function isContentfulTemplate(url) {
|
|
23
|
+
return Object.values(types_1.ContentfulExample).some((t) => url.includes(EXAMPLES_PATH + t));
|
|
24
|
+
}
|
|
25
|
+
const CONTENTFUL_APPS_EXAMPLE_FOLDER = "https://api.github.com/repos/contentful/apps/contents/examples";
|
|
26
|
+
function getGithubFolderNames() {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
const response = yield (0, node_fetch_1.default)(CONTENTFUL_APPS_EXAMPLE_FOLDER);
|
|
29
|
+
const contents = yield response.json();
|
|
30
|
+
return contents
|
|
31
|
+
.filter((content) => content.type === 'dir')
|
|
32
|
+
.map((content) => content.name);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function promptExampleSelection() {
|
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
let template = 'typescript';
|
|
38
|
+
// ask user whether to start with a blank template or use an example template
|
|
39
|
+
const { starter } = yield inquirer_1.default.prompt([
|
|
40
|
+
{
|
|
41
|
+
name: 'starter',
|
|
42
|
+
message: 'Do you want to start with a blank template or use one of our examples?',
|
|
43
|
+
type: 'list',
|
|
44
|
+
choices: ['blank', 'example'],
|
|
45
|
+
default: 'blank',
|
|
46
|
+
},
|
|
47
|
+
]);
|
|
48
|
+
// if the user chose to use an blank template, ask which language they prefer
|
|
49
|
+
if (starter === 'blank') {
|
|
50
|
+
const { language } = yield inquirer_1.default.prompt([
|
|
51
|
+
{
|
|
52
|
+
name: 'language',
|
|
53
|
+
message: 'Do you prefer TypeScript or JavaScript',
|
|
54
|
+
type: 'list',
|
|
55
|
+
choices: [
|
|
56
|
+
{ name: 'TypeScript', value: 'typescript' },
|
|
57
|
+
{ name: 'JavaScript', value: 'javascript' },
|
|
58
|
+
],
|
|
59
|
+
default: 'typescript',
|
|
60
|
+
},
|
|
61
|
+
]);
|
|
62
|
+
template = language;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// get available templates from examples
|
|
66
|
+
const availableTemplates = yield getGithubFolderNames();
|
|
67
|
+
// ask user to select a template from the available examples
|
|
68
|
+
const { example } = yield inquirer_1.default.prompt([
|
|
69
|
+
{
|
|
70
|
+
name: 'example',
|
|
71
|
+
message: 'Select a template',
|
|
72
|
+
type: 'list',
|
|
73
|
+
choices: availableTemplates,
|
|
74
|
+
},
|
|
75
|
+
]);
|
|
76
|
+
template = example;
|
|
77
|
+
}
|
|
78
|
+
// return the selected template
|
|
79
|
+
return selectTemplate(template);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function selectTemplate(template) {
|
|
83
|
+
(0, logger_1.wrapInBlanks)((0, logger_1.highlight)(`---- Cloning the ${chalk_1.default.cyan(template)} template...`));
|
|
84
|
+
return EXAMPLES_PATH + template;
|
|
85
|
+
}
|
|
86
|
+
function makeContentfulExampleSource(options) {
|
|
87
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
88
|
+
if (options.example) {
|
|
89
|
+
return selectTemplate(options.example);
|
|
90
|
+
}
|
|
91
|
+
if (options.javascript) {
|
|
92
|
+
return selectTemplate(types_1.ContentfulExample.Javascript);
|
|
93
|
+
}
|
|
94
|
+
if (options.typescript) {
|
|
95
|
+
return selectTemplate(types_1.ContentfulExample.Typescript);
|
|
96
|
+
}
|
|
97
|
+
return yield promptExampleSelection();
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
function getTemplateSource(options) {
|
|
101
|
+
var _a;
|
|
102
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
103
|
+
const source = (_a = options.source) !== null && _a !== void 0 ? _a : (yield makeContentfulExampleSource(options));
|
|
104
|
+
if (options.source && !isContentfulTemplate(source)) {
|
|
105
|
+
(0, logger_1.warn)(`Template at ${(0, logger_1.highlight)(source)} is not an official Contentful app template!`);
|
|
106
|
+
}
|
|
107
|
+
return source;
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
exports.getTemplateSource = getTemplateSource;
|
package/lib/index.js
CHANGED
|
@@ -25,6 +25,8 @@ const utils_1 = require("./utils");
|
|
|
25
25
|
const logger_1 = require("./logger");
|
|
26
26
|
const chalk_1 = __importDefault(require("chalk"));
|
|
27
27
|
const constants_1 = require("./constants");
|
|
28
|
+
const getTemplateSource_1 = require("./getTemplateSource");
|
|
29
|
+
const analytics_1 = require("./analytics");
|
|
28
30
|
const DEFAULT_APP_NAME = 'contentful-app';
|
|
29
31
|
function successMessage(folder, useYarn) {
|
|
30
32
|
console.log(`
|
|
@@ -93,7 +95,10 @@ function initProject(appName, options) {
|
|
|
93
95
|
appName = yield validateAppName(appName);
|
|
94
96
|
const fullAppFolder = (0, path_1.resolve)(process.cwd(), appName);
|
|
95
97
|
console.log(`Creating a Contentful app in ${(0, logger_1.highlight)((0, tildify_1.default)(fullAppFolder))}.`);
|
|
96
|
-
|
|
98
|
+
const isInteractive = !normalizedOptions.example && !normalizedOptions.source && !normalizedOptions.javascript && !normalizedOptions.typescript;
|
|
99
|
+
const templateSource = yield (0, getTemplateSource_1.getTemplateSource)(options);
|
|
100
|
+
(0, analytics_1.track)({ template: templateSource, manager: normalizedOptions.npm ? 'npm' : 'yarn', interactive: isInteractive });
|
|
101
|
+
yield (0, template_1.cloneTemplateIn)(fullAppFolder, templateSource);
|
|
97
102
|
updatePackageName(fullAppFolder);
|
|
98
103
|
const useYarn = normalizedOptions.yarn || (0, utils_1.detectManager)() === 'yarn';
|
|
99
104
|
(0, logger_1.wrapInBlanks)((0, logger_1.highlight)(`---- Installing the dependencies for your app (using ${chalk_1.default.cyan(useYarn ? 'yarn' : 'npm')})...`));
|
package/lib/template.js
CHANGED
|
@@ -17,101 +17,8 @@ const path_1 = require("path");
|
|
|
17
17
|
const fs_1 = require("fs");
|
|
18
18
|
const degit_1 = __importDefault(require("degit"));
|
|
19
19
|
const rimraf_1 = __importDefault(require("rimraf"));
|
|
20
|
-
const types_1 = require("./types");
|
|
21
20
|
const logger_1 = require("./logger");
|
|
22
21
|
const utils_1 = require("./utils");
|
|
23
|
-
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
24
|
-
const inquirer_1 = __importDefault(require("inquirer"));
|
|
25
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
26
|
-
const EXAMPLES_PATH = 'contentful/apps/examples/';
|
|
27
|
-
function isContentfulTemplate(url) {
|
|
28
|
-
return Object.values(types_1.ContentfulExample).some((t) => url.includes(EXAMPLES_PATH + t));
|
|
29
|
-
}
|
|
30
|
-
function getGithubFolderNames(username, repo, path) {
|
|
31
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
-
const url = `https://api.github.com/repos/${username}/${repo}/contents/${path}`;
|
|
33
|
-
const response = yield (0, node_fetch_1.default)(url);
|
|
34
|
-
const contents = yield response.json();
|
|
35
|
-
return contents
|
|
36
|
-
.filter((content) => content.type === 'dir')
|
|
37
|
-
.map((content) => content.name);
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
function promptExampleSelection() {
|
|
41
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
-
let template = 'typescript';
|
|
43
|
-
// ask user whether to start with a blank template or use an example template
|
|
44
|
-
const { starter } = yield inquirer_1.default.prompt([
|
|
45
|
-
{
|
|
46
|
-
name: 'starter',
|
|
47
|
-
message: 'Do you want to start with a blank template or use one of our examples?',
|
|
48
|
-
type: 'list',
|
|
49
|
-
choices: ['blank', 'example'],
|
|
50
|
-
default: 'blank',
|
|
51
|
-
},
|
|
52
|
-
]);
|
|
53
|
-
// if the user chose to use an blank template, ask which language they prefer
|
|
54
|
-
if (starter === 'blank') {
|
|
55
|
-
const { language } = yield inquirer_1.default.prompt([
|
|
56
|
-
{
|
|
57
|
-
name: 'language',
|
|
58
|
-
message: 'Do you prefer TypeScript or JavaScript',
|
|
59
|
-
type: 'list',
|
|
60
|
-
choices: [
|
|
61
|
-
{ name: 'TypeScript', value: 'typescript' },
|
|
62
|
-
{ name: 'JavaScript', value: 'javascript' },
|
|
63
|
-
],
|
|
64
|
-
default: 'typescript',
|
|
65
|
-
},
|
|
66
|
-
]);
|
|
67
|
-
template = language;
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
// get available templates from examples
|
|
71
|
-
const availableTemplates = yield getGithubFolderNames('contentful', 'apps', 'examples');
|
|
72
|
-
// ask user to select a template from the available examples
|
|
73
|
-
const { example } = yield inquirer_1.default.prompt([
|
|
74
|
-
{
|
|
75
|
-
name: 'example',
|
|
76
|
-
message: 'Select a template',
|
|
77
|
-
type: 'list',
|
|
78
|
-
choices: availableTemplates,
|
|
79
|
-
},
|
|
80
|
-
]);
|
|
81
|
-
template = example;
|
|
82
|
-
}
|
|
83
|
-
// return the selected template
|
|
84
|
-
return selectTemplate(template);
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
function selectTemplate(template) {
|
|
88
|
-
(0, logger_1.wrapInBlanks)((0, logger_1.highlight)(`---- Cloning the ${chalk_1.default.cyan(template)} template...`));
|
|
89
|
-
return EXAMPLES_PATH + template;
|
|
90
|
-
}
|
|
91
|
-
function makeContentfulExampleSource(options) {
|
|
92
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
93
|
-
if (options.example) {
|
|
94
|
-
return selectTemplate(options.example);
|
|
95
|
-
}
|
|
96
|
-
if (options.javascript) {
|
|
97
|
-
return selectTemplate(types_1.ContentfulExample.Javascript);
|
|
98
|
-
}
|
|
99
|
-
if (options.typescript) {
|
|
100
|
-
return selectTemplate(types_1.ContentfulExample.Typescript);
|
|
101
|
-
}
|
|
102
|
-
return yield promptExampleSelection();
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
function getTemplateSource(options) {
|
|
106
|
-
var _a;
|
|
107
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
108
|
-
const source = (_a = options.source) !== null && _a !== void 0 ? _a : (yield makeContentfulExampleSource(options));
|
|
109
|
-
if (options.source && !isContentfulTemplate(source)) {
|
|
110
|
-
(0, logger_1.warn)(`Template at ${(0, logger_1.highlight)(source)} is not an official Contentful app template!`);
|
|
111
|
-
}
|
|
112
|
-
return source;
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
22
|
function clone(source, destination) {
|
|
116
23
|
return __awaiter(this, void 0, void 0, function* () {
|
|
117
24
|
const d = (0, degit_1.default)(source, { mode: 'tar', cache: false });
|
|
@@ -146,9 +53,8 @@ function cleanUp(destination) {
|
|
|
146
53
|
(0, utils_1.rmIfExists)((0, path_1.resolve)(destination, 'package-lock.json'));
|
|
147
54
|
(0, utils_1.rmIfExists)((0, path_1.resolve)(destination, 'yarn.lock'));
|
|
148
55
|
}
|
|
149
|
-
function cloneTemplateIn(destination,
|
|
56
|
+
function cloneTemplateIn(destination, source) {
|
|
150
57
|
return __awaiter(this, void 0, void 0, function* () {
|
|
151
|
-
const source = yield getTemplateSource(options);
|
|
152
58
|
yield clone(source, destination);
|
|
153
59
|
console.log((0, logger_1.success)('Done!'));
|
|
154
60
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/create-contentful-app",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "A template for building Contentful Apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"contentful",
|
|
@@ -35,13 +35,14 @@
|
|
|
35
35
|
"build": "tsc"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@contentful/app-scripts": "1.
|
|
38
|
+
"@contentful/app-scripts": "1.7.0",
|
|
39
|
+
"analytics-node": "^6.2.0",
|
|
39
40
|
"chalk": "4.1.2",
|
|
40
|
-
"commander": "9.
|
|
41
|
+
"commander": "9.5.0",
|
|
41
42
|
"degit": "2.8.4",
|
|
42
43
|
"inquirer": "8.2.5",
|
|
43
44
|
"node-fetch": "2.6.7",
|
|
44
|
-
"rimraf": "
|
|
45
|
+
"rimraf": "4.1.1",
|
|
45
46
|
"tildify": "2.0.0",
|
|
46
47
|
"validate-npm-package-name": "5.0.0"
|
|
47
48
|
},
|
|
@@ -57,6 +58,7 @@
|
|
|
57
58
|
},
|
|
58
59
|
"devDependencies": {
|
|
59
60
|
"@tsconfig/node16": "1.0.3",
|
|
61
|
+
"@types/analytics-node": "^3.1.9",
|
|
60
62
|
"@types/chalk": "2.2.0",
|
|
61
63
|
"@types/degit": "2.8.3",
|
|
62
64
|
"@types/inquirer": "8.2.1",
|
|
@@ -66,5 +68,5 @@
|
|
|
66
68
|
"@types/tildify": "2.0.2",
|
|
67
69
|
"@types/validate-npm-package-name": "4.0.0"
|
|
68
70
|
},
|
|
69
|
-
"gitHead": "
|
|
71
|
+
"gitHead": "dcb14be43822fc3c4afc168de83c7207adf64236"
|
|
70
72
|
}
|