From b0f4ecdae71a0f49c1270414a355f6c7dffd77a6 Mon Sep 17 00:00:00 2001 From: Nnenna John Date: Sun, 25 Nov 2018 16:09:33 -0800 Subject: [PATCH 01/30] Add Prettier and Husky --- .prettierrc.js | 21 + .vulcan/prettier/index.js | 76 ++++ .vulcan/shared/listChangedFiles.js | 36 ++ .vulcan/shared/pathsByLanguageVersion.js | 18 + package-lock.json | 407 +++++++++++++++++- package.json | 14 +- packages/vulcan-forms/lib/components/Form.jsx | 2 +- 7 files changed, 557 insertions(+), 17 deletions(-) create mode 100644 .prettierrc.js create mode 100644 .vulcan/prettier/index.js create mode 100644 .vulcan/shared/listChangedFiles.js create mode 100644 .vulcan/shared/pathsByLanguageVersion.js diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 000000000..80ae81bc0 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,21 @@ +'use strict'; + +const {esNextPaths} = require('./.vulcan/shared/pathsByLanguageVersion'); + +module.exports = { + bracketSpacing: false, + singleQuote: true, + jsxBracketSameLine: true, + trailingComma: 'es5', + printWidth: 80, + parser: 'babylon', + + overrides: [ + { + files: esNextPaths, + options: { + trailingComma: 'all', + }, + }, + ], +}; \ No newline at end of file diff --git a/.vulcan/prettier/index.js b/.vulcan/prettier/index.js new file mode 100644 index 000000000..3008683dc --- /dev/null +++ b/.vulcan/prettier/index.js @@ -0,0 +1,76 @@ + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +// Based on similar script in Jest +// https://github.com/facebook/jest/blob/a7acc5ae519613647ff2c253dd21933d6f94b47f/scripts/prettier.js + +const chalk = require('chalk'); +const glob = require('glob'); +const prettier = require('prettier'); +const fs = require('fs'); +const listChangedFiles = require('../shared/listChangedFiles'); +const prettierConfigPath = require.resolve('../../.prettierrc'); + +const mode = process.argv[2] || 'check'; +const shouldWrite = mode === 'write' || mode === 'write-changed'; +const onlyChanged = mode === 'check-changed' || mode === 'write-changed'; + +const changedFiles = onlyChanged ? listChangedFiles() : null; +let didWarn = false; +let didError = false; + +const files = glob + .sync('**/*.js', {ignore: '**/node_modules/**'}) + .filter(f => !onlyChanged || changedFiles.has(f)); + +if (!files.length) { + return; +} + +files.forEach(file => { + const options = prettier.resolveConfig.sync(file, { + config: prettierConfigPath, + }); + try { + const input = fs.readFileSync(file, 'utf8'); + if (shouldWrite) { + const output = prettier.format(input, options); + if (output !== input) { + fs.writeFileSync(file, output, 'utf8'); + } + } else { + if (!prettier.check(input, options)) { + if (!didWarn) { + console.log( + '\n' + + chalk.red( + ` This project uses prettier to format all JavaScript code.\n` + ) + + chalk.dim(` Please run `) + + chalk.reset('yarn prettier-all') + + chalk.dim( + ` and add changes to files listed below to your commit:` + ) + + `\n\n` + ); + didWarn = true; + } + console.log(file); + } + } + } catch (error) { + didError = true; + console.log('\n\n' + error.message); + console.log(file); + } +}); + +if (didWarn || didError) { + process.exit(1); +} \ No newline at end of file diff --git a/.vulcan/shared/listChangedFiles.js b/.vulcan/shared/listChangedFiles.js new file mode 100644 index 000000000..65dad80af --- /dev/null +++ b/.vulcan/shared/listChangedFiles.js @@ -0,0 +1,36 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +const execFileSync = require('child_process').execFileSync; + +const exec = (command, args) => { + console.log('> ' + [command].concat(args).join(' ')); + const options = { + cwd: process.cwd(), + env: process.env, + stdio: 'pipe', + encoding: 'utf-8', + }; + return execFileSync(command, args, options); +}; + +const execGitCmd = args => + exec('git', args) + .trim() + .toString() + .split('\n'); + +const listChangedFiles = () => { + const mergeBase = execGitCmd(['merge-base', 'HEAD', 'devel']); + return new Set([ + ...execGitCmd(['diff', '--name-only', '--diff-filter=ACMRTUB', mergeBase]), + ...execGitCmd(['ls-files', '--others', '--exclude-standard']), + ]); +}; + +module.exports = listChangedFiles; diff --git a/.vulcan/shared/pathsByLanguageVersion.js b/.vulcan/shared/pathsByLanguageVersion.js new file mode 100644 index 000000000..1e875de0c --- /dev/null +++ b/.vulcan/shared/pathsByLanguageVersion.js @@ -0,0 +1,18 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +// Files that are transformed and can use ES6/Flow/JSX. +const esNextPaths = [ + // Internal forwarding modules + 'packages/*/*.js', + 'packages/*/*.jsx', +]; + +module.exports = { + esNextPaths, +}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 42640dbd4..49a9d4e8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "Vulcan", - "version": "1.12.9", + "version": "1.12.10", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1326,6 +1326,23 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + }, + "dependencies": { + "callsites": { + "version": "2.0.0", + "resolved": "http://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + } + } + }, "caller-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", @@ -1512,6 +1529,12 @@ "moment": "^2.10.3" } }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, "circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", @@ -1737,6 +1760,30 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cosmiconfig": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.0.7.tgz", + "integrity": "sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.9.0", + "parse-json": "^4.0.0" + }, + "dependencies": { + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + } + } + }, "create-react-class": { "version": "15.6.2", "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.2.tgz", @@ -1756,6 +1803,27 @@ "whatwg-fetch": "2.0.3" } }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + } + } + }, "cross-spawn-async": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz", @@ -2100,6 +2168,15 @@ "iconv-lite": "~0.4.13" } }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, "entities": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", @@ -2771,6 +2848,21 @@ } } }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, "exenv": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", @@ -3171,6 +3263,21 @@ "is-property": "^1.0.0" } }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -3180,9 +3287,9 @@ } }, "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3510,6 +3617,117 @@ "sshpk": "^1.7.0" } }, + "husky": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/husky/-/husky-1.2.0.tgz", + "integrity": "sha512-/ib3+iycykXC0tYIxsyqierikVa9DA2DrT32UEirqNEFVqOj1bFMTgP3jAz8HM7FgC/C8pc/BTUa9MV2GEkZaA==", + "dev": true, + "requires": { + "cosmiconfig": "^5.0.6", + "execa": "^1.0.0", + "find-up": "^3.0.0", + "get-stdin": "^6.0.0", + "is-ci": "^1.2.1", + "pkg-dir": "^3.0.0", + "please-upgrade-node": "^3.1.1", + "read-pkg": "^4.0.1", + "run-node": "^1.0.0", + "slash": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz", + "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", + "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "dev": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "read-pkg": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", + "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", + "dev": true, + "requires": { + "normalize-package-data": "^2.3.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0" + } + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + } + } + }, "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", @@ -3558,6 +3776,33 @@ } } }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "dependencies": { + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, "import-inspector": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-inspector/-/import-inspector-2.0.0.tgz", @@ -3731,6 +3976,15 @@ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=" }, + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, + "requires": { + "ci-info": "^1.5.0" + } + }, "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", @@ -3741,6 +3995,12 @@ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.1.tgz", "integrity": "sha1-9ftqlJlq2ejjdh+/vQkfH8qMToI=" }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, "is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", @@ -4137,6 +4397,12 @@ "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", "dev": true }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -4845,7 +5111,7 @@ "process": "^0.11.9", "punycode": "^1.4.1", "querystring-es3": "^0.2.1", - "readable-stream": "git+https://github.com/meteor/readable-stream.git#2e9112d7d31a2af6e0682db0e18679b1e5fd4694", + "readable-stream": "git+https://github.com/meteor/readable-stream.git#c688cdd193549919b840e8d72a86682d91961e12", "stream-browserify": "^2.0.1", "string_decoder": "^1.0.1", "timers-browserify": "^1.4.2", @@ -5254,11 +5520,6 @@ "resolved": "https://registry.npmjs.org/process/-/process-0.11.9.tgz", "integrity": "sha1-e9WtIapiU+fahoImTx4R0RwDGME=" }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" - }, "public-encrypt": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", @@ -5292,15 +5553,40 @@ "integrity": "sha1-Z0yZdgkBw8QRJ3GjHlIdw0nMCew=" }, "readable-stream": { - "version": "git+https://github.com/meteor/readable-stream.git#2e9112d7d31a2af6e0682db0e18679b1e5fd4694", + "version": "git+https://github.com/meteor/readable-stream.git#c688cdd193549919b840e8d72a86682d91961e12", "from": "git+https://github.com/meteor/readable-stream.git", "requires": { - "inherits": "~2.0.1", + "inherits": "~2.0.3", "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "safe-buffer": "^5.0.1", - "string_decoder": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.0", "util-deprecate": "~1.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "rimraf": { @@ -5595,6 +5881,12 @@ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-0.2.2.tgz", "integrity": "sha1-ddpKkn7liH45BliABltzNkE7MQ0=" }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, "node-fetch": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", @@ -5649,6 +5941,15 @@ "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", "dev": true }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, "nth-check": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", @@ -5819,6 +6120,12 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, "p-limit": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", @@ -5920,6 +6227,12 @@ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", @@ -5981,6 +6294,15 @@ "find-up": "^1.0.0" } }, + "please-upgrade-node": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz", + "integrity": "sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, "pluralize": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", @@ -6107,6 +6429,12 @@ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", "dev": true }, + "prettier": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.15.2.tgz", + "integrity": "sha512-YgPLFFA0CdKL4Eg2IHtUSjzj/BWgszDHiNQAe0VAIBse34148whfdzLagRL+QiKS+YfK5ftB6X4v/MBw8yCoug==", + "dev": true + }, "pretty-format": { "version": "23.2.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-23.2.0.tgz", @@ -6182,6 +6510,16 @@ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -6902,6 +7240,12 @@ "once": "^1.3.0" } }, + "run-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/run-node/-/run-node-1.0.0.tgz", + "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==", + "dev": true + }, "rx-lite": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", @@ -6983,6 +7327,12 @@ "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", "dev": true }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, "send": { "version": "0.16.1", "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", @@ -7206,6 +7556,21 @@ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.0.2.tgz", "integrity": "sha512-zlVXeVUKvo+HEv1e2KQF/csyeMKx2oHvatQ9l6XjCUj3agvC8XGf6R9HvIPDSmp8FNPvx7b5kaEJTRi7CqxtEw==" }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, "shelljs": { "version": "0.7.8", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", @@ -7217,6 +7582,12 @@ "rechoir": "^0.6.2" } }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, "simpl-schema": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/simpl-schema/-/simpl-schema-1.4.2.tgz", @@ -7405,6 +7776,12 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, + "strip-eof": { + "version": "1.0.0", + "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", diff --git a/package.json b/package.json index e46cf3988..a168469a7 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,15 @@ "start": "meteor --settings settings.json", "lint": "eslint --cache --ext .jsx,js packages", "test-unit": "TEST_WATCH=1 meteor test-packages ./packages/* --port 3002 --driver-package meteortesting:mocha --raw-logs", - "test": "npm run test-unit" + "test": "npm run test-unit", + "prettier": "node ./.vulcan/prettier/index.js write-changed", + "prettier-all": "node ./.vulcan/prettier/index.js write" + }, + "husky": { + "hooks": { + "pre-commit": "npm run lint", + "pre-push": "npm run prettier" + } }, "dependencies": { "@babel/runtime": "^7.0.0-beta.38", @@ -93,6 +101,7 @@ "devDependencies": { "autoprefixer": "^6.3.6", "babel-eslint": "^7.0.0", + "babylon": "^6.18.0", "chromedriver": "^2.40.0", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", @@ -108,8 +117,11 @@ "eslint-plugin-prettier": "^2.5.0", "eslint-plugin-react": "^6.7.1", "expect": "^23.4.0", + "glob": "^7.1.3", + "husky": "^1.2.0", "jsdom": "^11.11.0", "jsdom-global": "^3.0.2", + "prettier": "^1.15.2", "selenium-webdriver": "^4.0.0-alpha.1" }, "postcss": { diff --git a/packages/vulcan-forms/lib/components/Form.jsx b/packages/vulcan-forms/lib/components/Form.jsx index 34e929a6a..94ef3f3e0 100644 --- a/packages/vulcan-forms/lib/components/Form.jsx +++ b/packages/vulcan-forms/lib/components/Form.jsx @@ -1051,7 +1051,7 @@ SmartForm.propTypes = { prefilledProps: PropTypes.object, layout: PropTypes.string, fields: PropTypes.arrayOf(PropTypes.string), - addFields: PropTypes.arrayOf(PropTypes.string), + // addFields: PropTypes.arrayOf(PropTypes.string), // Nnenna: Commenting out to pass test. This field is already here 3 lines below. I can delete it. But wanted to be sure. removeFields: PropTypes.arrayOf(PropTypes.string), hideFields: PropTypes.arrayOf(PropTypes.string), // OpenCRUD backwards compatibility addFields: PropTypes.arrayOf(PropTypes.string), // OpenCRUD backwards compatibility From 466cb7d0a65c7e38514cf6dce63b98c0eb61a53f Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Tue, 27 Nov 2018 09:39:51 +0900 Subject: [PATCH 02/30] Make sourceVersion a function --- .../lib/server/sentry-server.js | 4 ++-- packages/vulcan-lib/lib/server/site.js | 4 ++-- packages/vulcan-lib/lib/server/source_version.js | 14 +++++++++++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/packages/vulcan-errors-sentry/lib/server/sentry-server.js b/packages/vulcan-errors-sentry/lib/server/sentry-server.js index 198aad45a..2c9ba1bc2 100644 --- a/packages/vulcan-errors-sentry/lib/server/sentry-server.js +++ b/packages/vulcan-errors-sentry/lib/server/sentry-server.js @@ -1,4 +1,4 @@ -import { getSetting, sourceVersion } from 'meteor/vulcan:core'; +import { getSetting, getSourceVersion } from 'meteor/vulcan:core'; import { addInitFunction, addLogFunction, addUserFunction } from 'meteor/vulcan:errors'; import { serverDSNSetting } from '../modules/settings'; import Sentry from '@sentry/node'; @@ -17,7 +17,7 @@ function initSentryForServer() { dsn: serverDSN, environment, // see https://github.com/zodern/meteor-up/issues/807#issuecomment-346915622 - release: sourceVersion, + release: getSourceVersion(), }); } addInitFunction(initSentryForServer); diff --git a/packages/vulcan-lib/lib/server/site.js b/packages/vulcan-lib/lib/server/site.js index a2b28f6a9..b25b681a4 100644 --- a/packages/vulcan-lib/lib/server/site.js +++ b/packages/vulcan-lib/lib/server/site.js @@ -1,7 +1,7 @@ import { addGraphQLSchema, addGraphQLResolvers, addGraphQLQuery } from '../modules/graphql.js'; import { Utils } from '../modules/utils'; import { getSetting } from '../modules/settings.js'; -import { sourceVersion } from './source_version.js'; +import { getSourceVersion } from './source_version.js'; const siteSchema = `type Site { title: String @@ -18,7 +18,7 @@ const siteResolvers = { title: getSetting('title'), url: getSetting('siteUrl', Meteor.absoluteUrl()), logoUrl: Utils.getLogoUrl(), - sourceVersion, + sourceVersion: getSourceVersion(), }; }, }, diff --git a/packages/vulcan-lib/lib/server/source_version.js b/packages/vulcan-lib/lib/server/source_version.js index d7ca96a98..a7071097a 100644 --- a/packages/vulcan-lib/lib/server/source_version.js +++ b/packages/vulcan-lib/lib/server/source_version.js @@ -8,4 +8,16 @@ or current child process. See https://github.com/zodern/meteor-up/issues/807#issuecomment-346915622 */ -export const sourceVersion = process.env.SOURCE_VERSION || childProcess.execSync('git rev-parse HEAD').toString().trim(); \ No newline at end of file +export const getSourceVersion = () => { + try { + return ( + process.env.SOURCE_VERSION || + childProcess + .execSync('git rev-parse HEAD') + .toString() + .trim() + ); + } catch (error) { + return null; + } +}; From bf440f8511a0a600294d75689b422ad4a4b48ec6 Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Tue, 27 Nov 2018 09:40:13 +0900 Subject: [PATCH 03/30] Add document prop to create.async callbacks --- packages/vulcan-lib/lib/server/mutators.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vulcan-lib/lib/server/mutators.js b/packages/vulcan-lib/lib/server/mutators.js index f0f3ead09..c568f73a8 100644 --- a/packages/vulcan-lib/lib/server/mutators.js +++ b/packages/vulcan-lib/lib/server/mutators.js @@ -132,8 +132,8 @@ export const createMutator = async ({ collection, document, data, currentUser, v // run async callbacks // note: query for document to get fresh document with collection-hooks effects applied - await runCallbacksAsync({ name: `${typeName.toLowerCase()}.create.async`, properties: { insertedDocument, ...callbackProperties }}); - await runCallbacksAsync({ name: '*.create.async', properties: { insertedDocument, ...callbackProperties }}); + await runCallbacksAsync({ name: `${typeName.toLowerCase()}.create.async`, properties: { insertedDocument, document: insertedDocument, ...callbackProperties }}); + await runCallbacksAsync({ name: '*.create.async', properties: { insertedDocument, document: insertedDocument, ...callbackProperties }}); // OpenCRUD backwards compatibility await runCallbacksAsync(`${collectionName.toLowerCase()}.new.async`, insertedDocument, currentUser, collection); From 48092c171e8c5628968c053ead510de3f10dd025 Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Fri, 30 Nov 2018 15:59:07 +0900 Subject: [PATCH 04/30] Add correct id code to intl field missing validation errors --- packages/vulcan-lib/lib/modules/intl.js | 2 +- packages/vulcan-lib/lib/modules/validation.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/vulcan-lib/lib/modules/intl.js b/packages/vulcan-lib/lib/modules/intl.js index 37da511d0..d55d5755c 100644 --- a/packages/vulcan-lib/lib/modules/intl.js +++ b/packages/vulcan-lib/lib/modules/intl.js @@ -87,7 +87,7 @@ export const validateIntlField = function() { if (!hasString) { const originalFieldName = this.key.replace('_intl', ''); errors.push({ - id: '', + id: 'errors.required', path: `${this.key}.${index}`, properties: { name: originalFieldName, locale: locale.id } }); diff --git a/packages/vulcan-lib/lib/modules/validation.js b/packages/vulcan-lib/lib/modules/validation.js index de069fcfb..cafacebab 100644 --- a/packages/vulcan-lib/lib/modules/validation.js +++ b/packages/vulcan-lib/lib/modules/validation.js @@ -26,7 +26,7 @@ export const validateDocument = (document, collection, context) => { let validationErrors = []; // Check validity of inserted document - _.forEach(document, (value, fieldName) => { + Object.keys(document).forEach(fieldName => { const fieldSchema = schema[fieldName]; // 1. check that the current user has permission to insert each field @@ -48,7 +48,8 @@ export const validateDocument = (document, collection, context) => { // eslint-disable-next-line no-console // console.log(error); if (error.type.includes('intlError')) { - validationErrors = validationErrors.concat(JSON.parse(error.type.replace('intlError|', ''))); + const intlError = JSON.parse(error.type.replace('intlError|', '')); + validationErrors = validationErrors.concat(intlError); } else { validationErrors.push({ id: `errors.${error.type}`, From 84ea6d878971eded95f81afa36fb867fb1dbf94f Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Fri, 30 Nov 2018 15:59:27 +0900 Subject: [PATCH 05/30] Make static text work for empty values and numbers --- .../vulcan-ui-bootstrap/lib/components/forms/StaticText.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vulcan-ui-bootstrap/lib/components/forms/StaticText.jsx b/packages/vulcan-ui-bootstrap/lib/components/forms/StaticText.jsx index c4f2a7418..e3f2be854 100644 --- a/packages/vulcan-ui-bootstrap/lib/components/forms/StaticText.jsx +++ b/packages/vulcan-ui-bootstrap/lib/components/forms/StaticText.jsx @@ -2,7 +2,7 @@ import React from 'react'; import { registerComponent } from 'meteor/vulcan:core'; const parseUrl = value => { - return value.slice(0,4) === 'http' ? {value} : value; + return value && value.toString().slice(0,4) === 'http' ? {value} : value; } const StaticComponent = ({ value, label }) => ( From 5e7fab49a1f57c7397e2145dd370ffc7433a4eff Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Fri, 30 Nov 2018 16:28:42 +0900 Subject: [PATCH 06/30] Change how validation callbacks work: iterator is now validationErrors object instead of data/document --- packages/vulcan-lib/lib/server/mutators.js | 45 ++++++++++++++-------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/packages/vulcan-lib/lib/server/mutators.js b/packages/vulcan-lib/lib/server/mutators.js index c568f73a8..4843a9c80 100644 --- a/packages/vulcan-lib/lib/server/mutators.js +++ b/packages/vulcan-lib/lib/server/mutators.js @@ -57,17 +57,19 @@ export const createMutator = async ({ collection, document, data, currentUser, v if (validate) { - const validationErrors = validateDocument(newDocument, collection, context); + let validationErrors = []; + + validationErrors = validationErrors.concat(validateDocument(newDocument, collection, context)); // run validation callbacks - newDocument = await runCallbacks({ name: `${typeName.toLowerCase()}.create.validate`, iterator: newDocument, properties: { ...callbackProperties, validationErrors } }); - newDocument = await runCallbacks({ name: '*.create.validate', iterator: newDocument, properties: { ...callbackProperties, validationErrors } }); + validationErrors = await runCallbacks({ name: `${typeName.toLowerCase()}.create.validate`, iterator: validationErrors, properties: { ...callbackProperties, document: newDocument } }); + validationErrors = await runCallbacks({ name: '*.create.validate', iterator: validationErrors, properties: { ...callbackProperties, document: newDocument } }); // OpenCRUD backwards compatibility newDocument = await runCallbacks(`${collectionName.toLowerCase()}.new.validate`, newDocument, currentUser, validationErrors); if (validationErrors.length) { - const NewDocumentValidationError = createError('app.validation_error', {message: 'app.new_document_validation_error'}); - throw new NewDocumentValidationError({data: {break: true, errors: validationErrors}}); + const CreateDocumentValidationError = createError('app.validation_error', {message: 'app.create_document_validation_error'}); + throw new CreateDocumentValidationError({data: {break: true, errors: validationErrors}}); } } @@ -168,7 +170,7 @@ export const updateMutator = async ({ collection, documentId, selector, data, se throw new Error(`Could not find document to update for selector: ${JSON.stringify(selector)}`); } - const callbackProperties = { document, currentUser, collection, context }; + const callbackProperties = { data, document, currentUser, collection, context }; debug(''); debugGroup(`--------------- start \x1b[36m${collectionName} Update Mutator\x1b[0m ---------------`); @@ -178,11 +180,12 @@ export const updateMutator = async ({ collection, documentId, selector, data, se if (validate) { - let validationErrors; + let validationErrors = []; - validationErrors = validateData(data, document, collection, context); - data = await runCallbacks({ name: `${typeName.toLowerCase()}.update.validate`, iterator: data, properties: { validationErrors, ...callbackProperties }}); - data = await runCallbacks({ name: '*.update.validate', iterator: data, properties: { validationErrors, ...callbackProperties }}); + validationErrors = validationErrors.concat(validateData(data, document, collection, context)); + + validationErrors = await runCallbacks({ name: `${typeName.toLowerCase()}.update.validate`, iterator: validationErrors, properties: callbackProperties }); + validationErrors = await runCallbacks({ name: '*.update.validate', iterator: validationErrors, properties: callbackProperties }); // OpenCRUD backwards compatibility data = modifierToData(await runCallbacks(`${collectionName.toLowerCase()}.edit.validate`, dataToModifier(data), document, currentUser, validationErrors)); @@ -191,8 +194,8 @@ export const updateMutator = async ({ collection, documentId, selector, data, se console.log('// validationErrors'); // eslint-disable-next-line no-console console.log(validationErrors); - const EditDocumentValidationError = createError('app.validation_error', { message: 'app.edit_document_validation_error' }); - throw new EditDocumentValidationError({data: {break: true, errors: validationErrors}}); + const UpdateDocumentValidationError = createError('app.validation_error', { message: 'app.update_document_validation_error' }); + throw new UpdateDocumentValidationError({data: {break: true, errors: validationErrors}}); } } @@ -297,12 +300,24 @@ export const deleteMutator = async ({ collection, documentId, selector, currentU const callbackProperties = { document, currentUser, collection, context }; - // if document is not trusted, run validation callbacks if (validate) { - document = await runCallbacks({ name: `${typeName.toLowerCase()}.delete.validate`, iterator: document, properties: callbackProperties }); - document = await runCallbacks({ name: '*.delete.validate', iterator: document, properties: callbackProperties }); + + let validationErrors = []; + + validationErrors = await runCallbacks({ name: `${typeName.toLowerCase()}.delete.validate`, iterator: validationErrors, properties: callbackProperties }); + validationErrors = await runCallbacks({ name: '*.delete.validate', iterator: validationErrors, properties: callbackProperties }); // OpenCRUD backwards compatibility document = await runCallbacks(`${collectionName.toLowerCase()}.remove.validate`, document, currentUser); + + if (validationErrors.length) { + // eslint-disable-next-line no-console + console.log('// validationErrors'); + // eslint-disable-next-line no-console + console.log(validationErrors); + const DeleteDocumentValidationError = createError('app.validation_error', { message: 'app.delete_document_validation_error' }); + throw new DeleteDocumentValidationError({data: {break: true, errors: validationErrors}}); + } + } // run onRemove step From 6d088ba5d6ab19835d43b97d45e6d4fda3ed95a2 Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Fri, 30 Nov 2018 17:26:32 +0900 Subject: [PATCH 07/30] Remove unnecessary "forceLocale" argument --- packages/vulcan-lib/lib/server/intl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vulcan-lib/lib/server/intl.js b/packages/vulcan-lib/lib/server/intl.js index 5aecf05e6..aa4627aa7 100644 --- a/packages/vulcan-lib/lib/server/intl.js +++ b/packages/vulcan-lib/lib/server/intl.js @@ -137,7 +137,7 @@ Take a header object, and figure out the locale Also accepts userLocale to indicate the current user's preferred locale */ -export const getHeaderLocale = (headers, forceLocale, userLocale) => { +export const getHeaderLocale = (headers, userLocale) => { let cookieLocale, acceptedLocale, locale, localeMethod; From 8330accba704baf5f6049045fea94f2aa5e0ba25 Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Sun, 2 Dec 2018 10:01:48 +0900 Subject: [PATCH 08/30] centralize error throwing in new throwError function --- .../lib/modules/default_resolvers.js | 6 ++---- packages/vulcan-errors/lib/modules/index.js | 2 +- packages/vulcan-lib/lib/modules/errors.js | 19 ++++++++++++++++++- packages/vulcan-lib/lib/modules/utils.js | 5 +++-- packages/vulcan-lib/lib/server/mutators.js | 11 ++++------- .../lib/server/integrations/mailchimp.js | 6 ++---- packages/vulcan-voting/lib/modules/vote.js | 6 ++---- 7 files changed, 32 insertions(+), 23 deletions(-) diff --git a/packages/vulcan-core/lib/modules/default_resolvers.js b/packages/vulcan-core/lib/modules/default_resolvers.js index 586c5c148..9e2d99e68 100644 --- a/packages/vulcan-core/lib/modules/default_resolvers.js +++ b/packages/vulcan-core/lib/modules/default_resolvers.js @@ -4,8 +4,7 @@ Default list, single, and total resolvers */ -import { Utils, debug, debugGroup, debugGroupEnd, Connectors, getTypeName, getCollectionName } from 'meteor/vulcan:lib'; -import { createError } from 'apollo-errors'; +import { Utils, debug, debugGroup, debugGroupEnd, Connectors, getTypeName, getCollectionName, throwError } from 'meteor/vulcan:lib'; const defaultOptions = { cacheMaxAge: 300 @@ -118,8 +117,7 @@ export function getDefaultResolvers(options) { if (allowNull) { return { result: null }; } else { - const MissingDocumentError = createError('app.missing_document', { message: 'app.missing_document' }); - throw new MissingDocumentError({ data: { documentId, selector } }); + throwError({ id: 'app.missing_document', data: {documentId, selector} }); } } diff --git a/packages/vulcan-errors/lib/modules/index.js b/packages/vulcan-errors/lib/modules/index.js index 56d1cded1..5d60bbdef 100644 --- a/packages/vulcan-errors/lib/modules/index.js +++ b/packages/vulcan-errors/lib/modules/index.js @@ -1,3 +1,3 @@ import '../components/ErrorsUserMonitor'; import '../components/ErrorCatcher'; -export * from './errors'; +export * from './errors.js'; \ No newline at end of file diff --git a/packages/vulcan-lib/lib/modules/errors.js b/packages/vulcan-lib/lib/modules/errors.js index 219f5bd63..f51d27e5e 100644 --- a/packages/vulcan-lib/lib/modules/errors.js +++ b/packages/vulcan-lib/lib/modules/errors.js @@ -1,3 +1,5 @@ +import { createError } from 'apollo-errors'; + /* Get whatever word is contained between the first two double quotes @@ -89,4 +91,19 @@ export const getErrors = error => { } } return errors; -} \ No newline at end of file +} + +/* + +An error should have: + +- id: will be used as i18n key (note: available as `name` on the client) +- message: optionally, a plain-text message +- data: data/values to give more context to the error + +*/ +export const throwError = error => { + const { id, message = id, data } = error; + const MissingDocumentError = createError(id, { message }); + throw new MissingDocumentError({ id, data }); +}; \ No newline at end of file diff --git a/packages/vulcan-lib/lib/modules/utils.js b/packages/vulcan-lib/lib/modules/utils.js index 326866227..2e7e44ceb 100644 --- a/packages/vulcan-lib/lib/modules/utils.js +++ b/packages/vulcan-lib/lib/modules/utils.js @@ -14,6 +14,7 @@ import { getCollection } from './collections.js'; import set from 'lodash/set'; import get from 'lodash/get'; import isFunction from 'lodash/isFunction'; +import { throwError } from './errors.js'; registerSetting('debug', false, 'Enable debug mode (more verbose logging)'); @@ -491,11 +492,11 @@ Utils.defineName = (o, name) => { Utils.performCheck = (operation, user, checkedObject, context, documentId, operationName, collectionName) => { if (!checkedObject) { - throw new Error(Utils.encodeIntlError({id: 'app.document_not_found', value: documentId})) + throwError({ id: 'app.document_not_found', data: { documentId, operationName } }); } if (!operation(user, checkedObject, context)) { - throw new Error(Utils.encodeIntlError({id: 'app.operation_not_allowed', value: operationName, documentId })); + throwError({ id: 'app.operation_not_allowed', data: { documentId, operationName } }); } } diff --git a/packages/vulcan-lib/lib/server/mutators.js b/packages/vulcan-lib/lib/server/mutators.js index 4843a9c80..79ca69679 100644 --- a/packages/vulcan-lib/lib/server/mutators.js +++ b/packages/vulcan-lib/lib/server/mutators.js @@ -28,10 +28,10 @@ to the client. */ import { runCallbacks, runCallbacksAsync } from '../modules/index.js'; -import { createError } from 'apollo-errors'; import { validateDocument, validateData, dataToModifier, modifierToData } from '../modules/validation.js'; import { registerSetting } from '../modules/settings.js'; import { debug, debugGroup, debugGroupEnd } from '../modules/debug.js'; +import { throwError } from '../modules/errors.js'; import { Connectors } from './connectors.js'; import pickBy from 'lodash/pickBy'; import clone from 'lodash/clone'; @@ -68,8 +68,7 @@ export const createMutator = async ({ collection, document, data, currentUser, v newDocument = await runCallbacks(`${collectionName.toLowerCase()}.new.validate`, newDocument, currentUser, validationErrors); if (validationErrors.length) { - const CreateDocumentValidationError = createError('app.validation_error', {message: 'app.create_document_validation_error'}); - throw new CreateDocumentValidationError({data: {break: true, errors: validationErrors}}); + throwError({ id: 'app.validation_error', data: {break: true, errors: validationErrors}}); } } @@ -194,8 +193,7 @@ export const updateMutator = async ({ collection, documentId, selector, data, se console.log('// validationErrors'); // eslint-disable-next-line no-console console.log(validationErrors); - const UpdateDocumentValidationError = createError('app.validation_error', { message: 'app.update_document_validation_error' }); - throw new UpdateDocumentValidationError({data: {break: true, errors: validationErrors}}); + throwError({ id: 'app.validation_error', data: {break: true, errors: validationErrors}}); } } @@ -314,8 +312,7 @@ export const deleteMutator = async ({ collection, documentId, selector, currentU console.log('// validationErrors'); // eslint-disable-next-line no-console console.log(validationErrors); - const DeleteDocumentValidationError = createError('app.validation_error', { message: 'app.delete_document_validation_error' }); - throw new DeleteDocumentValidationError({data: {break: true, errors: validationErrors}}); + throwError({id: 'app.validation_error', data: {break: true, errors: validationErrors}}); } } diff --git a/packages/vulcan-newsletter/lib/server/integrations/mailchimp.js b/packages/vulcan-newsletter/lib/server/integrations/mailchimp.js index 50a5b42c3..3bc96cba9 100644 --- a/packages/vulcan-newsletter/lib/server/integrations/mailchimp.js +++ b/packages/vulcan-newsletter/lib/server/integrations/mailchimp.js @@ -3,10 +3,9 @@ // newsletter scheduling with MailChimp import moment from 'moment'; -import { getSetting, registerSetting } from 'meteor/vulcan:core'; +import { getSetting, registerSetting, throwError } from 'meteor/vulcan:core'; import Newsletters from '../../modules/collection.js'; import MailChimpNPM from 'mailchimp'; -import { createError } from 'apollo-errors'; registerSetting('mailchimp', null, 'MailChimp settings'); @@ -59,8 +58,7 @@ if (settings) { } else { name = 'subscription_failed'; } - const NewsletterError = createError(name, { message }); - throw new NewsletterError({ data: {path: 'newsletter_subscribeToNewsletter', message}}); + throwError({ id: name, message, data: {path: 'newsletter_subscribeToNewsletter', message}}); } }, diff --git a/packages/vulcan-voting/lib/modules/vote.js b/packages/vulcan-voting/lib/modules/vote.js index 9c7f6800c..86339bbd9 100644 --- a/packages/vulcan-voting/lib/modules/vote.js +++ b/packages/vulcan-voting/lib/modules/vote.js @@ -1,5 +1,4 @@ -import { Connectors, debug, debugGroup, debugGroupEnd /* runCallbacksAsync, runCallbacks, addCallback */ } from 'meteor/vulcan:core'; -import { createError } from 'apollo-errors'; +import { Connectors, debug, debugGroup, debugGroupEnd, throwError /* runCallbacksAsync, runCallbacks, addCallback */ } from 'meteor/vulcan:core'; import Votes from './votes/collection.js'; import Users from 'meteor/vulcan:users'; import { recalculateScore } from './scoring.js'; @@ -289,8 +288,7 @@ export const performVoteServer = async ({ documentId, document, voteType = 'upvo const voteOptions = {document, collection, voteType, user, voteId, updateDocument}; if (!document || !user || !Users.canDo(user, `${collectionName.toLowerCase()}.${voteType}`)) { - const VoteError = createError('voting.no_permission', {message: 'voting.no_permission'}); - throw new VoteError(); + throwError({ id: 'voting.no_permission' }); } const existingVote = await hasVotedServer({document, voteType, user}); From 50315bcf73ef4d640e931d8fad0a9808b02e1107 Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Sun, 2 Dec 2018 10:28:04 +0900 Subject: [PATCH 09/30] Fix linting --- packages/vulcan-core/lib/modules/components/App.jsx | 2 +- .../lib/components/ErrorsUserMonitor.jsx | 7 +++---- packages/vulcan-errors/lib/modules/errors.js | 12 ++++++------ packages/vulcan-errors/package.js | 8 ++++---- packages/vulcan-forms-tags/lib/components/Tags.jsx | 3 --- packages/vulcan-forms/lib/components/Form.jsx | 2 -- .../lib/components/FormNestedDivider.jsx | 1 - .../vulcan-forms/lib/components/FormNestedFoot.jsx | 1 - .../vulcan-forms/lib/components/FormNestedHead.jsx | 1 - packages/vulcan-forms/lib/components/propTypes.js | 5 +++-- packages/vulcan-lib/lib/modules/collections.js | 2 +- packages/vulcan-lib/lib/modules/utils.js | 4 ++-- packages/vulcan-lib/lib/server/utils.js | 1 - 13 files changed, 20 insertions(+), 29 deletions(-) diff --git a/packages/vulcan-core/lib/modules/components/App.jsx b/packages/vulcan-core/lib/modules/components/App.jsx index 896d6f586..5bc556d68 100644 --- a/packages/vulcan-core/lib/modules/components/App.jsx +++ b/packages/vulcan-core/lib/modules/components/App.jsx @@ -7,7 +7,7 @@ import { detectLocale, hasIntlFields, } from 'meteor/vulcan:lib'; -import React, { PureComponent, Fragment } from 'react'; +import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { IntlProvider, intlShape } from 'meteor/vulcan:i18n'; import withCurrentUser from '../containers/withCurrentUser.js'; diff --git a/packages/vulcan-errors/lib/components/ErrorsUserMonitor.jsx b/packages/vulcan-errors/lib/components/ErrorsUserMonitor.jsx index bbb31f984..c5b01e2c8 100644 --- a/packages/vulcan-errors/lib/components/ErrorsUserMonitor.jsx +++ b/packages/vulcan-errors/lib/components/ErrorsUserMonitor.jsx @@ -24,10 +24,9 @@ class ErrorsUserMonitor extends PureComponent { const errorsUserId = Errors.currentUser && Errors.currentUser._id; if (currentUserId !== errorsUserId) { - const currentUserEmail = currentUser && currentUser.email; - const errorsUserEmail = Errors.currentUser && Errors.currentUser.email; - - console.log(`User changed from ${errorsUserEmail} (${errorsUserId}) to ${currentUserEmail} (${currentUserId})`); + // const currentUserEmail = currentUser && currentUser.email; + // const errorsUserEmail = Errors.currentUser && Errors.currentUser.email; + // console.log(`User changed from ${errorsUserEmail} (${errorsUserId}) to ${currentUserEmail} (${currentUserId})`); Errors.setCurrentUser(currentUser); } diff --git a/packages/vulcan-errors/lib/modules/errors.js b/packages/vulcan-errors/lib/modules/errors.js index 508bd96d1..fffc6e48f 100644 --- a/packages/vulcan-errors/lib/modules/errors.js +++ b/packages/vulcan-errors/lib/modules/errors.js @@ -1,10 +1,10 @@ -import Users from 'meteor/vulcan:users'; -import { getSetting } from 'meteor/vulcan:core'; -import get from 'lodash/get'; +// import Users from 'meteor/vulcan:users'; +// import { getSetting } from 'meteor/vulcan:core'; +// import get from 'lodash/get'; import isEqual from 'lodash/isEqual'; -import { formatMessage } from 'meteor/vulcan:i18n'; -import _isEmpty from 'lodash/isEmpty'; -import { inspect } from 'util'; +// import { formatMessage } from 'meteor/vulcan:i18n'; +// import _isEmpty from 'lodash/isEmpty'; +// import { inspect } from 'util'; export const initFunctions = []; export const logFunctions = []; diff --git a/packages/vulcan-errors/package.js b/packages/vulcan-errors/package.js index 5b3be9a30..c97aef3f7 100644 --- a/packages/vulcan-errors/package.js +++ b/packages/vulcan-errors/package.js @@ -1,8 +1,8 @@ Package.describe({ - name: "vulcan:errors", - summary: "Vulcan error tracking package", + name: 'vulcan:errors', + summary: 'Vulcan error tracking package', version: '1.12.10', - git: "https://github.com/VulcanJS/Vulcan.git" + git: 'https://github.com/VulcanJS/Vulcan.git' }); Package.onUse(function(api) { @@ -14,7 +14,7 @@ Package.onUse(function(api) { 'vulcan:core@1.12.10', ]); - api.mainModule("lib/server/main.js", "server"); + api.mainModule('lib/server/main.js', 'server'); api.mainModule('lib/client/main.js', 'client'); }); diff --git a/packages/vulcan-forms-tags/lib/components/Tags.jsx b/packages/vulcan-forms-tags/lib/components/Tags.jsx index c557e3c46..41ab31cd1 100644 --- a/packages/vulcan-forms-tags/lib/components/Tags.jsx +++ b/packages/vulcan-forms-tags/lib/components/Tags.jsx @@ -1,12 +1,9 @@ import React, { PureComponent } from 'react'; -import FRC from 'formsy-react-components'; import ReactTagInput from 'react-tag-input'; import PropTypes from 'prop-types'; const ReactTags = ReactTagInput.WithContext; -const Input = FRC.Input; - class Tags extends PureComponent { constructor(props) { diff --git a/packages/vulcan-forms/lib/components/Form.jsx b/packages/vulcan-forms/lib/components/Form.jsx index 34e929a6a..9ba3720ef 100644 --- a/packages/vulcan-forms/lib/components/Form.jsx +++ b/packages/vulcan-forms/lib/components/Form.jsx @@ -26,7 +26,6 @@ import { registerComponent, Components, runCallbacks, - getCollection, getErrors, getSetting, Utils, @@ -1054,7 +1053,6 @@ SmartForm.propTypes = { addFields: PropTypes.arrayOf(PropTypes.string), removeFields: PropTypes.arrayOf(PropTypes.string), hideFields: PropTypes.arrayOf(PropTypes.string), // OpenCRUD backwards compatibility - addFields: PropTypes.arrayOf(PropTypes.string), // OpenCRUD backwards compatibility showRemove: PropTypes.bool, submitLabel: PropTypes.node, cancelLabel: PropTypes.node, diff --git a/packages/vulcan-forms/lib/components/FormNestedDivider.jsx b/packages/vulcan-forms/lib/components/FormNestedDivider.jsx index 465293875..aceb25d22 100644 --- a/packages/vulcan-forms/lib/components/FormNestedDivider.jsx +++ b/packages/vulcan-forms/lib/components/FormNestedDivider.jsx @@ -1,7 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import { registerComponent } from 'meteor/vulcan:core'; -import { FormattedMessage } from 'meteor/vulcan:i18n'; const FormNestedDivider = ({ label, addItem }) =>
; diff --git a/packages/vulcan-forms/lib/components/FormNestedFoot.jsx b/packages/vulcan-forms/lib/components/FormNestedFoot.jsx index 379f4adb1..4a3fa9914 100644 --- a/packages/vulcan-forms/lib/components/FormNestedFoot.jsx +++ b/packages/vulcan-forms/lib/components/FormNestedFoot.jsx @@ -1,7 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Components, registerComponent } from 'meteor/vulcan:core'; -import { FormattedMessage } from 'meteor/vulcan:i18n'; const FormNestedFoot = ({ label, addItem }) => ( diff --git a/packages/vulcan-forms/lib/components/FormNestedHead.jsx b/packages/vulcan-forms/lib/components/FormNestedHead.jsx index 88b77ca3c..aa4f338fd 100644 --- a/packages/vulcan-forms/lib/components/FormNestedHead.jsx +++ b/packages/vulcan-forms/lib/components/FormNestedHead.jsx @@ -1,7 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import { registerComponent } from 'meteor/vulcan:core'; -import { FormattedMessage } from 'meteor/vulcan:i18n'; const FormNestedHead = ({ label, addItem }) => ( diff --git a/packages/vulcan-forms/lib/components/propTypes.js b/packages/vulcan-forms/lib/components/propTypes.js index d2350b65d..1cdd329fc 100644 --- a/packages/vulcan-forms/lib/components/propTypes.js +++ b/packages/vulcan-forms/lib/components/propTypes.js @@ -1,7 +1,7 @@ /** PropTypes for documentation purpose (not tested yet) */ import PropTypes from 'prop-types'; -const fieldProps = { +export const fieldProps = { // defaultValue: PropTypes.any, help: PropTypes.string, @@ -28,7 +28,8 @@ const fieldProps = { nestedInput: PropTypes.boolean, // flag nestedFields: PropTypes.array //arrayOf(fieldProps) }; -const groupProps = { + +export const groupProps = { name: PropTypes.string.isRequired, label: PropTypes.string.isRequired, order: PropTypes.number, diff --git a/packages/vulcan-lib/lib/modules/collections.js b/packages/vulcan-lib/lib/modules/collections.js index ae21b9369..6790d9a45 100644 --- a/packages/vulcan-lib/lib/modules/collections.js +++ b/packages/vulcan-lib/lib/modules/collections.js @@ -48,7 +48,6 @@ Mongo.Collection.prototype.attachSchema = function(schemaOrFields) { */ Mongo.Collection.prototype.addField = function(fieldOrFieldArray) { const collection = this; - const schema = collection.simpleSchema()._schema; const fieldSchema = {}; const fieldArray = Array.isArray(fieldOrFieldArray) ? fieldOrFieldArray : [fieldOrFieldArray]; @@ -313,6 +312,7 @@ export const createCollection = options => { } }); } else { + // eslint-disable-next-line no-console console.warn( `Warning: terms.query is set but schema ${ collection.options.typeName diff --git a/packages/vulcan-lib/lib/modules/utils.js b/packages/vulcan-lib/lib/modules/utils.js index 2e7e44ceb..fdc14cee4 100644 --- a/packages/vulcan-lib/lib/modules/utils.js +++ b/packages/vulcan-lib/lib/modules/utils.js @@ -170,13 +170,13 @@ Utils.slugify = function (s) { return slug; }; Utils.getUnusedSlug = function (collection, slug) { - let suffix = ""; + let suffix = ''; let index = 0; // test if slug is already in use while (!!collection.findOne({slug: slug+suffix})) { index++; - suffix = "-"+index; + suffix = '-'+index; } return slug+suffix; diff --git a/packages/vulcan-lib/lib/server/utils.js b/packages/vulcan-lib/lib/server/utils.js index f345c15c6..bccf5f1b1 100644 --- a/packages/vulcan-lib/lib/server/utils.js +++ b/packages/vulcan-lib/lib/server/utils.js @@ -1,5 +1,4 @@ import sanitizeHtml from 'sanitize-html'; -import { Connectors } from './connectors'; import { Utils } from '../modules'; Utils.sanitize = function(s) { From 3d920138b227eaac4da0d0b61f033e528abded7e Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Sun, 2 Dec 2018 10:53:24 +0900 Subject: [PATCH 10/30] Pass document to callback --- .../vulcan-core/lib/modules/components/EditButton.jsx | 8 ++++---- packages/vulcan-core/lib/modules/components/NewButton.jsx | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/vulcan-core/lib/modules/components/EditButton.jsx b/packages/vulcan-core/lib/modules/components/EditButton.jsx index 026084f9e..4ad5be21e 100644 --- a/packages/vulcan-core/lib/modules/components/EditButton.jsx +++ b/packages/vulcan-core/lib/modules/components/EditButton.jsx @@ -32,15 +32,15 @@ EditForm Component const EditForm = ({ closeModal, successCallback, removeSuccessCallback, ...props }) => { const success = successCallback - ? () => { - successCallback(); + ? document => { + successCallback(document); closeModal(); } : closeModal; const remove = removeSuccessCallback - ? () => { - removeSuccessCallback(); + ? document => { + removeSuccessCallback(document); closeModal(); } : closeModal; diff --git a/packages/vulcan-core/lib/modules/components/NewButton.jsx b/packages/vulcan-core/lib/modules/components/NewButton.jsx index 1451ff8bf..a7a3c88d5 100644 --- a/packages/vulcan-core/lib/modules/components/NewButton.jsx +++ b/packages/vulcan-core/lib/modules/components/NewButton.jsx @@ -31,8 +31,8 @@ NewForm Component const NewForm = ({ closeModal, successCallback, ...props }) => { const success = successCallback - ? () => { - successCallback(); + ? document => { + successCallback(document); closeModal(); } : closeModal; From a58c1ad22bc5841dd4091b037b90d3d8851acdec Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Sun, 2 Dec 2018 22:33:45 +0900 Subject: [PATCH 11/30] Pass form instance to callbacks --- packages/vulcan-forms/lib/components/Form.jsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/vulcan-forms/lib/components/Form.jsx b/packages/vulcan-forms/lib/components/Form.jsx index 9ba3720ef..f0349f2bd 100644 --- a/packages/vulcan-forms/lib/components/Form.jsx +++ b/packages/vulcan-forms/lib/components/Form.jsx @@ -850,7 +850,7 @@ class SmartForm extends Component { mutationSuccessCallback = (result, mutationType) => { this.setState(prevState => ({ disabled: false })); - const document = result.data[Object.keys(result.data)[0]].data; // document is always on first property + let document = result.data[Object.keys(result.data)[0]].data; // document is always on first property // for new mutation, run refetch function if it exists if (mutationType === 'new' && this.props.refetch) this.props.refetch(); @@ -865,10 +865,10 @@ class SmartForm extends Component { } // run document through mutation success callbacks - result = runCallbacks(this.successFormCallbacks, result); + document = runCallbacks(this.successFormCallbacks, document, { form: this }); // run success callback if it exists - if (this.props.successCallback) this.props.successCallback(document); + if (this.props.successCallback) this.props.successCallback(document, { form: this }); }; // catch graphql errors @@ -881,7 +881,7 @@ class SmartForm extends Component { console.log(error); // run mutation failure callbacks on error, we do not allow the callbacks to change the error - runCallbacks(this.failureFormCallbacks, error); + runCallbacks(this.failureFormCallbacks, error, { form: this }); if (!_.isEmpty(error)) { // add error to state @@ -889,7 +889,7 @@ class SmartForm extends Component { } // run error callback if it exists - if (this.props.errorCallback) this.props.errorCallback(document, error); + if (this.props.errorCallback) this.props.errorCallback(document, error, { form: this }); // scroll back up to show error messages Utils.scrollIntoView('.flash-message'); From dea838ecceee692bdf2cbf6acddd4739c1312dad Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Sun, 2 Dec 2018 22:33:57 +0900 Subject: [PATCH 12/30] Add google analytics event tracking --- packages/vulcan-events-ga/lib/client/ga.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/vulcan-events-ga/lib/client/ga.js b/packages/vulcan-events-ga/lib/client/ga.js index 6eb126937..a08eb0bd7 100644 --- a/packages/vulcan-events-ga/lib/client/ga.js +++ b/packages/vulcan-events-ga/lib/client/ga.js @@ -1,5 +1,5 @@ import { getSetting } from 'meteor/vulcan:core'; -import { addPageFunction, addInitFunction } from 'meteor/vulcan:events'; +import { addPageFunction, addInitFunction, addTrackFunction } from 'meteor/vulcan:events'; /* @@ -19,10 +19,25 @@ function googleAnaticsTrackPage() { } return {}; } - // add client-side callback: log a ga request on page view addPageFunction(googleAnaticsTrackPage); +function googleAnaticsTrackEvent(name, properties, currentUser) { + const { category = name, action = name, label = name, value } = properties; + if (window && window.ga) { + window.ga('send', { + hitType: 'event', + eventCategory: category, + eventAction: action, + eventLabel: label, + eventValue: value, + }); + } + return {}; +} +// add client-side callback: log a ga request on page view +addTrackFunction(googleAnaticsTrackEvent); + function googleAnalyticsInit() { // get the google analytics id from the settings const googleAnalyticsId = getSetting('googleAnalytics.apiKey'); From 8e878258b8864a868d4f37d699c0f3ecad09a8c9 Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Sun, 2 Dec 2018 22:34:03 +0900 Subject: [PATCH 13/30] Hide profile field --- packages/vulcan-users/lib/modules/schema.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/vulcan-users/lib/modules/schema.js b/packages/vulcan-users/lib/modules/schema.js index 0a4b20f5c..bd16e6fb6 100644 --- a/packages/vulcan-users/lib/modules/schema.js +++ b/packages/vulcan-users/lib/modules/schema.js @@ -111,6 +111,7 @@ const schema = { type: Object, optional: true, blackbox: true, + hidden: true, canCreate: ['members'], }, // // telescope-specific data, kept for backward compatibility and migration purposes From 5d12dbef478d7f55928eaff66d90ca8d49c5d2e8 Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Tue, 4 Dec 2018 15:57:19 +0900 Subject: [PATCH 14/30] Add onClick props to ModalTrigger and Checkout button (useful for analytics tracking) --- .../lib/components/Checkout.jsx | 8 ++++++++ .../lib/components/ui/ModalTrigger.jsx | 18 ++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/packages/vulcan-payments/lib/components/Checkout.jsx b/packages/vulcan-payments/lib/components/Checkout.jsx index c6ce831f5..b7cdcc0c4 100644 --- a/packages/vulcan-payments/lib/components/Checkout.jsx +++ b/packages/vulcan-payments/lib/components/Checkout.jsx @@ -20,6 +20,12 @@ class Checkout extends React.Component { }; } + handleOpen = () => { + if (this.props.onClick) { + this.props.onClick(); + } + } + onToken(token) { const {paymentActionMutation, productKey, associatedCollection, associatedDocument, callback, successCallback, errorCallback, properties, currentUser, flash, coupon} = this.props; @@ -88,6 +94,7 @@ class Checkout extends React.Component { return (
{ diff --git a/packages/vulcan-ui-bootstrap/lib/components/ui/ModalTrigger.jsx b/packages/vulcan-ui-bootstrap/lib/components/ui/ModalTrigger.jsx index 37afdb206..075b8420c 100644 --- a/packages/vulcan-ui-bootstrap/lib/components/ui/ModalTrigger.jsx +++ b/packages/vulcan-ui-bootstrap/lib/components/ui/ModalTrigger.jsx @@ -5,18 +5,23 @@ import PropTypes from 'prop-types'; class ModalTrigger extends PureComponent { constructor() { super(); - this.openModal = this.openModal.bind(this); - this.closeModal = this.closeModal.bind(this); this.state = { modalIsOpen: false, }; } - openModal() { + clickHandler = () => { + if (this.props.onClick) { + this.props.onClick(); + } + this.openModal(); + } + + openModal = () => { this.setState({ modalIsOpen: true }); } - closeModal() { + closeModal = () => { this.setState({ modalIsOpen: false }); } @@ -37,9 +42,9 @@ class ModalTrigger extends PureComponent { let triggerComponent = trigger || component; triggerComponent = triggerComponent ? ( - React.cloneElement(triggerComponent, { onClick: this.openModal }) + React.cloneElement(triggerComponent, { onClick: this.clickHandler }) ) : ( - + {label} ); @@ -75,6 +80,7 @@ ModalTrigger.propTypes = { trigger: PropTypes.object, size: PropTypes.string, title: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), + onClick: PropTypes.func, }; registerComponent('ModalTrigger', ModalTrigger); From 626ab25fcef3400c8557b03a33f6fec752e92dbe Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Tue, 4 Dec 2018 15:57:34 +0900 Subject: [PATCH 15/30] Fix token Stripe error --- packages/vulcan-payments/lib/server/integrations/stripe.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/vulcan-payments/lib/server/integrations/stripe.js b/packages/vulcan-payments/lib/server/integrations/stripe.js index 24905238e..5555404ad 100644 --- a/packages/vulcan-payments/lib/server/integrations/stripe.js +++ b/packages/vulcan-payments/lib/server/integrations/stripe.js @@ -128,8 +128,10 @@ export const receiveAction = async (args) => { Retrieve or create a Stripe customer */ -export const getCustomer = async (user, id) => { +export const getCustomer = async (user, token) => { + const { id } = token; + let customer; try { From 82d320cea7952a661e1612ae0bd1a549eac148b3 Mon Sep 17 00:00:00 2001 From: neobii Date: Wed, 5 Dec 2018 06:14:17 -0600 Subject: [PATCH 16/30] added refetch to props on withSingle --- packages/vulcan-core/lib/modules/containers/withSingle.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/vulcan-core/lib/modules/containers/withSingle.js b/packages/vulcan-core/lib/modules/containers/withSingle.js index 01ad490cf..9fde46e38 100644 --- a/packages/vulcan-core/lib/modules/containers/withSingle.js +++ b/packages/vulcan-core/lib/modules/containers/withSingle.js @@ -44,6 +44,7 @@ export default function withSingle(options) { const propertyName = options.propertyName || 'document'; const props = { loading: data.loading, + refetch: data.refetch, // document: Utils.convertDates(collection, data[singleResolverName]), [propertyName]: data[resolverName] && data[resolverName].result, fragmentName, From e5885cabd7f85aebc04f5dd6782b13a97b248f73 Mon Sep 17 00:00:00 2001 From: neobii Date: Wed, 5 Dec 2018 05:11:48 -0600 Subject: [PATCH 17/30] added english field errors --- packages/vulcan-i18n-en-us/lib/en_US.js | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/vulcan-i18n-en-us/lib/en_US.js b/packages/vulcan-i18n-en-us/lib/en_US.js index 71ebe385f..0d3bc3b3b 100644 --- a/packages/vulcan-i18n-en-us/lib/en_US.js +++ b/packages/vulcan-i18n-en-us/lib/en_US.js @@ -136,10 +136,23 @@ addStrings('en', { 'admin': 'Admin', 'notifications': 'Notifications', - 'errors.expectedType': 'Expected a field “{label}” of type {dataType}, got “{value}” instead.', + 'errors.expectedType': 'Expected type {dataType} for field “{label}”, received “{value}“ instead.', 'errors.required': 'Field “{label}” is required.', - 'errors.maxString': 'Field “{label}” is limited to {max} characters.', + 'errors.minString': 'Field “{label}“ needs to have at least {min} characters', + 'errors.maxString': 'Field “{label}“ is limited to {max} characters.', 'errors.generic': 'Sorry, something went wrong: {errorMessage}.', 'errors.generic_report': 'Sorry, something went wrong: {errorMessage}.
An error report has been generated.', - -}); + 'errors.minNumber': 'Field “{label}“ must be higher than {min}. ', + 'errors.maxNumber': 'Field “{label}“ must be lower than {max}. ', + 'errors.minCount': 'There needs to be at least {count} in field “{label}“.', + 'errors.maxCount': 'Field “{label}“ is only allowed {count}.', + 'errors.regEx': 'Field “{label}“: wrong formatting', + 'errors.badDate': 'Field “{label}“ is not a date.', + 'errors.notAllowed': 'The value for field “{label}“ is not allowed.', + 'errors.noDecimal': 'The value for field “{label}“ must not be a decimal number.', + //TODO other simple schema errors + 'errors.minNumberExclusive': '', + 'errors.maxNumberExclusive': '', + 'errors.keyNotInSchema': '' + +}); \ No newline at end of file From e6137df423a5c6d1bbf29d3028088ab8d488ec73 Mon Sep 17 00:00:00 2001 From: neobii Date: Wed, 5 Dec 2018 08:49:36 -0600 Subject: [PATCH 18/30] corrected quotes --- packages/vulcan-i18n-en-us/lib/en_US.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/vulcan-i18n-en-us/lib/en_US.js b/packages/vulcan-i18n-en-us/lib/en_US.js index 0d3bc3b3b..a3d51b219 100644 --- a/packages/vulcan-i18n-en-us/lib/en_US.js +++ b/packages/vulcan-i18n-en-us/lib/en_US.js @@ -136,20 +136,20 @@ addStrings('en', { 'admin': 'Admin', 'notifications': 'Notifications', - 'errors.expectedType': 'Expected type {dataType} for field “{label}”, received “{value}“ instead.', + 'errors.expectedType': 'Expected type {dataType} for field “{label}”, received “{value}” instead.', 'errors.required': 'Field “{label}” is required.', - 'errors.minString': 'Field “{label}“ needs to have at least {min} characters', - 'errors.maxString': 'Field “{label}“ is limited to {max} characters.', + 'errors.minString': 'Field “{label}” needs to have at least {min} characters', + 'errors.maxString': 'Field “{label}” is limited to {max} characters.', 'errors.generic': 'Sorry, something went wrong: {errorMessage}.', 'errors.generic_report': 'Sorry, something went wrong: {errorMessage}.
An error report has been generated.', - 'errors.minNumber': 'Field “{label}“ must be higher than {min}. ', - 'errors.maxNumber': 'Field “{label}“ must be lower than {max}. ', - 'errors.minCount': 'There needs to be at least {count} in field “{label}“.', - 'errors.maxCount': 'Field “{label}“ is only allowed {count}.', - 'errors.regEx': 'Field “{label}“: wrong formatting', - 'errors.badDate': 'Field “{label}“ is not a date.', - 'errors.notAllowed': 'The value for field “{label}“ is not allowed.', - 'errors.noDecimal': 'The value for field “{label}“ must not be a decimal number.', + 'errors.minNumber': 'Field “{label}” must be higher than {min}. ', + 'errors.maxNumber': 'Field “{label}” must be lower than {max}. ', + 'errors.minCount': 'There needs to be at least {count} in field “{label}”.', + 'errors.maxCount': 'Field “{label}” is only allowed {count}.', + 'errors.regEx': 'Field “{label}”: wrong formatting', + 'errors.badDate': 'Field “{label}” is not a date.', + 'errors.notAllowed': 'The value for field “{label}” is not allowed.', + 'errors.noDecimal': 'The value for field “{label}” must not be a decimal number.', //TODO other simple schema errors 'errors.minNumberExclusive': '', 'errors.maxNumberExclusive': '', From 9f7a43c8236efc52192ad39f88c4834d178306c8 Mon Sep 17 00:00:00 2001 From: neobii Date: Fri, 7 Dec 2018 02:37:36 -0600 Subject: [PATCH 19/30] added minCount and maxCount to show SmartForm array fields --- .../lib/components/FormNestedArray.jsx | 26 ++++++++++++------- .../lib/components/FormNestedItem.jsx | 4 +-- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/vulcan-forms/lib/components/FormNestedArray.jsx b/packages/vulcan-forms/lib/components/FormNestedArray.jsx index 81e19b4d3..2ef659374 100644 --- a/packages/vulcan-forms/lib/components/FormNestedArray.jsx +++ b/packages/vulcan-forms/lib/components/FormNestedArray.jsx @@ -58,8 +58,13 @@ class FormNestedArray extends PureComponent { 'inputProperties', 'nestedInput' ); - const { errors, path, label, formComponents } = this.props; + const { errors, path, label, formComponents, minCount, maxCount } = this.props; const FormComponents = formComponents; + + //filter out null values to calculate array length + let arrayLength = value.filter(singleValue => { + return !!singleValue; + }).length; // only keep errors specific to the nested array (and not its subfields) const nestedArrayErrors = errors.filter( error => error.path && error.path === path @@ -81,6 +86,7 @@ class FormNestedArray extends PureComponent { removeItem={() => { this.removeItem(i); }} + hideRemove={minCount && arrayLength <= minCount} /> ) ), - + !maxCount || arrayValue < maxCount && ( + - , + + ), hasErrors ? ( { const FormComponents = mergeWithComponents(formComponents); @@ -46,7 +46,7 @@ const FormNestedItem = ( ); })} removeButton={ - isArray && [ + isArray && !hideRemove && [
Date: Fri, 7 Dec 2018 04:45:17 -0600 Subject: [PATCH 20/30] populate initial values if minCount is supplied --- packages/vulcan-forms/lib/components/Form.jsx | 14 ++++++++++++++ .../lib/components/FormNestedArray.jsx | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/vulcan-forms/lib/components/Form.jsx b/packages/vulcan-forms/lib/components/Form.jsx index f0349f2bd..7aefc24ae 100644 --- a/packages/vulcan-forms/lib/components/Form.jsx +++ b/packages/vulcan-forms/lib/components/Form.jsx @@ -97,6 +97,20 @@ const getInitialStateFromProps = nextProps => { nextProps.prefilledProps, nextProps.document ); + + //if minCount is specified, go ahead and create empty nested documents + Object.keys(convertedSchema).forEach(key => { + let minCount = convertedSchema[key].minCount; + if(minCount) { + if(!initialDocument[key]) + initialDocument[key] = []; + let toAdd = minCount - initialDocument[key].length; + for( let i = 0; i < toAdd; i++ ) { + initialDocument[key].push({}); + } + } + }) + // remove all instances of the `__typename` property from document Utils.removeProperty(initialDocument, '__typename'); diff --git a/packages/vulcan-forms/lib/components/FormNestedArray.jsx b/packages/vulcan-forms/lib/components/FormNestedArray.jsx index 2ef659374..83fae038a 100644 --- a/packages/vulcan-forms/lib/components/FormNestedArray.jsx +++ b/packages/vulcan-forms/lib/components/FormNestedArray.jsx @@ -65,6 +65,7 @@ class FormNestedArray extends PureComponent { let arrayLength = value.filter(singleValue => { return !!singleValue; }).length; + // only keep errors specific to the nested array (and not its subfields) const nestedArrayErrors = errors.filter( error => error.path && error.path === path @@ -95,7 +96,7 @@ class FormNestedArray extends PureComponent { ) ), - !maxCount || arrayValue < maxCount && ( + !maxCount || arrayLength < maxCount && ( Date: Fri, 7 Dec 2018 05:31:56 -0600 Subject: [PATCH 21/30] fixed bug if maxCount was not speficied --- packages/vulcan-forms/lib/components/FormNestedArray.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/vulcan-forms/lib/components/FormNestedArray.jsx b/packages/vulcan-forms/lib/components/FormNestedArray.jsx index 83fae038a..96ab98528 100644 --- a/packages/vulcan-forms/lib/components/FormNestedArray.jsx +++ b/packages/vulcan-forms/lib/components/FormNestedArray.jsx @@ -65,13 +65,13 @@ class FormNestedArray extends PureComponent { let arrayLength = value.filter(singleValue => { return !!singleValue; }).length; - + // only keep errors specific to the nested array (and not its subfields) const nestedArrayErrors = errors.filter( error => error.path && error.path === path ); const hasErrors = nestedArrayErrors && nestedArrayErrors.length; - + return ( ) ), - !maxCount || arrayLength < maxCount && ( + (!maxCount || arrayLength < maxCount) && ( Date: Fri, 7 Dec 2018 05:45:47 -0600 Subject: [PATCH 22/30] more elegant code --- packages/vulcan-forms/lib/components/Form.jsx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/vulcan-forms/lib/components/Form.jsx b/packages/vulcan-forms/lib/components/Form.jsx index 7aefc24ae..0baeca4b5 100644 --- a/packages/vulcan-forms/lib/components/Form.jsx +++ b/packages/vulcan-forms/lib/components/Form.jsx @@ -102,12 +102,9 @@ const getInitialStateFromProps = nextProps => { Object.keys(convertedSchema).forEach(key => { let minCount = convertedSchema[key].minCount; if(minCount) { - if(!initialDocument[key]) - initialDocument[key] = []; - let toAdd = minCount - initialDocument[key].length; - for( let i = 0; i < toAdd; i++ ) { + initialDocument[key] = initialDocument[key] || []; + while(initialDocument[key].length < minCount) initialDocument[key].push({}); - } } }) @@ -150,7 +147,7 @@ class SmartForm extends Component { }; } - defaultValues = {}; + defaultValues = {}; submitFormCallbacks = []; successFormCallbacks = []; From e350c5d281a45f80764ad5fc39d96330fd407ae7 Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Mon, 10 Dec 2018 15:49:25 +0900 Subject: [PATCH 23/30] Avoid siteData errors --- packages/vulcan-errors/lib/components/ErrorCatcher.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vulcan-errors/lib/components/ErrorCatcher.jsx b/packages/vulcan-errors/lib/components/ErrorCatcher.jsx index 9570f951a..b8be2f322 100644 --- a/packages/vulcan-errors/lib/components/ErrorCatcher.jsx +++ b/packages/vulcan-errors/lib/components/ErrorCatcher.jsx @@ -20,7 +20,7 @@ class ErrorCatcher extends Component { }; componentDidCatch = (error, errorInfo) => { - const { currentUser, siteData } = this.props; + const { currentUser, siteData = {} } = this.props; const { sourceVersion } = siteData; this.setState({ error }); Errors.log({ From c79b991176400806a78a3c8d16095f50f8b3943c Mon Sep 17 00:00:00 2001 From: Sara Itani Date: Mon, 10 Dec 2018 11:11:04 -0800 Subject: [PATCH 24/30] Allow user to customize apollo json parser options In particular, the functionality is currently scoped to the maximum request body size (`limit`), which helps avoid errors like `PayloadTooLargeError: request entity too large` Keys defined here: https://www.npmjs.com/package/body-parser#bodyparserjsonoptions --- packages/vulcan-lib/lib/server/apollo_server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vulcan-lib/lib/server/apollo_server.js b/packages/vulcan-lib/lib/server/apollo_server.js index e3bcf391e..0588fdbfb 100644 --- a/packages/vulcan-lib/lib/server/apollo_server.js +++ b/packages/vulcan-lib/lib/server/apollo_server.js @@ -127,7 +127,7 @@ const createApolloServer = (givenOptions = {}, givenConfig = {}) => { graphQLServer.use(compression()); // GraphQL endpoint - graphQLServer.use(config.path, bodyParser.json(), graphqlExpress(async (req) => { + graphQLServer.use(config.path, bodyParser.json({ limit: getSetting('apolloServer.jsonParserOptions.limit') }), graphqlExpress(async (req) => { let options; let user = null; From baea826800016e09a7d73a8ef09c94c5ab4b9315 Mon Sep 17 00:00:00 2001 From: neobii Date: Tue, 11 Dec 2018 03:25:17 -0600 Subject: [PATCH 25/30] added collection creation hook --- .../vulcan-lib/lib/modules/collections.js | 117 ++++++++++++------ 1 file changed, 80 insertions(+), 37 deletions(-) diff --git a/packages/vulcan-lib/lib/modules/collections.js b/packages/vulcan-lib/lib/modules/collections.js index 6790d9a45..af2cb0c9e 100644 --- a/packages/vulcan-lib/lib/modules/collections.js +++ b/packages/vulcan-lib/lib/modules/collections.js @@ -2,7 +2,7 @@ import { Mongo } from 'meteor/mongo'; import SimpleSchema from 'simpl-schema'; import { addGraphQLCollection, addToGraphQLContext } from './graphql.js'; import { Utils } from './utils.js'; -import { runCallbacks, runCallbacksAsync } from './callbacks.js'; +import { runCallbacks, runCallbacksAsync, registerCallback, addCallback } from './callbacks.js'; import { getSetting, registerSetting } from './settings.js'; import { registerFragment, getDefaultFragmentText } from './fragments.js'; import escapeStringRegexp from 'escape-string-regexp'; @@ -125,10 +125,10 @@ export const createCollection = options => { const { typeName, collectionName = getCollectionName(typeName), - schema, generateGraphQLSchema = true, dbCollectionName } = options; + let { schema } = options; // initialize new Mongo collection const collection = @@ -152,40 +152,12 @@ export const createCollection = options => { // add views collection.views = []; - // generate foo_intl fields - Object.keys(schema).forEach(fieldName => { - const fieldSchema = schema[fieldName]; - if (isIntlField(fieldSchema)) { - // we have at least one intl field - hasIntlFields = true; + //register individual collection callback + registerCollectionCallback(collectionName); - // remove `intl` to avoid treating new _intl field as a field to internationalize - // eslint-disable-next-line no-unused-vars - const { intl, ...propertiesToCopy } = schema[fieldName]; - - schema[`${fieldName}_intl`] = { - ...propertiesToCopy, // copy properties from regular field - hidden: true, - type: Array, - isIntlData: true - }; - - delete schema[`${fieldName}_intl`].intl; - - schema[`${fieldName}_intl.$`] = { - type: getIntlString() - }; - - // if original field is required, enable custom validation function instead of `optional` property - if (!schema[fieldName].optional) { - schema[`${fieldName}_intl`].optional = true; - schema[`${fieldName}_intl`].custom = validateIntlField; - } - - // make original non-intl field optional - schema[fieldName].optional = true; - } - }); + //run schema callbacks and run general callbacks last + schema = runCallbacks({ name: `${collectionName}.collection`, iterator: schema, properties: { options }}); + schema = runCallbacks({ name: '*.collection', iterator: schema, properties: { options }}); if (schema) { // attach schema to collection @@ -202,8 +174,8 @@ export const createCollection = options => { addGraphQLCollection(collection); } - runCallbacksAsync({ name: '*.collection', properties: { options } }); - runCallbacksAsync({ name: `${collectionName}.collection`, properties: { options } }); + runCallbacksAsync({ name: '*.collection.async', properties: { options } }); + runCallbacksAsync({ name: `${collectionName}.collection.async`, properties: { options } }); // ------------------------------------- Default Fragment -------------------------------- // @@ -335,3 +307,74 @@ export const createCollection = options => { return collection; }; + +//register collection creation hook for each collection +function registerCollectionCallback(typeName) { + registerCallback({ + name: `${typeName}.collection`, + iterator: { schema: 'the schema of the collection' }, + properties: [ + { schema: 'The schema of the collection' }, + { validationErrors: 'An Object that can be used to accumulate validation errors' } + ], + runs: 'sync', + returns: 'schema', + description: 'Modifies schemas on collection creation' + }) +} + +//register colleciton creation hook +registerCallback({ + name: `*.collection`, + iterator: { schema: 'the schema of the collection' }, + properties: [ + { schema: 'The schema of the collection' }, + { validationErrors: 'An object that can be used to accumulate validation errors' } + ], + runs: 'sync', + returns: 'schema', + description: 'Modifies schemas on collection creation', +}); + +// generate foo_intl fields +function addIntlFields(schema) { + Object.keys(schema).forEach(fieldName => { + const fieldSchema = schema[fieldName]; + if (isIntlField(fieldSchema)) { + // we have at least one intl field + hasIntlFields = true; + + // remove `intl` to avoid treating new _intl field as a field to internationalize + // eslint-disable-next-line no-unused-vars + const { intl, ...propertiesToCopy } = schema[fieldName]; + + schema[`${fieldName}_intl`] = { + ...propertiesToCopy, // copy properties from regular field + hidden: true, + type: Array, + isIntlData: true + }; + + delete schema[`${fieldName}_intl`].intl; + + schema[`${fieldName}_intl.$`] = { + type: getIntlString() + }; + + // if original field is required, enable custom validation function instead of `optional` property + if (!schema[fieldName].optional) { + schema[`${fieldName}_intl`].optional = true; + schema[`${fieldName}_intl`].custom = validateIntlField; + } + + // make original non-intl field optional + schema[fieldName].optional = true; + } + }); + return schema; +}; + +//register intl callback very last +Meteor.startup(() => { + addCallback(`*.collection`, addIntlFields); +}); \ No newline at end of file From c7423bc74e85e9487564a92f637a6d8fd784c0d0 Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Wed, 12 Dec 2018 17:35:25 +0900 Subject: [PATCH 26/30] fix linting; "document" prop of update async callbacks should be new, updated document --- packages/vulcan-lib/lib/modules/collections.js | 6 +++--- packages/vulcan-lib/lib/server/mutators.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/vulcan-lib/lib/modules/collections.js b/packages/vulcan-lib/lib/modules/collections.js index af2cb0c9e..ca809aced 100644 --- a/packages/vulcan-lib/lib/modules/collections.js +++ b/packages/vulcan-lib/lib/modules/collections.js @@ -325,7 +325,7 @@ function registerCollectionCallback(typeName) { //register colleciton creation hook registerCallback({ - name: `*.collection`, + name: '*.collection', iterator: { schema: 'the schema of the collection' }, properties: [ { schema: 'The schema of the collection' }, @@ -372,9 +372,9 @@ function addIntlFields(schema) { } }); return schema; -}; +} //register intl callback very last Meteor.startup(() => { - addCallback(`*.collection`, addIntlFields); + addCallback('*.collection', addIntlFields); }); \ No newline at end of file diff --git a/packages/vulcan-lib/lib/server/mutators.js b/packages/vulcan-lib/lib/server/mutators.js index 79ca69679..bfd63d5f4 100644 --- a/packages/vulcan-lib/lib/server/mutators.js +++ b/packages/vulcan-lib/lib/server/mutators.js @@ -258,8 +258,8 @@ export const updateMutator = async ({ collection, documentId, selector, data, se newDocument = await runCallbacks(`${collectionName.toLowerCase()}.edit.after`, newDocument, document, currentUser); // run async callbacks - await runCallbacksAsync({ name: `${typeName.toLowerCase()}.update.async`, properties: { newDocument, ...callbackProperties }}); - await runCallbacksAsync({ name: '*.update.async', properties: { newDocument, ...callbackProperties }}); + await runCallbacksAsync({ name: `${typeName.toLowerCase()}.update.async`, properties: { ...callbackProperties,newDocument, document: newDocument, oldDocument: document }}); + await runCallbacksAsync({ name: '*.update.async', properties: { ...callbackProperties, newDocument, document: newDocument, oldDocument: document }}); // OpenCRUD backwards compatibility await runCallbacksAsync(`${collectionName.toLowerCase()}.edit.async`, newDocument, document, currentUser, collection); From 33ab51972ea23e907f2bf9e05e82bc3ea360a58a Mon Sep 17 00:00:00 2001 From: Sara Itani Date: Thu, 13 Dec 2018 12:45:20 -0800 Subject: [PATCH 27/30] Support form id attribute --- packages/vulcan-forms/lib/components/Form.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/vulcan-forms/lib/components/Form.jsx b/packages/vulcan-forms/lib/components/Form.jsx index 0baeca4b5..9eca8453b 100644 --- a/packages/vulcan-forms/lib/components/Form.jsx +++ b/packages/vulcan-forms/lib/components/Form.jsx @@ -991,6 +991,7 @@ class SmartForm extends Component { return (
{ From b05b35ed572c6f754dfcf0af9cd8f746bc505747 Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Sat, 15 Dec 2018 15:10:18 +0900 Subject: [PATCH 28/30] v1.12.11 --- package.json | 2 +- packages/vulcan-accounts/package.js | 4 ++-- packages/vulcan-admin/package.js | 4 ++-- packages/vulcan-cloudinary/package.js | 4 ++-- packages/vulcan-core/package.js | 14 +++++++------- packages/vulcan-debug/package.js | 6 +++--- packages/vulcan-email/package.js | 4 ++-- packages/vulcan-embed/package.js | 4 ++-- packages/vulcan-errors-sentry/package.js | 8 ++++---- packages/vulcan-errors/package.js | 4 ++-- packages/vulcan-events-ga/package.js | 6 +++--- packages/vulcan-events-intercom/package.js | 6 +++--- packages/vulcan-events-internal/package.js | 6 +++--- packages/vulcan-events-segment/package.js | 6 +++--- packages/vulcan-events/package.js | 4 ++-- packages/vulcan-forms-tags/package.js | 6 +++--- packages/vulcan-forms-upload/package.js | 6 +++--- packages/vulcan-forms/package.js | 4 ++-- packages/vulcan-i18n-en-us/package.js | 4 ++-- packages/vulcan-i18n-es-es/package.js | 4 ++-- packages/vulcan-i18n-fr-fr/package.js | 4 ++-- packages/vulcan-i18n/package.js | 4 ++-- packages/vulcan-lib/lib/modules/config.js | 2 +- packages/vulcan-lib/package.js | 2 +- packages/vulcan-newsletter/package.js | 6 +++--- packages/vulcan-payments/package.js | 4 ++-- packages/vulcan-routing/package.js | 4 ++-- packages/vulcan-subscribe/package.js | 10 +++++----- packages/vulcan-ui-bootstrap/package.js | 4 ++-- packages/vulcan-users/package.js | 4 ++-- packages/vulcan-voting/package.js | 6 +++--- 31 files changed, 78 insertions(+), 78 deletions(-) diff --git a/package.json b/package.json index e46cf3988..11958dfa0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Vulcan", - "version": "1.12.10", + "version": "1.12.11", "engines": { "npm": "^3.0" }, diff --git a/packages/vulcan-accounts/package.js b/packages/vulcan-accounts/package.js index 0c9d212ae..362dbf959 100755 --- a/packages/vulcan-accounts/package.js +++ b/packages/vulcan-accounts/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'vulcan:accounts', - version: '1.12.10', + version: '1.12.11', summary: 'Accounts UI for React in Meteor 1.3+', git: 'https://github.com/studiointeract/accounts-ui', documentation: 'README.md' @@ -9,7 +9,7 @@ Package.describe({ Package.onUse(function(api) { api.versionsFrom('1.6.1'); - api.use('vulcan:core@1.12.10'); + api.use('vulcan:core@1.12.11'); api.use('ecmascript'); api.use('tracker'); diff --git a/packages/vulcan-admin/package.js b/packages/vulcan-admin/package.js index 10ed166f7..459aded50 100644 --- a/packages/vulcan-admin/package.js +++ b/packages/vulcan-admin/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:admin', summary: 'Vulcan components package', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -14,7 +14,7 @@ Package.onUse(function (api) { 'fourseven:scss@4.10.0', 'dynamic-import@0.1.1', // Vulcan packages - 'vulcan:core@1.12.10', + 'vulcan:core@1.12.11', ]); diff --git a/packages/vulcan-cloudinary/package.js b/packages/vulcan-cloudinary/package.js index 39aa32aad..ebb36d585 100644 --- a/packages/vulcan-cloudinary/package.js +++ b/packages/vulcan-cloudinary/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:cloudinary', summary: 'Vulcan file upload package.', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -10,7 +10,7 @@ Package.onUse(function (api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:core@1.12.10' + 'vulcan:core@1.12.11' ]); api.mainModule('lib/client/main.js', 'client'); diff --git a/packages/vulcan-core/package.js b/packages/vulcan-core/package.js index 7f212f568..fa4114c9b 100644 --- a/packages/vulcan-core/package.js +++ b/packages/vulcan-core/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:core', summary: 'Vulcan core package', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -9,14 +9,14 @@ Package.onUse(function (api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:lib@1.12.10', - 'vulcan:i18n@1.12.10', - 'vulcan:users@1.12.10', - 'vulcan:routing@1.12.10', - 'vulcan:debug@1.12.10' + 'vulcan:lib@1.12.11', + 'vulcan:i18n@1.12.11', + 'vulcan:users@1.12.11', + 'vulcan:routing@1.12.11', + 'vulcan:debug@1.12.11' ]); - api.imply(['vulcan:lib@1.12.10']); + api.imply(['vulcan:lib@1.12.11']); api.mainModule('lib/server/main.js', 'server'); api.mainModule('lib/client/main.js', 'client'); diff --git a/packages/vulcan-debug/package.js b/packages/vulcan-debug/package.js index 626520b5b..c182d40ae 100644 --- a/packages/vulcan-debug/package.js +++ b/packages/vulcan-debug/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:debug', summary: 'Vulcan debug package', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git', debugOnly: true }); @@ -17,8 +17,8 @@ Package.onUse(function (api) { // Vulcan packages - 'vulcan:lib@1.12.10', - 'vulcan:email@1.12.10', + 'vulcan:lib@1.12.11', + 'vulcan:email@1.12.11', ]); diff --git a/packages/vulcan-email/package.js b/packages/vulcan-email/package.js index b32fa10ff..c5393916e 100644 --- a/packages/vulcan-email/package.js +++ b/packages/vulcan-email/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:email', summary: 'Vulcan email package', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -10,7 +10,7 @@ Package.onUse(function (api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:lib@1.12.10' + 'vulcan:lib@1.12.11' ]); api.mainModule('lib/server.js', 'server'); diff --git a/packages/vulcan-embed/package.js b/packages/vulcan-embed/package.js index 80e2009af..bdf31d4e9 100644 --- a/packages/vulcan-embed/package.js +++ b/packages/vulcan-embed/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:embed', summary: 'Vulcan Embed package', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -11,7 +11,7 @@ Package.onUse( function(api) { api.use([ 'http', - 'vulcan:core@1.12.10', + 'vulcan:core@1.12.11', 'fourseven:scss@4.10.0' ]); diff --git a/packages/vulcan-errors-sentry/package.js b/packages/vulcan-errors-sentry/package.js index 8759ce2e5..796a64813 100755 --- a/packages/vulcan-errors-sentry/package.js +++ b/packages/vulcan-errors-sentry/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:errors-sentry', summary: 'Vulcan Sentry error tracking package', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -11,9 +11,9 @@ Package.onUse(function(api) { api.use([ 'ecmascript', - 'vulcan:core@1.12.10', - 'vulcan:users@1.12.10', - 'vulcan:errors@1.12.10', + 'vulcan:core@1.12.11', + 'vulcan:users@1.12.11', + 'vulcan:errors@1.12.11', ]); api.mainModule('lib/server/main.js', 'server'); diff --git a/packages/vulcan-errors/package.js b/packages/vulcan-errors/package.js index c97aef3f7..6c316b2a4 100644 --- a/packages/vulcan-errors/package.js +++ b/packages/vulcan-errors/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:errors', summary: 'Vulcan error tracking package', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -11,7 +11,7 @@ Package.onUse(function(api) { api.use([ 'ecmascript', - 'vulcan:core@1.12.10', + 'vulcan:core@1.12.11', ]); api.mainModule('lib/server/main.js', 'server'); diff --git a/packages/vulcan-events-ga/package.js b/packages/vulcan-events-ga/package.js index 6f73e9a31..9056acd05 100644 --- a/packages/vulcan-events-ga/package.js +++ b/packages/vulcan-events-ga/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:events-ga', summary: 'Vulcan Google Analytics event tracking package', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -10,8 +10,8 @@ Package.onUse(function(api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:core@1.12.10', - 'vulcan:events@1.12.10', + 'vulcan:core@1.12.11', + 'vulcan:events@1.12.11', ]); api.mainModule('lib/server/main.js', 'server'); diff --git a/packages/vulcan-events-intercom/package.js b/packages/vulcan-events-intercom/package.js index 48953a164..bf50188ef 100644 --- a/packages/vulcan-events-intercom/package.js +++ b/packages/vulcan-events-intercom/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:events-intercom', summary: 'Vulcan Intercom integration package.', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -10,8 +10,8 @@ Package.onUse(function (api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:core@1.12.10', - 'vulcan:events@1.12.10' + 'vulcan:core@1.12.11', + 'vulcan:events@1.12.11' ]); api.mainModule('lib/client/main.js', 'client'); diff --git a/packages/vulcan-events-internal/package.js b/packages/vulcan-events-internal/package.js index 6af4393e8..0935844d7 100644 --- a/packages/vulcan-events-internal/package.js +++ b/packages/vulcan-events-internal/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:events-internal', summary: 'Vulcan internal event tracking package', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -10,8 +10,8 @@ Package.onUse(function(api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:core@1.12.10', - 'vulcan:events@1.12.10', + 'vulcan:core@1.12.11', + 'vulcan:events@1.12.11', ]); api.mainModule('lib/server/main.js', 'server'); diff --git a/packages/vulcan-events-segment/package.js b/packages/vulcan-events-segment/package.js index f1e3b317d..5c364cf49 100644 --- a/packages/vulcan-events-segment/package.js +++ b/packages/vulcan-events-segment/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:events-segment', summary: 'Vulcan Segment', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -10,8 +10,8 @@ Package.onUse(function (api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:core@1.12.10', - 'vulcan:events@1.12.10', + 'vulcan:core@1.12.11', + 'vulcan:events@1.12.11', ]); api.mainModule('lib/server/main.js', 'server'); diff --git a/packages/vulcan-events/package.js b/packages/vulcan-events/package.js index fb616044c..e3df2bd79 100644 --- a/packages/vulcan-events/package.js +++ b/packages/vulcan-events/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:events', summary: 'Vulcan event tracking package', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -10,7 +10,7 @@ Package.onUse(function(api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:core@1.12.10', + 'vulcan:core@1.12.11', ]); api.mainModule('lib/server/main.js', 'server'); diff --git a/packages/vulcan-forms-tags/package.js b/packages/vulcan-forms-tags/package.js index 3c75bea08..18a256969 100644 --- a/packages/vulcan-forms-tags/package.js +++ b/packages/vulcan-forms-tags/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:forms-tags', summary: 'Vulcan tag input package', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -10,8 +10,8 @@ Package.onUse( function(api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:core@1.12.10', - 'vulcan:forms@1.12.10' + 'vulcan:core@1.12.11', + 'vulcan:forms@1.12.11' ]); api.mainModule('lib/export.js', ['client', 'server']); diff --git a/packages/vulcan-forms-upload/package.js b/packages/vulcan-forms-upload/package.js index 2788f62aa..431ae339e 100755 --- a/packages/vulcan-forms-upload/package.js +++ b/packages/vulcan-forms-upload/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:forms-upload', summary: 'Vulcan package extending vulcan:forms to upload images to Cloudinary from a drop zone.', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/xavcz/nova-forms-upload.git' }); @@ -10,8 +10,8 @@ Package.onUse( function(api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:core@1.12.10', - 'vulcan:forms@1.12.10', + 'vulcan:core@1.12.11', + 'vulcan:forms@1.12.11', 'fourseven:scss@4.10.0' ]); diff --git a/packages/vulcan-forms/package.js b/packages/vulcan-forms/package.js index dde807bfc..dece66063 100644 --- a/packages/vulcan-forms/package.js +++ b/packages/vulcan-forms/package.js @@ -1,14 +1,14 @@ Package.describe({ name: 'vulcan:forms', summary: 'Form containers for React', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/meteor-utilities/react-form-containers.git' }); Package.onUse(function (api) { api.versionsFrom('1.6.1'); - api.use(['vulcan:core@1.12.10']); + api.use(['vulcan:core@1.12.11']); api.mainModule('lib/client/main.js', ['client']); api.mainModule('lib/server/main.js', ['server']); diff --git a/packages/vulcan-i18n-en-us/package.js b/packages/vulcan-i18n-en-us/package.js index 3b50c2c99..ee882811b 100644 --- a/packages/vulcan-i18n-en-us/package.js +++ b/packages/vulcan-i18n-en-us/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:i18n-en-us', summary: 'Vulcan i18n package (en_US)', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -10,7 +10,7 @@ Package.onUse(function (api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:core@1.12.10' + 'vulcan:core@1.12.11' ]); api.addFiles([ diff --git a/packages/vulcan-i18n-es-es/package.js b/packages/vulcan-i18n-es-es/package.js index 01a99fc4c..56859c2dc 100644 --- a/packages/vulcan-i18n-es-es/package.js +++ b/packages/vulcan-i18n-es-es/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:i18n-es-es', summary: 'Vulcan i18n package (es_ES)', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -10,7 +10,7 @@ Package.onUse(function (api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:core@1.12.10' + 'vulcan:core@1.12.11' ]); api.addFiles([ diff --git a/packages/vulcan-i18n-fr-fr/package.js b/packages/vulcan-i18n-fr-fr/package.js index b465834a8..b683f0106 100644 --- a/packages/vulcan-i18n-fr-fr/package.js +++ b/packages/vulcan-i18n-fr-fr/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:i18n-fr-fr', summary: 'Vulcan i18n package (fr_FR)', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -10,7 +10,7 @@ Package.onUse(function (api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:core@1.12.10' + 'vulcan:core@1.12.11' ]); api.addFiles([ diff --git a/packages/vulcan-i18n/package.js b/packages/vulcan-i18n/package.js index 5cafcfa4f..fe648e4cc 100644 --- a/packages/vulcan-i18n/package.js +++ b/packages/vulcan-i18n/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:i18n', summary: 'i18n client polyfill', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan' }); @@ -10,7 +10,7 @@ Package.onUse(function (api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:lib@1.12.10', + 'vulcan:lib@1.12.11', ]); api.mainModule('lib/server/main.js', 'server'); diff --git a/packages/vulcan-lib/lib/modules/config.js b/packages/vulcan-lib/lib/modules/config.js index e41da7284..8ece7c394 100644 --- a/packages/vulcan-lib/lib/modules/config.js +++ b/packages/vulcan-lib/lib/modules/config.js @@ -9,7 +9,7 @@ import SimpleSchema from 'simpl-schema'; Vulcan = {}; // eslint-disable-next-line no-undef -Vulcan.VERSION = '1.12.10'; +Vulcan.VERSION = '1.12.11'; // ------------------------------------- Schemas -------------------------------- // diff --git a/packages/vulcan-lib/package.js b/packages/vulcan-lib/package.js index 3c5f5be5c..3d65fec25 100644 --- a/packages/vulcan-lib/package.js +++ b/packages/vulcan-lib/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:lib', summary: 'Vulcan libraries.', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); diff --git a/packages/vulcan-newsletter/package.js b/packages/vulcan-newsletter/package.js index a52cea9eb..2c5e38b56 100644 --- a/packages/vulcan-newsletter/package.js +++ b/packages/vulcan-newsletter/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:newsletter', summary: 'Vulcan email newsletter package', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -10,8 +10,8 @@ Package.onUse(function (api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:core@1.12.10', - 'vulcan:email@1.12.10' + 'vulcan:core@1.12.11', + 'vulcan:email@1.12.11' ]); api.mainModule('lib/server/main.js', 'server'); diff --git a/packages/vulcan-payments/package.js b/packages/vulcan-payments/package.js index 78993bc77..766a8afc1 100644 --- a/packages/vulcan-payments/package.js +++ b/packages/vulcan-payments/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:payments', summary: 'Vulcan payments package', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -11,7 +11,7 @@ Package.onUse(function (api) { api.use([ 'promise', - 'vulcan:core@1.12.10', + 'vulcan:core@1.12.11', 'fourseven:scss@4.5.4', ]); diff --git a/packages/vulcan-routing/package.js b/packages/vulcan-routing/package.js index 3ba151ad9..d7554e6ed 100644 --- a/packages/vulcan-routing/package.js +++ b/packages/vulcan-routing/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:routing', summary: 'Vulcan router package', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -10,7 +10,7 @@ Package.onUse(function (api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:lib@1.12.10', + 'vulcan:lib@1.12.11', ]); api.mainModule('lib/server/main.js', 'server'); diff --git a/packages/vulcan-subscribe/package.js b/packages/vulcan-subscribe/package.js index d3df81f22..28c5984e0 100644 --- a/packages/vulcan-subscribe/package.js +++ b/packages/vulcan-subscribe/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:subscribe', summary: 'Subscribe to posts, users, etc. to be notified of new activity', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -11,14 +11,14 @@ Package.onUse(function (api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:core@1.12.10', + 'vulcan:core@1.12.11', // dependencies on posts, categories are done with nested imports to reduce explicit dependencies ]); api.use([ - 'vulcan:posts@1.12.10', - 'vulcan:comments@1.12.10', - 'vulcan:categories@1.12.10', + 'vulcan:posts@1.12.11', + 'vulcan:comments@1.12.11', + 'vulcan:categories@1.12.11', ], {weak: true}); api.mainModule('lib/modules.js', ['client']); diff --git a/packages/vulcan-ui-bootstrap/package.js b/packages/vulcan-ui-bootstrap/package.js index 3a5aca668..408328341 100644 --- a/packages/vulcan-ui-bootstrap/package.js +++ b/packages/vulcan-ui-bootstrap/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:ui-bootstrap', summary: 'Vulcan Bootstrap UI components.', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -10,7 +10,7 @@ Package.onUse(function (api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:lib@1.12.10', + 'vulcan:lib@1.12.11', 'fourseven:scss@4.10.0', ]); diff --git a/packages/vulcan-users/package.js b/packages/vulcan-users/package.js index ae78bba41..edcc521ec 100644 --- a/packages/vulcan-users/package.js +++ b/packages/vulcan-users/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:users', summary: 'Vulcan permissions.', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -10,7 +10,7 @@ Package.onUse(function (api) { api.versionsFrom('1.6.1'); api.use([ - 'vulcan:lib@1.12.10' + 'vulcan:lib@1.12.11' ]); api.mainModule('lib/server/main.js', 'server'); diff --git a/packages/vulcan-voting/package.js b/packages/vulcan-voting/package.js index b7ef5d0f6..8e86a59b7 100644 --- a/packages/vulcan-voting/package.js +++ b/packages/vulcan-voting/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'vulcan:voting', summary: 'Vulcan scoring package.', - version: '1.12.10', + version: '1.12.11', git: 'https://github.com/VulcanJS/Vulcan.git' }); @@ -11,8 +11,8 @@ Package.onUse(function (api) { api.use([ 'fourseven:scss@4.10.0', - 'vulcan:core@1.12.10', - 'vulcan:i18n@1.12.10', + 'vulcan:core@1.12.11', + 'vulcan:i18n@1.12.11', ], ['client', 'server']); api.mainModule('lib/server/main.js', 'server'); From 8fe3b7abfdb4b61059464d4b82e60849928b85c9 Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Sat, 15 Dec 2018 16:27:06 +0900 Subject: [PATCH 29/30] Fix issue with addIntlFields callback --- packages/vulcan-lib/lib/modules/collections.js | 16 ++++++++-------- packages/vulcan-lib/lib/modules/intl.js | 7 +++++++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/vulcan-lib/lib/modules/collections.js b/packages/vulcan-lib/lib/modules/collections.js index ca809aced..e74219367 100644 --- a/packages/vulcan-lib/lib/modules/collections.js +++ b/packages/vulcan-lib/lib/modules/collections.js @@ -6,7 +6,7 @@ import { runCallbacks, runCallbacksAsync, registerCallback, addCallback } from ' import { getSetting, registerSetting } from './settings.js'; import { registerFragment, getDefaultFragmentText } from './fragments.js'; import escapeStringRegexp from 'escape-string-regexp'; -import { validateIntlField, getIntlString, isIntlField } from './intl'; +import { validateIntlField, getIntlString, isIntlField, schemaHasIntlFields } from './intl'; const wrapAsync = Meteor.wrapAsync ? Meteor.wrapAsync : Meteor._wrapAsync; // import { debug } from './debug.js'; @@ -155,6 +155,13 @@ export const createCollection = options => { //register individual collection callback registerCollectionCallback(collectionName); + // if schema has at least one intl field, add intl callback just before + // `${collectionName}.collection` callbacks run to make sure it always runs last + if (schemaHasIntlFields(schema)) { + hasIntlFields = true; // we have at least one intl field + addCallback(`${collectionName}.collection`, addIntlFields); + } + //run schema callbacks and run general callbacks last schema = runCallbacks({ name: `${collectionName}.collection`, iterator: schema, properties: { options }}); schema = runCallbacks({ name: '*.collection', iterator: schema, properties: { options }}); @@ -341,8 +348,6 @@ function addIntlFields(schema) { Object.keys(schema).forEach(fieldName => { const fieldSchema = schema[fieldName]; if (isIntlField(fieldSchema)) { - // we have at least one intl field - hasIntlFields = true; // remove `intl` to avoid treating new _intl field as a field to internationalize // eslint-disable-next-line no-unused-vars @@ -373,8 +378,3 @@ function addIntlFields(schema) { }); return schema; } - -//register intl callback very last -Meteor.startup(() => { - addCallback('*.collection', addIntlFields); -}); \ No newline at end of file diff --git a/packages/vulcan-lib/lib/modules/intl.js b/packages/vulcan-lib/lib/modules/intl.js index d55d5755c..6b0bc7160 100644 --- a/packages/vulcan-lib/lib/modules/intl.js +++ b/packages/vulcan-lib/lib/modules/intl.js @@ -70,6 +70,13 @@ export const getIntlString = () => { /* +Check if a schema has at least one intl field + +*/ +export const schemaHasIntlFields = schema => Object.keys(schema).some(fieldName => isIntlField(schema[fieldName])); + +/* + Custom validation function to check for required locales See https://github.com/aldeed/simple-schema-js#custom-field-validation From a523125da80d3bd0671eae1f03beb4d3f7616db0 Mon Sep 17 00:00:00 2001 From: SachaG <358832+SachaG@users.noreply.github.com> Date: Sat, 15 Dec 2018 16:30:38 +0900 Subject: [PATCH 30/30] Use lowercase typeName for callbacks --- packages/vulcan-lib/lib/modules/collections.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/vulcan-lib/lib/modules/collections.js b/packages/vulcan-lib/lib/modules/collections.js index e74219367..98eaff538 100644 --- a/packages/vulcan-lib/lib/modules/collections.js +++ b/packages/vulcan-lib/lib/modules/collections.js @@ -153,17 +153,17 @@ export const createCollection = options => { collection.views = []; //register individual collection callback - registerCollectionCallback(collectionName); + registerCollectionCallback(typeName.toLowerCase()); // if schema has at least one intl field, add intl callback just before // `${collectionName}.collection` callbacks run to make sure it always runs last if (schemaHasIntlFields(schema)) { hasIntlFields = true; // we have at least one intl field - addCallback(`${collectionName}.collection`, addIntlFields); + addCallback(`${typeName.toLowerCase()}.collection`, addIntlFields); } //run schema callbacks and run general callbacks last - schema = runCallbacks({ name: `${collectionName}.collection`, iterator: schema, properties: { options }}); + schema = runCallbacks({ name: `${typeName.toLowerCase()}.collection`, iterator: schema, properties: { options }}); schema = runCallbacks({ name: '*.collection', iterator: schema, properties: { options }}); if (schema) {