@automattic/vip 2.10.0 → 2.12.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.
Files changed (123) hide show
  1. package/CONTRIBUTING.md +7 -2
  2. package/README.md +27 -0
  3. package/config/{config.json → config.publish.json} +0 -0
  4. package/dist/bin/vip-dev-env-create.js +1 -0
  5. package/dist/bin/vip-dev-env-destroy.js +1 -0
  6. package/dist/bin/vip-dev-env-exec.js +1 -0
  7. package/dist/bin/vip-dev-env-import-media.js +1 -0
  8. package/dist/bin/vip-dev-env-import-sql.js +1 -0
  9. package/dist/bin/vip-dev-env-info.js +1 -0
  10. package/dist/bin/vip-dev-env-list.js +1 -0
  11. package/dist/bin/vip-dev-env-start.js +4 -3
  12. package/dist/bin/vip-dev-env-stop.js +7 -1
  13. package/dist/bin/vip-dev-env-update.js +1 -0
  14. package/dist/bin/vip-import-sql.js +7 -1
  15. package/dist/bin/vip-wp.js +2 -2
  16. package/dist/bin/vip.js +1 -1
  17. package/dist/lib/analytics/clients/pendo.js +92 -0
  18. package/dist/lib/analytics/clients/stub.js +1 -1
  19. package/dist/lib/analytics/clients/tracks.js +0 -5
  20. package/dist/lib/analytics/index.js +21 -4
  21. package/dist/lib/api.js +2 -2
  22. package/dist/lib/cli/config.js +30 -0
  23. package/dist/lib/dev-environment/dev-environment-cli.js +25 -2
  24. package/dist/lib/dev-environment/dev-environment-lando.js +17 -0
  25. package/dist/lib/http/proxy-agent.js +94 -0
  26. package/dist/lib/rollbar.js +1 -1
  27. package/dist/lib/tracker.js +13 -4
  28. package/npm-shrinkwrap.json +319 -133
  29. package/package/dist/bin/vip-app-list.js +73 -0
  30. package/package/dist/bin/vip-app.js +76 -0
  31. package/package/dist/bin/vip-config-envvar-delete.js +97 -0
  32. package/package/dist/bin/vip-config-envvar-get-all.js +94 -0
  33. package/package/dist/bin/vip-config-envvar-get.js +79 -0
  34. package/package/dist/bin/vip-config-envvar-list.js +91 -0
  35. package/package/dist/bin/vip-config-envvar-set.js +123 -0
  36. package/package/dist/bin/vip-config-envvar.js +23 -0
  37. package/package/dist/bin/vip-config.js +20 -0
  38. package/package/dist/bin/vip-dev-env-create.js +105 -0
  39. package/package/dist/bin/vip-dev-env-destroy.js +56 -0
  40. package/package/dist/bin/vip-dev-env-exec.js +67 -0
  41. package/package/dist/bin/vip-dev-env-import-media.js +51 -0
  42. package/package/dist/bin/vip-dev-env-import-sql.js +83 -0
  43. package/package/dist/bin/vip-dev-env-import.js +32 -0
  44. package/package/dist/bin/vip-dev-env-info.js +61 -0
  45. package/package/dist/bin/vip-dev-env-list.js +46 -0
  46. package/package/dist/bin/vip-dev-env-start.js +77 -0
  47. package/package/dist/bin/vip-dev-env-stop.js +52 -0
  48. package/package/dist/bin/vip-dev-env-update.js +89 -0
  49. package/package/dist/bin/vip-dev-env.js +23 -0
  50. package/package/dist/bin/vip-import-media-abort.js +132 -0
  51. package/package/dist/bin/vip-import-media-status.js +84 -0
  52. package/package/dist/bin/vip-import-media.js +168 -0
  53. package/package/dist/bin/vip-import-sql-status.js +83 -0
  54. package/package/dist/bin/vip-import-sql.js +580 -0
  55. package/package/dist/bin/vip-import-validate-files.js +191 -0
  56. package/package/dist/bin/vip-import-validate-sql.js +34 -0
  57. package/package/dist/bin/vip-import.js +20 -0
  58. package/package/dist/bin/vip-logs.js +232 -0
  59. package/package/dist/bin/vip-search-replace.js +71 -0
  60. package/package/dist/bin/vip-sync.js +191 -0
  61. package/package/dist/bin/vip-whoami.js +67 -0
  62. package/package/dist/bin/vip-wp.js +555 -0
  63. package/package/dist/bin/vip.js +149 -0
  64. package/package/dist/lib/analytics/clients/client.js +1 -0
  65. package/package/dist/lib/analytics/clients/pendo.js +92 -0
  66. package/package/dist/lib/analytics/clients/stub.js +19 -0
  67. package/package/dist/lib/analytics/clients/tracks.js +128 -0
  68. package/package/dist/lib/analytics/index.js +45 -0
  69. package/package/dist/lib/api/app.js +70 -0
  70. package/package/dist/lib/api/feature-flags.js +39 -0
  71. package/package/dist/lib/api/user.js +58 -0
  72. package/package/dist/lib/api.js +136 -0
  73. package/package/dist/lib/app-logs/app-logs.js +70 -0
  74. package/package/dist/lib/cli/apiConfig.js +90 -0
  75. package/package/dist/lib/cli/command.js +606 -0
  76. package/package/dist/lib/cli/envAlias.js +60 -0
  77. package/package/dist/lib/cli/exit.js +33 -0
  78. package/package/dist/lib/cli/format.js +213 -0
  79. package/package/dist/lib/cli/pager.js +52 -0
  80. package/package/dist/lib/cli/progress.js +208 -0
  81. package/package/dist/lib/cli/prompt.js +37 -0
  82. package/package/dist/lib/cli/repo.js +77 -0
  83. package/package/dist/lib/client-file-uploader.js +602 -0
  84. package/package/dist/lib/constants/dev-environment.js +42 -0
  85. package/package/dist/lib/constants/file-size.js +14 -0
  86. package/package/dist/lib/dev-environment/dev-environment-cli.js +508 -0
  87. package/package/dist/lib/dev-environment/dev-environment-core.js +620 -0
  88. package/package/dist/lib/dev-environment/dev-environment-lando.js +330 -0
  89. package/package/dist/lib/dev-environment/types.js +1 -0
  90. package/package/dist/lib/env.js +36 -0
  91. package/package/dist/lib/envvar/api-delete.js +56 -0
  92. package/package/dist/lib/envvar/api-get-all.js +59 -0
  93. package/package/dist/lib/envvar/api-get.js +24 -0
  94. package/package/dist/lib/envvar/api-list.js +60 -0
  95. package/package/dist/lib/envvar/api-set.js +58 -0
  96. package/package/dist/lib/envvar/api.js +104 -0
  97. package/package/dist/lib/envvar/input.js +55 -0
  98. package/package/dist/lib/envvar/logging.js +33 -0
  99. package/package/dist/lib/envvar/read-file.js +43 -0
  100. package/{dist → package/dist}/lib/http/socks-proxy-agent.js +0 -0
  101. package/package/dist/lib/keychain/browser.js +35 -0
  102. package/package/dist/lib/keychain/insecure.js +63 -0
  103. package/package/dist/lib/keychain/keychain.js +1 -0
  104. package/package/dist/lib/keychain/secure.js +36 -0
  105. package/package/dist/lib/keychain.js +36 -0
  106. package/package/dist/lib/media-import/media-file-import.js +34 -0
  107. package/package/dist/lib/media-import/progress.js +86 -0
  108. package/package/dist/lib/media-import/status.js +335 -0
  109. package/package/dist/lib/rollbar.js +35 -0
  110. package/package/dist/lib/search-and-replace.js +203 -0
  111. package/package/dist/lib/site-import/db-file-import.js +46 -0
  112. package/package/dist/lib/site-import/status.js +444 -0
  113. package/package/dist/lib/token.js +132 -0
  114. package/package/dist/lib/tracker.js +96 -0
  115. package/package/dist/lib/validations/is-multi-site-sql-dump.js +59 -0
  116. package/package/dist/lib/validations/is-multi-site.js +99 -0
  117. package/package/dist/lib/validations/line-by-line.js +92 -0
  118. package/package/dist/lib/validations/site-type.js +66 -0
  119. package/package/dist/lib/validations/sql.js +371 -0
  120. package/package/dist/lib/vip-import-validate-files.js +548 -0
  121. package/package/vip.iml +11 -0
  122. package/package.json +12 -9
  123. package/helpers/prepare-config.js +0 -19
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.sqlDumpLineIsMultiSite = sqlDumpLineIsMultiSite;
7
+ exports.isMultiSiteDumpFile = isMultiSiteDumpFile;
8
+
9
+ var _lineByLine = require("./line-by-line");
10
+
11
+ var exit = _interopRequireWildcard(require("../cli/exit"));
12
+
13
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
14
+
15
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
16
+
17
+ /**
18
+ *
19
+ * @format
20
+ */
21
+
22
+ /**
23
+ * External dependencies
24
+ */
25
+
26
+ /**
27
+ * Internal dependencies
28
+ */
29
+ const SQL_CREATE_TABLE_IS_MULTISITE_REGEX = /^CREATE TABLE `?(wp_\d+_[a-z0-9_]*|wp_blogs)/i;
30
+ const SQL_CONTAINS_MULTISITE_WP_USERS_REGEX = /\`spam\` tinyint\(2\)|\`deleted\` tinyint\(2\)/i;
31
+
32
+ function sqlDumpLineIsMultiSite(line) {
33
+ // determine if we're on a CREATE TABLE statement line what has eg. wp_\d_options OR wp_blogs
34
+ // also check if we're on a line that defines the additional two columns found on the wp_users table for multisites
35
+ if (SQL_CREATE_TABLE_IS_MULTISITE_REGEX.test(line) || SQL_CONTAINS_MULTISITE_WP_USERS_REGEX.test(line)) {
36
+ return true;
37
+ }
38
+
39
+ return false;
40
+ }
41
+
42
+ function isMultiSiteDumpFile(fileName) {
43
+ return new Promise(async resolve => {
44
+ const readInterface = await (0, _lineByLine.getReadInterface)(fileName);
45
+ readInterface.on('line', line => {
46
+ const result = sqlDumpLineIsMultiSite(line);
47
+
48
+ if (true === result) {
49
+ resolve(true);
50
+ }
51
+ });
52
+ readInterface.on('error', () => {
53
+ exit.withError('An error was encountered while reading your SQL dump file. Please verify the file contents.');
54
+ }); // Block until the processing completes
55
+
56
+ await new Promise(resolveBlock => readInterface.on('close', resolveBlock));
57
+ resolve(false);
58
+ });
59
+ }
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isMultiSiteInSiteMeta = isMultiSiteInSiteMeta;
7
+
8
+ var _graphqlTag = _interopRequireDefault(require("graphql-tag"));
9
+
10
+ var _api = _interopRequireDefault(require("../api"));
11
+
12
+ var _tracker = require("../tracker");
13
+
14
+ var exit = _interopRequireWildcard(require("../cli/exit"));
15
+
16
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
17
+
18
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
19
+
20
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
+
22
+ /**
23
+ *
24
+ * @format
25
+ */
26
+
27
+ /**
28
+ * External dependencies
29
+ */
30
+
31
+ /**
32
+ * Internal dependencies
33
+ */
34
+ const isMultiSite = new WeakMap();
35
+
36
+ async function isMultiSiteInSiteMeta(appId, envId) {
37
+ var _res, _res$data, _res$data$app;
38
+
39
+ const track = _tracker.trackEventWithEnv.bind(null, appId, envId); // if we've already been through this, avoid doing it again within the same process
40
+
41
+
42
+ if (isMultiSite.has(arguments) && 'boolean' === typeof isMultiSite.get(arguments)) {
43
+ return Boolean(isMultiSite.get(arguments));
44
+ }
45
+
46
+ const api = await (0, _api.default)();
47
+ let res;
48
+
49
+ try {
50
+ res = await api.query({
51
+ query: (0, _graphqlTag.default)`
52
+ query AppMultiSiteCheck($appId: Int, $envId: Int) {
53
+ app(id: $appId) {
54
+ id
55
+ name
56
+ repo
57
+ environments(id: $envId) {
58
+ id
59
+ appId
60
+ name
61
+ type
62
+ isMultisite
63
+ isSubdirectoryMultisite
64
+ }
65
+ }
66
+ }
67
+ `,
68
+ variables: {
69
+ appId,
70
+ envId
71
+ }
72
+ });
73
+ } catch (GraphQlError) {
74
+ await track('import_sql_command_error', {
75
+ error_type: 'GraphQL-MultiSite-Check-failed',
76
+ gql_err: GraphQlError
77
+ });
78
+ exit.withError(`StartImport call failed: ${GraphQlError}`);
79
+ }
80
+
81
+ if (Array.isArray((_res = res) === null || _res === void 0 ? void 0 : (_res$data = _res.data) === null || _res$data === void 0 ? void 0 : (_res$data$app = _res$data.app) === null || _res$data$app === void 0 ? void 0 : _res$data$app.environments)) {
82
+ const environments = res.data.app.environments;
83
+
84
+ if (!environments.length) {
85
+ isMultiSite.set(arguments, false);
86
+ return false;
87
+ } // we asked for one result with one appId and one envId, so...
88
+
89
+
90
+ const thisEnv = environments[0];
91
+
92
+ if (thisEnv.isMultiSite || thisEnv.isSubdirectoryMultisite) {
93
+ isMultiSite.set(arguments, true);
94
+ return true;
95
+ }
96
+ }
97
+
98
+ return false;
99
+ }
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getReadInterface = getReadInterface;
7
+ exports.fileLineValidations = fileLineValidations;
8
+
9
+ var _readline = _interopRequireDefault(require("readline"));
10
+
11
+ var _fs = _interopRequireDefault(require("fs"));
12
+
13
+ var _debug = _interopRequireDefault(require("debug"));
14
+
15
+ var exit = _interopRequireWildcard(require("../cli/exit"));
16
+
17
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
18
+
19
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
20
+
21
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22
+
23
+ /**
24
+ *
25
+ * @format
26
+ */
27
+
28
+ /**
29
+ * External dependencies
30
+ */
31
+
32
+ /**
33
+ * Internal dependencies
34
+ */
35
+ const debug = (0, _debug.default)('vip:validations:line-by-line');
36
+
37
+ function openFile(filename, flags = 'r', mode = 666) {
38
+ return new Promise((resolve, reject) => {
39
+ _fs.default.open(filename, flags, mode, (err, fd) => {
40
+ if (err) {
41
+ return reject(err);
42
+ }
43
+
44
+ resolve(fd);
45
+ });
46
+ });
47
+ }
48
+
49
+ async function getReadInterface(filename) {
50
+ let fd;
51
+
52
+ try {
53
+ fd = await openFile(filename);
54
+ } catch (err) {
55
+ exit.withError('The file at the provided path is either missing or not readable. Please check the input and try again.');
56
+ }
57
+
58
+ return _readline.default.createInterface({
59
+ input: _fs.default.createReadStream('', {
60
+ fd
61
+ }),
62
+ output: null,
63
+ console: false
64
+ });
65
+ }
66
+
67
+ async function fileLineValidations(appId, envId, fileName, validations) {
68
+ const isImport = true;
69
+ const readInterface = await getReadInterface(fileName);
70
+ debug('Validations: ', validations);
71
+ readInterface.on('line', line => {
72
+ validations.map(validation => {
73
+ validation.execute(line);
74
+ });
75
+ });
76
+ readInterface.on('error', err => {
77
+ throw new Error(` Error validating input file: ${err.toString()}`);
78
+ }); // Block until the processing completes
79
+
80
+ await new Promise(resolve => readInterface.on('close', resolve));
81
+ readInterface.close();
82
+ return Promise.all(validations.map(async validation => {
83
+ if (validation.hasOwnProperty('postLineExecutionProcessing') && typeof validation.postLineExecutionProcessing === 'function') {
84
+ return validation.postLineExecutionProcessing({
85
+ fileName,
86
+ isImport,
87
+ appId,
88
+ envId
89
+ });
90
+ }
91
+ }));
92
+ }
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.siteTypeValidations = void 0;
7
+
8
+ var _debug = _interopRequireDefault(require("debug"));
9
+
10
+ var _tracker = require("../tracker");
11
+
12
+ var _isMultiSiteSqlDump = require("./is-multi-site-sql-dump");
13
+
14
+ var _isMultiSite = require("./is-multi-site");
15
+
16
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
+
18
+ /**
19
+ *
20
+ * @format
21
+ */
22
+
23
+ /**
24
+ * External dependencies
25
+ */
26
+
27
+ /**
28
+ * Internal dependencies
29
+ */
30
+ const debug = (0, _debug.default)('vip:vip-import-sql');
31
+ let isMultiSiteSqlDump = false;
32
+ const siteTypeValidations = {
33
+ execute: line => {
34
+ const lineIsMultiSite = (0, _isMultiSiteSqlDump.sqlDumpLineIsMultiSite)(line);
35
+
36
+ if (lineIsMultiSite) {
37
+ isMultiSiteSqlDump = true;
38
+ }
39
+ },
40
+ postLineExecutionProcessing: async ({
41
+ appId,
42
+ envId
43
+ }) => {
44
+ const isMultiSite = await (0, _isMultiSite.isMultiSiteInSiteMeta)(appId, envId);
45
+
46
+ const track = _tracker.trackEventWithEnv.bind(null, appId, envId);
47
+
48
+ debug(`\nAppId: ${appId} is ${isMultiSite ? 'a multisite.' : 'not a multisite'}`);
49
+ debug(`The SQL dump provided is ${isMultiSiteSqlDump ? 'from a multisite.' : 'not from a multisite'}\n`);
50
+
51
+ if (!isMultiSite && isMultiSiteSqlDump) {
52
+ await track('import_sql_command_error', {
53
+ error_type: 'not-multisite-with-multisite-sql-dump'
54
+ });
55
+ throw new Error('You have provided a multisite SQL dump file for import into a single site (non-multisite).');
56
+ }
57
+
58
+ if (isMultiSite && !isMultiSiteSqlDump) {
59
+ await track('import_sql_command_error', {
60
+ error_type: 'subsite-import-without-subsite-sql-dump'
61
+ });
62
+ throw new Error('You have requested a subsite SQL import but have not provided a subsite compatiable SQL dump.');
63
+ }
64
+ }
65
+ };
66
+ exports.siteTypeValidations = siteTypeValidations;
@@ -0,0 +1,371 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.validate = exports.staticSqlValidations = exports.getTableNames = exports.postValidation = void 0;
7
+
8
+ var _chalk = _interopRequireDefault(require("chalk"));
9
+
10
+ var _singleLineLog = require("single-line-log");
11
+
12
+ var exit = _interopRequireWildcard(require("../cli/exit"));
13
+
14
+ var _tracker = require("../tracker");
15
+
16
+ var _lineByLine = require("./line-by-line");
17
+
18
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
19
+
20
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
21
+
22
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
+
24
+ /**
25
+ *
26
+ * @format
27
+ */
28
+
29
+ /**
30
+ * External dependencies
31
+ */
32
+
33
+ /**
34
+ * Internal dependencies
35
+ */
36
+ let problemsFound = 0;
37
+ let lineNum = 1;
38
+ const tableNames = [];
39
+
40
+ function formatError(message) {
41
+ return `${_chalk.default.red('SQL Error:')} ${message}`;
42
+ }
43
+
44
+ function formatRecommendation(message) {
45
+ return `${_chalk.default.yellow('Recommendation:')} ${message}`;
46
+ }
47
+
48
+ const errorCheckFormatter = check => {
49
+ const errors = [];
50
+ const infos = [];
51
+
52
+ if (check.results.length > 0) {
53
+ problemsFound += 1;
54
+ errors.push({
55
+ error: formatError(`${check.message} on line(s) ${check.results.join(', ')}.`),
56
+ recommendation: formatRecommendation(check.recommendation)
57
+ });
58
+ } else {
59
+ infos.push(`✅ ${check.message} was found ${check.results.length} times.`);
60
+ }
61
+
62
+ return {
63
+ errors,
64
+ infos
65
+ };
66
+ };
67
+
68
+ const requiredCheckFormatter = (check, type, isImport) => {
69
+ const errors = [];
70
+ const infos = [];
71
+
72
+ if (check.results.length > 0) {
73
+ infos.push(`✅ ${check.message} was found ${check.results.length} times.`);
74
+
75
+ if (type === 'createTable') {
76
+ if (!isImport) {
77
+ checkTablePrefixes(check.results, errors, infos);
78
+ }
79
+ }
80
+ } else {
81
+ problemsFound += 1;
82
+ errors.push({
83
+ error: formatError(`${check.message} was not found.`),
84
+ recommendation: formatRecommendation(check.recommendation)
85
+ });
86
+ }
87
+
88
+ return {
89
+ errors,
90
+ infos
91
+ };
92
+ };
93
+
94
+ const infoCheckFormatter = check => {
95
+ const infos = [];
96
+ check.results.forEach(item => {
97
+ infos.push(item);
98
+ });
99
+ return {
100
+ errors: [],
101
+ infos
102
+ };
103
+ };
104
+
105
+ function checkTablePrefixes(tables, errors, infos) {
106
+ const wpTables = [],
107
+ notWPTables = [],
108
+ wpMultisiteTables = [];
109
+ tables.forEach(tableName => {
110
+ if (tableName.match(/^wp_(\d+_)/)) {
111
+ wpMultisiteTables.push(tableName);
112
+ } else if (tableName.match(/^wp_/)) {
113
+ wpTables.push(tableName);
114
+ } else if (!tableName.match(/^wp_/)) {
115
+ notWPTables.push(tableName);
116
+ }
117
+ });
118
+
119
+ if (wpTables.length > 0) {
120
+ infos.push(` - wp_ prefix tables found: ${wpTables.length} `);
121
+ }
122
+
123
+ if (notWPTables.length > 0) {
124
+ problemsFound += 1;
125
+ errors.push({
126
+ error: formatError(`tables without wp_ prefix found: ${notWPTables.join(',')}`),
127
+ recommendation: formatRecommendation('Please make sure all table names are prefixed with `wp_`')
128
+ });
129
+ }
130
+
131
+ if (wpMultisiteTables.length > 0) {
132
+ infos.push(` - wp_n_ prefix tables found: ${wpMultisiteTables.length} `);
133
+ }
134
+ }
135
+
136
+ const checks = {
137
+ binaryLogging: {
138
+ matcher: /SET @@SESSION.sql_log_bin/i,
139
+ matchHandler: lineNumber => lineNumber,
140
+ outputFormatter: errorCheckFormatter,
141
+ results: [],
142
+ message: 'SET @@SESSION.sql_log_bin statement',
143
+ excerpt: "'SET @@SESSION.sql_log_bin' statement should not be present (case-insensitive)",
144
+ recommendation: 'Remove these lines'
145
+ },
146
+ trigger: {
147
+ // Match `CREATE (DEFINER=`root`@`host`) TRIGGER`
148
+ matcher: /^CREATE (\(?DEFINER=`?(\w*)(`@`)?(\w*\.*%?)*`?\)?)?(| )TRIGGER/i,
149
+ matchHandler: lineNumber => lineNumber,
150
+ outputFormatter: errorCheckFormatter,
151
+ results: [],
152
+ message: 'TRIGGER statement',
153
+ excerpt: "'TRIGGER' statement should not be present (case-sensitive)",
154
+ recommendation: 'Remove these lines'
155
+ },
156
+ dropDB: {
157
+ matcher: /^DROP DATABASE/i,
158
+ matchHandler: lineNumber => lineNumber,
159
+ outputFormatter: errorCheckFormatter,
160
+ results: [],
161
+ message: 'DROP DATABASE statement',
162
+ excerpt: "'DROP DATABASE' should not be present (case-insensitive)",
163
+ recommendation: 'Remove these lines'
164
+ },
165
+ useStatement: {
166
+ matcher: /^USE /i,
167
+ matchHandler: lineNumber => lineNumber,
168
+ outputFormatter: errorCheckFormatter,
169
+ results: [],
170
+ message: 'USE <DATABASE_NAME> statement',
171
+ excerpt: "'USE <DATABASE_NAME>' should not be present (case-insensitive)",
172
+ recommendation: 'Remove these lines'
173
+ },
174
+ alterUser: {
175
+ matcher: /^(ALTER USER|SET PASSWORD)/i,
176
+ matchHandler: lineNumber => lineNumber,
177
+ outputFormatter: errorCheckFormatter,
178
+ results: [],
179
+ message: 'ALTER USER statement',
180
+ excerpt: "'ALTER USER' should not be present (case-insensitive)",
181
+ recommendation: 'Remove these lines'
182
+ },
183
+ dropTable: {
184
+ matcher: /^DROP TABLE IF EXISTS `?([a-z0-9_]*)/i,
185
+ matchHandler: (lineNumber, results) => results[1],
186
+ outputFormatter: requiredCheckFormatter,
187
+ results: [],
188
+ message: 'DROP TABLE',
189
+ excerpt: "'DROP TABLE IF EXISTS' should be present (case-insensitive)",
190
+ recommendation: 'Check import settings to include DROP TABLE statements'
191
+ },
192
+ createTable: {
193
+ matcher: /^CREATE TABLE (?:IF NOT EXISTS )?`?([a-z0-9_]*)/i,
194
+ matchHandler: (lineNumber, results) => results[1],
195
+ outputFormatter: requiredCheckFormatter,
196
+ results: [],
197
+ message: 'CREATE TABLE',
198
+ excerpt: "'CREATE TABLE' should be present (case-insensitive)",
199
+ recommendation: 'Check import settings to include CREATE TABLE statements'
200
+ },
201
+ siteHomeUrl: {
202
+ matcher: "'(siteurl|home)',\\s?'(.*?)'",
203
+ matchHandler: (lineNumber, results) => results[0],
204
+ outputFormatter: infoCheckFormatter,
205
+ results: [],
206
+ message: 'Siteurl/home matches',
207
+ excerpt: 'Siteurl/home options',
208
+ recommendation: ''
209
+ },
210
+ engineInnoDB: {
211
+ matcher: / ENGINE=(?!(InnoDB))/i,
212
+ matchHandler: lineNumber => lineNumber,
213
+ outputFormatter: errorCheckFormatter,
214
+ results: [],
215
+ message: 'ENGINE != InnoDB',
216
+ excerpt: "'ENGINE=InnoDB' should be present (case-insensitive) for all tables",
217
+ recommendation: "Ensure your application works with InnoDB and update your SQL dump to include only 'ENGINE=InnoDB' engine definitions in 'CREATE TABLE' statements. " + "We suggest you search for all 'ENGINE=X' entries and replace them with 'ENGINE=InnoDB'!"
218
+ }
219
+ };
220
+
221
+ const postValidation = async (filename, isImport = false) => {
222
+ await (0, _tracker.trackEvent)('import_validate_sql_command_execute', {
223
+ is_import: isImport
224
+ });
225
+
226
+ if (!isImport) {
227
+ (0, _singleLineLog.stdout)(`Finished processing ${lineNum} lines.`);
228
+ console.log('\n');
229
+ }
230
+
231
+ const errorSummary = {};
232
+ const checkEntries = Object.entries(checks);
233
+ let formattedErrors = [];
234
+ let formattedInfos = [];
235
+
236
+ for (const [type, check] of checkEntries) {
237
+ const formattedOutput = check.outputFormatter(check, type, isImport);
238
+ formattedErrors = formattedErrors.concat(formattedOutput.errors);
239
+ formattedInfos = formattedInfos.concat(formattedOutput.infos);
240
+ errorSummary[type] = check.results.length;
241
+ } // eslint-disable-next-line camelcase
242
+
243
+
244
+ errorSummary.problems_found = problemsFound;
245
+ const tableNamesSet = new Set(tableNames);
246
+
247
+ if (tableNames.length > tableNamesSet.size) {
248
+ // there was a duplciate table
249
+ problemsFound++;
250
+
251
+ function findDuplicates(arr) {
252
+ const filtered = arr.filter(item => {
253
+ if (tableNamesSet.has(item)) {
254
+ tableNamesSet.delete(item);
255
+ } else {
256
+ return item;
257
+ }
258
+ });
259
+ return [...new Set(filtered)];
260
+ }
261
+
262
+ const duplicates = findDuplicates(tableNames);
263
+ const errorObject = {
264
+ error: formatError('Duplicate table names were found: ' + duplicates.join(',')),
265
+ recommendation: formatRecommendation('Ensure that there are no duplicate tables in your SQL dump')
266
+ };
267
+ formattedErrors = formattedErrors.concat(errorObject);
268
+ }
269
+
270
+ if (problemsFound > 0) {
271
+ await (0, _tracker.trackEvent)('import_validate_sql_command_failure', {
272
+ is_import: isImport,
273
+ error: errorSummary
274
+ });
275
+ const errorOutput = [`SQL validation failed due to ${_chalk.default.red(problemsFound)} error(s)`, ''];
276
+ formattedErrors.forEach(error => {
277
+ errorOutput.push(error.error);
278
+
279
+ if (error.recommendation) {
280
+ errorOutput.push(error.recommendation);
281
+ }
282
+
283
+ errorOutput.push('');
284
+ });
285
+
286
+ if (isImport) {
287
+ throw new Error(errorOutput.join('\n'));
288
+ }
289
+
290
+ exit.withError(errorOutput.join('\n'));
291
+ }
292
+
293
+ if (!isImport) {
294
+ console.log(formattedInfos.join('\n'));
295
+ console.log('');
296
+ }
297
+
298
+ await (0, _tracker.trackEvent)('import_validate_sql_command_success', {
299
+ is_import: isImport
300
+ });
301
+ };
302
+
303
+ exports.postValidation = postValidation;
304
+
305
+ const getTableNames = () => {
306
+ return tableNames;
307
+ };
308
+
309
+ exports.getTableNames = getTableNames;
310
+
311
+ const checkForTableName = line => {
312
+ const matches = line.match(/(?<=^CREATE\sTABLE\s)`?(?:(wp_[\d+_]?\w+))`?/);
313
+
314
+ if (matches) {
315
+ const tableName = matches[1]; // we should only have one match if we have any since we're looking at the start of the string
316
+
317
+ tableNames.push(tableName);
318
+ }
319
+ };
320
+
321
+ const perLineValidations = (line, runAsImport, skipChecks) => {
322
+ if (lineNum % 500 === 0) {
323
+ runAsImport ? '' : (0, _singleLineLog.stdout)(`Reading line ${lineNum} `);
324
+ }
325
+
326
+ checkForTableName(line);
327
+ const checkKeys = Object.keys(checks).filter(checkItem => !skipChecks.includes(checkItem));
328
+ const checkValues = checkKeys.map(checkKey => checks[checkKey]);
329
+ checkValues.forEach(check => {
330
+ const results = line.match(check.matcher);
331
+
332
+ if (results) {
333
+ check.results.push(check.matchHandler(lineNum, results));
334
+ }
335
+ });
336
+ lineNum += 1;
337
+ };
338
+
339
+ const execute = (line, isImport = true, skipChecks = ['useStatement']) => {
340
+ perLineValidations(line, isImport, skipChecks);
341
+ };
342
+
343
+ const postLineExecutionProcessing = async ({
344
+ fileName,
345
+ isImport
346
+ }) => {
347
+ await postValidation(fileName, isImport);
348
+ };
349
+
350
+ const staticSqlValidations = {
351
+ execute,
352
+ postLineExecutionProcessing
353
+ }; // For standalone SQL validations
354
+
355
+ exports.staticSqlValidations = staticSqlValidations;
356
+
357
+ const validate = async (filename, skipChecks = ['useStatement']) => {
358
+ const readInterface = await (0, _lineByLine.getReadInterface)(filename);
359
+ readInterface.on('line', line => {
360
+ execute(line, false, skipChecks);
361
+ }); // Block until the processing completes
362
+
363
+ await new Promise(resolve => readInterface.on('close', resolve));
364
+ readInterface.close();
365
+ await postLineExecutionProcessing({
366
+ filename,
367
+ isImport: false
368
+ });
369
+ };
370
+
371
+ exports.validate = validate;