├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .gitignore
├── .npmignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── demo
├── angular-scope-types.js
├── angular.js
├── api-check.js
├── index.html
└── script.js
├── dist
├── angular-scope-types.js
├── angular-scope-types.min.js
└── angular-scope-types.min.js.map
├── karma.conf.js
├── package.json
├── scripts
├── karma-overrides.js
└── webpack-overrides.js
└── src
├── angular-fix
└── index.js
├── checkers
├── checkerUtils.js
├── ddo.js
├── ddo.test.js
├── index.js
├── index.test.js
├── injectableFunction.js
└── injectableFunction.test.js
├── index.js
├── index.test.js
├── scopeTypes.js
├── scopeTypes.test.js
└── test.utils.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | node_modules/kcd-common-tools/shared/link/editorconfig
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/kcd-common-tools/shared/link/eslintignore
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "rules": {
4 | "quotes": [2, "single"],
5 | "no-use-before-define": [2, "nofunc"],
6 | "no-unused-expressions": 0,
7 | "strict": 0,
8 | "no-unused-vars": [2, {"args": "none"}],
9 | "new-cap": [2, {
10 | "newIsCap": true,
11 | "capIsNew": true,
12 | "capIsNewExceptions": [
13 | "DSCreate", "DSUpdate", "DSSave", "DSDestroy", "DSRefresh", "DSChanges"
14 | ]
15 | }],
16 | "comma-dangle": 0,
17 | "max-statements": [2, 30],
18 | "max-len": [2, 120, 2],
19 | "complexity": [2, 5],
20 | "max-depth": [2, 4],
21 | "max-nested-callbacks": [2, 5],
22 | "indent": [2, 2],
23 | "brace-style": [2, "1tbs"],
24 | "spaced-line-comment": [2, "always"],
25 | "no-trailing-spaces": 0,
26 | "no-underscore-dangle": 0
27 | },
28 | "env": {
29 | "browser": true,
30 | "es6": true,
31 | "mocha": true
32 | },
33 | "ecmaFeatures": {
34 | "modules": true
35 | },
36 | "globals": {
37 | "expect": false,
38 | "require": false,
39 | "module": false,
40 | "__filename": false,
41 |
42 |
43 | "ATAC_CONFIG": true,
44 |
45 | "ON_DEV": true,
46 | "ON_PROD": true,
47 | "ON_TEST": true,
48 |
49 | "inject": true,
50 | "module": true,
51 | "before": true,
52 | "beforeEach": true,
53 | "after": true,
54 | "afterEach": true,
55 | "describe": true,
56 | "it": true,
57 | "expect": true,
58 | "sinon": true
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/kcd-common-tools/shared/link/gitignore
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules/kcd-common-tools/shared/link/npmignore
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 1.0.0-beta.7
2 |
3 | ## Bug Fixes
4 |
5 | - Allowing `replace` in the `ddo` checker.
6 |
7 | # 1.0.0-beta.6
8 |
9 | ## Other
10 |
11 | - Fixing link in README.md
12 |
13 | # 1.0.0-beta.5
14 |
15 | ## Breaking Changes
16 |
17 | - Now, if a checker is not optional, the api-check for it will be evaluated immediately.
18 |
19 | ## New Features
20 |
21 | - Adding `displayName` for the wrapper controller for error messaging and debugging.
22 | - Adding `scopeTypesFunction` to the `ddo` to allow you to specify `warn` or `throw`.
23 |
24 | # 1.0.0-beta.4
25 |
26 | ## New Features
27 |
28 | - Adding ability to specify your own instance of an `apiCheck` which allows you to use your own checkers.
29 |
30 | ## Bug Fixes
31 |
32 | - Fixing the prefix for the `scopeTypes` instance of an `apiCheck` to be `angular-scope-types` rather than `api-check-angular`
33 |
34 | # 1.0.0-beta.3
35 |
36 | ## Bug Fixes
37 |
38 | - Fixing issue where a new instance of the controller was created and the properties were not bound to that instance.
39 |
40 | # 1.0.0-beta.2
41 |
42 | ## Other
43 |
44 | - Adding `.npmignore`
45 |
46 | # 1.0.0-beta.1
47 |
48 | ## Breaking changes
49 |
50 | - `scopeTypes` must be a function that accepts the api-check instance and returns the api (perf improvement)
51 | - Changing what is exported to be the `scopeTypesFactory` function.
52 |
53 | ## New Features
54 |
55 | - Adding `disabled` option.
56 | - Improved the API, adding more tests, adding example.
57 |
58 | # 1.0.0-beta.0
59 |
60 | - Initial release
61 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # angular-scope-types
2 |
3 | [](https://www.npmjs.org/package/angular-scope-types)
4 | [](http://npm-stat.com/charts.html?package=angular-scope-types)
5 | [](https://snap-ci.com/alianza-dev/angular-scope-types/branch/master)
6 | [](https://codecov.io/github/alianza-dev/angular-scope-types)
7 | [](https://gitter.im/alianza-dev/angular-scope-types?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
8 |
9 | ## [Demo](https://jsbin.com/kuqeye/edit?html,js,output)
10 |
11 | This is still in the early stages. This is currently available as a beta on `npm`. Basically this is intended
12 | to bring a concept like
13 | [React `propTypes`](https://facebook.github.io/react/docs/reusable-components.html#prop-validation) to Angular.
14 |
15 | This is based on trying to support [this issue](https://github.com/angular/angular.js/issues/11657) with as clean an api
16 | as possible.
17 |
18 |
19 | ## Usage
20 |
21 | angular-scope-types uses [api-check](https://github.com/kentcdodds/api-check) to do api checking. api-check is basically
22 | React propTypes without React. So you'll need to install `api-check` into your project and include the script first. It
23 | is available on `npm` via `npm install --save api-check`
24 |
25 | You will then create your own instance of `apiCheck` and use that to create your own instance of `angular-scope-types`.
26 | (Note, you don't have to create your own instance, but it is recommended).
27 |
28 | Both `api-check` and `angular-scope-types` are exported as UMD modules meaning you can use them with CommonJS, AMD, or
29 | as globals (`apiCheck` and `angularScopeTypes` respectively).
30 |
31 | Here's a quick example for recommended usage (uses globals):
32 |
33 | ```javascript
34 |
35 | // create your apiCheckInstance
36 | var myApiCheck = apiCheck({
37 | output: {
38 | prefix: 'Global prefix',
39 | suffix: 'global suffix',
40 | docsBaseUrl: 'https://example.com/errors-and-warnings#'
41 | },
42 | disabled: SOME_VARIABLE_THAT_SAYS_YOU_ARE_ON_PRODUCTION
43 | }, {
44 | /* custom checkers if you wanna */
45 | });
46 |
47 |
48 | // create your angularScopeTypesInstance
49 | var myScopeTypes = angularScopeTypes({
50 | disabled: SOME_VARIABLE_THAT_SAYS_YOU_ARE_ON_PRODUCTION,
51 | apiCheckInstance: myApiCheck
52 | });
53 |
54 | // get your angular module
55 | var yourModule = angular.module('yourModule');
56 |
57 | // add your instance's `directive` function to your module to make it injectable
58 | yourModule.constant('myScopeTypesDirective', myScopeTypes.directive);
59 |
60 |
61 | // later in your code for a directive:
62 | yourModule.directive('myDirective', function(myScopeTypesDirective) {
63 | return myScopeTypesDirective({
64 | templateUrl: '/my-directive.html',
65 | scope: {foo: '=', bar: '@'},
66 | scopeTypes: getScopeTypes
67 | });
68 |
69 | function getScopeTypes(check) {
70 | return {
71 | foo: check.shape({
72 | isFoo: check.bool,
73 | isBar: check.bool,
74 | someNum: check.number,
75 | someOptional: check.object.optional
76 | }).strict.optional,
77 | bar: check.oneOf(['fooString', 'barString'])
78 | };
79 | }
80 | });
81 | ```
82 |
83 | See and play with [the demo](https://jsbin.com/kuqeye/edit?html,js,output) for a live example.
84 |
85 | ## LICENSE MIT
86 |
--------------------------------------------------------------------------------
/demo/angular-scope-types.js:
--------------------------------------------------------------------------------
1 | ../dist/angular-scope-types.js
--------------------------------------------------------------------------------
/demo/angular.js:
--------------------------------------------------------------------------------
1 | ../node_modules/angular/angular.js
--------------------------------------------------------------------------------
/demo/api-check.js:
--------------------------------------------------------------------------------
1 | ../node_modules/api-check/dist/api-check.js
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | angular-scope-types
6 |
7 |
8 |
9 | angular-scope-types
10 |
11 | Example App
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/demo/script.js:
--------------------------------------------------------------------------------
1 | var app = angular.module('app', []);
2 |
3 | app.controller('MainCtrl', function MainCtrl($timeout) {
4 | var vm = this;
5 |
6 | vm.goodFoo = {
7 | isFoo: true,
8 | isBar: false,
9 | someNum: 32
10 | };
11 |
12 | $timeout(function() {
13 | vm.badFoo = '';
14 | }, 1500);
15 | });
16 |
17 |
18 | app.constant('scopeTypesDirective', angularScopeTypes().directive);
19 |
20 | app.directive('scopeTypedDir', function(scopeTypesDirective) {
21 | return scopeTypesDirective({
22 | template: `
23 |
24 | This was scope type checked!
25 |
Passed: {{$scopeTypesResults.__passed}}
26 |
Failed: {{$scopeTypesResults.__failed}}
27 |
28 | `,
29 | scope: {foo: '=', bar: '@'},
30 | scopeTypes: getScopeTypes
31 | });
32 |
33 | function getScopeTypes(st) {
34 | return {
35 | foo: st.shape({
36 | isFoo: st.bool,
37 | isBar: st.bool,
38 | someNum: st.number,
39 | someOptional: st.object.optional
40 | }).strict.optional,
41 | bar: st.oneOf(['fooString', 'barString'])
42 | };
43 | }
44 |
45 | });
46 |
--------------------------------------------------------------------------------
/dist/angular-scope-types.js:
--------------------------------------------------------------------------------
1 | //! angular-scope-types version 1.0.0-beta.7 built with ♥ by Kent C. Dodds (http://kent.doddsfamily.us) (ó ì_í)=óò=(ì_í ò)
2 |
3 | (function webpackUniversalModuleDefinition(root, factory) {
4 | if(typeof exports === 'object' && typeof module === 'object')
5 | module.exports = factory(require("angular"), require("api-check"));
6 | else if(typeof define === 'function' && define.amd)
7 | define(["angular", "api-check"], factory);
8 | else if(typeof exports === 'object')
9 | exports["angularScopeTypes"] = factory(require("angular"), require("api-check"));
10 | else
11 | root["angularScopeTypes"] = factory(root["angular"], root["apiCheck"]);
12 | })(this, function(__WEBPACK_EXTERNAL_MODULE_3__, __WEBPACK_EXTERNAL_MODULE_4__) {
13 | return /******/ (function(modules) { // webpackBootstrap
14 | /******/ // The module cache
15 | /******/ var installedModules = {};
16 |
17 | /******/ // The require function
18 | /******/ function __webpack_require__(moduleId) {
19 |
20 | /******/ // Check if module is in cache
21 | /******/ if(installedModules[moduleId])
22 | /******/ return installedModules[moduleId].exports;
23 |
24 | /******/ // Create a new module (and put it into the cache)
25 | /******/ var module = installedModules[moduleId] = {
26 | /******/ exports: {},
27 | /******/ id: moduleId,
28 | /******/ loaded: false
29 | /******/ };
30 |
31 | /******/ // Execute the module function
32 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
33 |
34 | /******/ // Flag the module as loaded
35 | /******/ module.loaded = true;
36 |
37 | /******/ // Return the exports of the module
38 | /******/ return module.exports;
39 | /******/ }
40 |
41 |
42 | /******/ // expose the modules object (__webpack_modules__)
43 | /******/ __webpack_require__.m = modules;
44 |
45 | /******/ // expose the module cache
46 | /******/ __webpack_require__.c = installedModules;
47 |
48 | /******/ // __webpack_public_path__
49 | /******/ __webpack_require__.p = "";
50 |
51 | /******/ // Load entry module and return exports
52 | /******/ return __webpack_require__(0);
53 | /******/ })
54 | /************************************************************************/
55 | /******/ ([
56 | /* 0 */
57 | /***/ function(module, exports, __webpack_require__) {
58 |
59 | 'use strict';
60 |
61 | Object.defineProperty(exports, '__esModule', {
62 | value: true
63 | });
64 |
65 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
66 |
67 | var _scopeTypes = __webpack_require__(1);
68 |
69 | var _scopeTypes2 = _interopRequireDefault(_scopeTypes);
70 |
71 | exports['default'] = _scopeTypes2['default'];
72 | module.exports = exports['default'];
73 |
74 | /***/ },
75 | /* 1 */
76 | /***/ function(module, exports, __webpack_require__) {
77 |
78 | 'use strict';
79 |
80 | Object.defineProperty(exports, '__esModule', {
81 | value: true
82 | });
83 |
84 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
85 |
86 | var _angularFix = __webpack_require__(2);
87 |
88 | var _angularFix2 = _interopRequireDefault(_angularFix);
89 |
90 | var _apiCheck = __webpack_require__(4);
91 |
92 | var _apiCheck2 = _interopRequireDefault(_apiCheck);
93 |
94 | var _checkers = __webpack_require__(5);
95 |
96 | var _checkers2 = _interopRequireDefault(_checkers);
97 |
98 | var defaultOutput = { prefix: 'angular-scope-types' };
99 |
100 | exports['default'] = scopeTypesFactory;
101 |
102 | function scopeTypesFactory() {
103 | var _ref = arguments[0] === undefined ? {
104 | disabled: false,
105 | output: defaultOutput,
106 | apiCheckInstance: undefined
107 | } : arguments[0];
108 |
109 | var _ref$disabled = _ref.disabled;
110 | var disabled = _ref$disabled === undefined ? false : _ref$disabled;
111 | var _ref$output = _ref.output;
112 | var output = _ref$output === undefined ? defaultOutput : _ref$output;
113 | var apiCheckInstance = _ref.apiCheckInstance;
114 |
115 | var scopeTypes = (0, _apiCheck2['default'])({
116 | output: output,
117 | disabled: disabled
118 | });
119 | // manually adding checkers so we have an instance of scopeTypes to pass them.
120 | _angularFix2['default'].forEach(_checkers2['default'], function (factory, name) {
121 | scopeTypes[name] = factory({ scopeTypes: scopeTypes, disabled: disabled });
122 | });
123 |
124 | scopeTypes.directive = validateDirective;
125 |
126 | apiCheckInstance = apiCheckInstance || scopeTypes;
127 |
128 | return scopeTypes;
129 |
130 | function validateDirective(ddo) {
131 | if (scopeTypes.config.disabled || apiCheckInstance.config.disabled) {
132 | return ddo;
133 | }
134 | scopeTypes.warn(scopeTypes.ddo, ddo, { prefix: 'creating directive with scopeTypes' });
135 | // Would really love to not have to extend the ddo's controller
136 | // like this. Suggestions welcome!
137 | ddo.controller = extendController(ddo.controller, scopeTypesController);
138 |
139 | scopeTypesController.$inject = ['$scope'];
140 | function scopeTypesController($scope) {
141 | var context = $scope;
142 | if (ddo.bindToController) {
143 | context = context[ddo.controllerAs];
144 | }
145 |
146 | var typeDefinitions = ddo.scopeTypes(apiCheckInstance);
147 | scopeTypes.warn(scopeTypes.objectOf(scopeTypes.func).optional, typeDefinitions, { prefix: 'getting scope types for ' + ddo.name });
148 |
149 | $scope.$scopeTypesResults = { __passed: 0, __failed: 0 };
150 |
151 | _angularFix2['default'].forEach(typeDefinitions, function (check, name) {
152 | if (!_angularFix2['default'].isDefined(context[name]) && check.isOptional) {
153 | (function () {
154 | var prefix = ddo.controllerAs ? ddo.controllerAs + '.' : '';
155 | var stopWatching = $scope.$watch('' + prefix + '' + name, function (value, oldValue) {
156 | if (value !== oldValue) {
157 | stopWatching();
158 | checkOption(check, name);
159 | }
160 | });
161 | })();
162 | } else {
163 | checkOption(check, name);
164 | }
165 | });
166 |
167 | function checkOption(checker, name) {
168 | $scope.$scopeTypesResults[name] = apiCheckInstance[ddo.scopeTypesFunction || 'warn'](checker, context[name], { prefix: '' + ddo.name + 'Directive for "' + name + '"' });
169 | updateData();
170 | }
171 |
172 | function updateData() {
173 | var passedCount = 0;
174 | var failedCount = 0;
175 | var ignore = ['__passed', '__failed'];
176 | _angularFix2['default'].forEach($scope.$scopeTypesResults, function (result, name) {
177 | if (ignore.indexOf(name) === -1) {
178 | if (result.passed) {
179 | passedCount++;
180 | } else {
181 | failedCount++;
182 | }
183 | }
184 | });
185 | $scope.$scopeTypesResults.__passed = passedCount;
186 | $scope.$scopeTypesResults.__failed = failedCount;
187 | }
188 | }
189 |
190 | return ddo;
191 |
192 | function extendController(originalController, newController) {
193 | if (!_angularFix2['default'].isDefined(originalController)) {
194 | return newController;
195 | }
196 | function wrappedController($scope, $controller, $element, $attrs, $transclude, $injector) {
197 | var locals = { $scope: $scope, $element: $element, $attrs: $attrs, $transclude: $transclude };
198 | $injector.invoke(newController, this, locals);
199 | $injector.invoke(originalController, this, locals);
200 | }
201 |
202 | wrappedController.$inject = ['$scope', '$controller', '$element', '$attrs', '$transclude', '$injector'];
203 | wrappedController.displayName = getWrappedControllerDisplayName(originalController);
204 | return wrappedController;
205 | }
206 |
207 | function getWrappedControllerDisplayName(originalController) {
208 | var originalControllerName = originalController.displayName || originalController.name;
209 | var name = 'angular-scope-types controller wrapper';
210 | if (originalControllerName) {
211 | name = '' + name + ' for ' + originalControllerName;
212 | }
213 | return name;
214 | }
215 | }
216 | }
217 | module.exports = exports['default'];
218 |
219 | /***/ },
220 | /* 2 */
221 | /***/ function(module, exports, __webpack_require__) {
222 |
223 | // some versions of angular don't export the angular module properly,
224 | // so we get it from window in this case.
225 | 'use strict';
226 |
227 | Object.defineProperty(exports, '__esModule', {
228 | value: true
229 | });
230 | var angular = __webpack_require__(3);
231 | /* istanbul ignore next */
232 | if (!angular.version) {
233 | angular = window.angular;
234 | }
235 | exports['default'] = angular;
236 | module.exports = exports['default'];
237 |
238 | /***/ },
239 | /* 3 */
240 | /***/ function(module, exports) {
241 |
242 | module.exports = __WEBPACK_EXTERNAL_MODULE_3__;
243 |
244 | /***/ },
245 | /* 4 */
246 | /***/ function(module, exports) {
247 |
248 | module.exports = __WEBPACK_EXTERNAL_MODULE_4__;
249 |
250 | /***/ },
251 | /* 5 */
252 | /***/ function(module, exports, __webpack_require__) {
253 |
254 | 'use strict';
255 |
256 | Object.defineProperty(exports, '__esModule', {
257 | value: true
258 | });
259 |
260 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
261 |
262 | var _injectableFunction = __webpack_require__(6);
263 |
264 | var _injectableFunction2 = _interopRequireDefault(_injectableFunction);
265 |
266 | var _ddo = __webpack_require__(7);
267 |
268 | var _ddo2 = _interopRequireDefault(_ddo);
269 |
270 | exports['default'] = {
271 | injectableFunction: _injectableFunction2['default'], ddo: _ddo2['default']
272 | };
273 | module.exports = exports['default'];
274 |
275 | /***/ },
276 | /* 6 */
277 | /***/ function(module, exports, __webpack_require__) {
278 |
279 | 'use strict';
280 |
281 | Object.defineProperty(exports, '__esModule', {
282 | value: true
283 | });
284 | exports['default'] = injectableFunction;
285 |
286 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
287 |
288 | var _apiCheck = __webpack_require__(4);
289 |
290 | var _apiCheck2 = _interopRequireDefault(_apiCheck);
291 |
292 | function injectableFunction() {
293 | var _ref = arguments[0] === undefined ? { strictDi: false, disabled: false } : arguments[0];
294 |
295 | var _ref$strictDi = _ref.strictDi;
296 | var strictDi = _ref$strictDi === undefined ? false : _ref$strictDi;
297 | var _ref$disabled = _ref.disabled;
298 | var disabled = _ref$disabled === undefined ? false : _ref$disabled;
299 |
300 | var $injectProperty = _apiCheck2['default'].func.withProperties({
301 | $inject: _apiCheck2['default'].arrayOf(_apiCheck2['default'].string)
302 | });
303 |
304 | var arraySyntax = _apiCheck2['default'].utils.checkerHelpers.setupChecker(function arraySyntax(val, name, location) {
305 | if (!Array.isArray(val)) {
306 | return _apiCheck2['default'].utils.getError(name, location, _apiCheck2['default'].array.type);
307 | }
308 | var copy = val.slice();
309 | var fn = copy.pop();
310 | var arrayOfStringsChecker = _apiCheck2['default'].arrayOf(_apiCheck2['default'].string);
311 | var notArrayOfStrings = arrayOfStringsChecker(copy);
312 | if (_apiCheck2['default'].utils.isError(notArrayOfStrings)) {
313 | return _apiCheck2['default'].utils.getError(name, location, arrayOfStringsChecker.type);
314 | }
315 | if (typeof fn !== 'function') {
316 | return _apiCheck2['default'].utils.getError(name, location, _apiCheck2['default'].func.type);
317 | }
318 | }, { type: 'angular injectable function (array syntax)' }, disabled);
319 |
320 | var types = [$injectProperty, arraySyntax];
321 |
322 | if (!strictDi) {
323 | types.push(_apiCheck2['default'].func);
324 | }
325 |
326 | return _apiCheck2['default'].oneOfType(types);
327 | }
328 |
329 | module.exports = exports['default'];
330 |
331 | /***/ },
332 | /* 7 */
333 | /***/ function(module, exports, __webpack_require__) {
334 |
335 | 'use strict';
336 |
337 | Object.defineProperty(exports, '__esModule', {
338 | value: true
339 | });
340 | exports['default'] = ddo;
341 |
342 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
343 |
344 | var _checkerUtils = __webpack_require__(8);
345 |
346 | var _checkerUtils2 = _interopRequireDefault(_checkerUtils);
347 |
348 | function ddo() {
349 | var _ref = arguments[0] === undefined ? {
350 | strictDi: false, disabled: false
351 | } : arguments[0];
352 |
353 | var scopeTypes = _ref.scopeTypes;
354 | var _ref$strictDi = _ref.strictDi;
355 | var strictDi = _ref$strictDi === undefined ? false : _ref$strictDi;
356 | var _ref$disabled = _ref.disabled;
357 | var disabled = _ref$disabled === undefined ? false : _ref$disabled;
358 |
359 | if (disabled) {
360 | return _checkerUtils2['default'].noopChecker;
361 | }
362 |
363 | var check = scopeTypes;
364 | if (!check) {
365 | throw new Error('Must provide an instance of scopeTypes');
366 | }
367 | var stringOrFunc = scopeTypes.oneOfType([check.string, check.func]);
368 | var ddoShape = check.shape({
369 | priority: check.number.optional,
370 | template: check.shape.ifNot('templateUrl', stringOrFunc).optional,
371 | templateUrl: check.shape.ifNot('template', check.string).optional,
372 | transclude: check.bool.optional,
373 | restrict: check.oneOf(['A', 'E', 'C', 'AE', 'EA', 'AEC', 'AC', 'EC']).optional,
374 | replace: check.bool.optional,
375 | templateNamespace: check.oneOf(['html', 'svg', 'math']).optional,
376 | scope: check.oneOfType([check.bool, check.objectOf(check.string)]).optional, // TODO, make an advanced scope checker
377 | controller: check.injectableFunction.optional,
378 | controllerAs: check.string.optional,
379 | bindToController: check.oneOfType([check.bool, check.objectOf(check.string)]).optional,
380 | // TODO, tell the version of angular and use a scope checker for +1.4
381 | require: check.typeOrArrayOf(check.string).optional, // TODO make a pattern checker.
382 | // 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'],
383 | compile: check.func.optional,
384 | link: check.oneOfType([check.func, check.shape({
385 | pre: check.func.optional,
386 | post: check.func.optional
387 | }).strict]).optional,
388 | scopeTypes: check.func,
389 | scopeTypesFunction: check.oneOf(['warn', 'throw']).optional,
390 | data: check.object.optional
391 | }).strict;
392 |
393 | return check.oneOfType([check.func, ddoShape]);
394 | }
395 |
396 | module.exports = exports['default'];
397 |
398 | /***/ },
399 | /* 8 */
400 | /***/ function(module, exports) {
401 |
402 | "use strict";
403 |
404 | Object.defineProperty(exports, "__esModule", {
405 | value: true
406 | });
407 | function noopChecker() {}
408 | noopChecker.nullable = noopChecker;
409 | noopChecker.nullable.optional = noopChecker;
410 |
411 | exports["default"] = { noopChecker: noopChecker };
412 | module.exports = exports["default"];
413 |
414 | /***/ }
415 | /******/ ])
416 | });
417 | ;
--------------------------------------------------------------------------------
/dist/angular-scope-types.min.js:
--------------------------------------------------------------------------------
1 | //! angular-scope-types version 1.0.0-beta.7 built with ♥ by Kent C. Dodds (http://kent.doddsfamily.us) (ó ì_í)=óò=(ì_í ò)
2 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("api-check"),require("angular")):"function"==typeof define&&define.amd?define(["api-check","angular"],t):"object"==typeof exports?exports.angularScopeTypes=t(require("api-check"),require("angular")):e.angularScopeTypes=t(e.apiCheck,e.angular)}(this,function(e,t){return function(e){function t(n){if(o[n])return o[n].exports;var r=o[n]={exports:{},id:n,loaded:!1};return e[n].call(r.exports,r,r.exports,t),r.loaded=!0,r.exports}var o={};return t.m=e,t.c=o,t.p="",t(0)}([function(e,t,o){"use strict";function n(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var r=o(7),a=n(r);t["default"]=a["default"],e.exports=t["default"]},function(t,o){t.exports=e},function(e,t,o){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=o(8);n.version||(n=window.angular),t["default"]=n,e.exports=t["default"]},function(e,t){"use strict";function o(){}Object.defineProperty(t,"__esModule",{value:!0}),o.nullable=o,o.nullable.optional=o,t["default"]={noopChecker:o},e.exports=t["default"]},function(e,t,o){"use strict";function n(e){return e&&e.__esModule?e:{"default":e}}function r(){var e=void 0===arguments[0]?{strictDi:!1,disabled:!1}:arguments[0],t=e.scopeTypes,o=(e.strictDi,e.disabled),n=void 0===o?!1:o;if(n)return i["default"].noopChecker;var r=t;if(!r)throw new Error("Must provide an instance of scopeTypes");var a=t.oneOfType([r.string,r.func]),u=r.shape({priority:r.number.optional,template:r.shape.ifNot("templateUrl",a).optional,templateUrl:r.shape.ifNot("template",r.string).optional,transclude:r.bool.optional,restrict:r.oneOf(["A","E","C","AE","EA","AEC","AC","EC"]).optional,replace:r.bool.optional,templateNamespace:r.oneOf(["html","svg","math"]).optional,scope:r.oneOfType([r.bool,r.objectOf(r.string)]).optional,controller:r.injectableFunction.optional,controllerAs:r.string.optional,bindToController:r.oneOfType([r.bool,r.objectOf(r.string)]).optional,require:r.typeOrArrayOf(r.string).optional,compile:r.func.optional,link:r.oneOfType([r.func,r.shape({pre:r.func.optional,post:r.func.optional}).strict]).optional,scopeTypes:r.func,scopeTypesFunction:r.oneOf(["warn","throw"]).optional,data:r.object.optional}).strict;return r.oneOfType([r.func,u])}Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=r;var a=o(3),i=n(a);e.exports=t["default"]},function(e,t,o){"use strict";function n(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var r=o(6),a=n(r),i=o(4),u=n(i);t["default"]={injectableFunction:a["default"],ddo:u["default"]},e.exports=t["default"]},function(e,t,o){"use strict";function n(e){return e&&e.__esModule?e:{"default":e}}function r(){var e=void 0===arguments[0]?{strictDi:!1,disabled:!1}:arguments[0],t=e.strictDi,o=void 0===t?!1:t,n=e.disabled,r=void 0===n?!1:n,a=i["default"].func.withProperties({$inject:i["default"].arrayOf(i["default"].string)}),u=i["default"].utils.checkerHelpers.setupChecker(function(e,t,o){if(!Array.isArray(e))return i["default"].utils.getError(t,o,i["default"].array.type);var n=e.slice(),r=n.pop(),a=i["default"].arrayOf(i["default"].string),u=a(n);return i["default"].utils.isError(u)?i["default"].utils.getError(t,o,a.type):"function"!=typeof r?i["default"].utils.getError(t,o,i["default"].func.type):void 0},{type:"angular injectable function (array syntax)"},r),l=[a,u];return o||l.push(i["default"].func),i["default"].oneOfType(l)}Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=r;var a=o(1),i=n(a);e.exports=t["default"]},function(e,t,o){"use strict";function n(e){return e&&e.__esModule?e:{"default":e}}function r(){function e(e){function t(t){function o(o,a){t.$scopeTypesResults[a]=u[e.scopeTypesFunction||"warn"](o,r[a],{prefix:""+e.name+'Directive for "'+a+'"'}),n()}function n(){var e=0,o=0,n=["__passed","__failed"];i["default"].forEach(t.$scopeTypesResults,function(t,r){-1===n.indexOf(r)&&(t.passed?e++:o++)}),t.$scopeTypesResults.__passed=e,t.$scopeTypesResults.__failed=o}var r=t;e.bindToController&&(r=r[e.controllerAs]);var a=e.scopeTypes(u);s.warn(s.objectOf(s.func).optional,a,{prefix:"getting scope types for "+e.name}),t.$scopeTypesResults={__passed:0,__failed:0},i["default"].forEach(a,function(n,a){!i["default"].isDefined(r[a])&&n.isOptional?!function(){var r=e.controllerAs?e.controllerAs+".":"",i=t.$watch(""+r+a,function(e,t){e!==t&&(i(),o(n,a))})}():o(n,a)})}function o(e,t){function o(o,n,r,a,i,u){var l={$scope:o,$element:r,$attrs:a,$transclude:i};u.invoke(t,this,l),u.invoke(e,this,l)}return i["default"].isDefined(e)?(o.$inject=["$scope","$controller","$element","$attrs","$transclude","$injector"],o.displayName=n(e),o):t}function n(e){var t=e.displayName||e.name,o="angular-scope-types controller wrapper";return t&&(o=""+o+" for "+t),o}return s.config.disabled||u.config.disabled?e:(s.warn(s.ddo,e,{prefix:"creating directive with scopeTypes"}),e.controller=o(e.controller,t),t.$inject=["$scope"],e)}var t=void 0===arguments[0]?{disabled:!1,output:f,apiCheckInstance:void 0}:arguments[0],o=t.disabled,n=void 0===o?!1:o,r=t.output,a=void 0===r?f:r,u=t.apiCheckInstance,s=l["default"]({output:a,disabled:n});return i["default"].forEach(c["default"],function(e,t){s[t]=e({scopeTypes:s,disabled:n})}),s.directive=e,u=u||s,s}Object.defineProperty(t,"__esModule",{value:!0});var a=o(2),i=n(a),u=o(1),l=n(u),s=o(5),c=n(s),f={prefix:"angular-scope-types"};t["default"]=r,e.exports=t["default"]},function(e,o){e.exports=t}])});
3 | //# sourceMappingURL=angular-scope-types.min.js.map
--------------------------------------------------------------------------------
/dist/angular-scope-types.min.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///dist/angular-scope-types.min.js","webpack:///webpack/bootstrap 857925f8c38dd1dc86e2","webpack:///./index.js","webpack:///external {\"root\":\"apiCheck\",\"amd\":\"api-check\",\"commonjs2\":\"api-check\",\"commonjs\":\"api-check\"}","webpack:///./angular-fix/index.js","webpack:///./checkers/checkerUtils.js","webpack:///./checkers/ddo.js","webpack:///./checkers/index.js","webpack:///./checkers/injectableFunction.js","webpack:///./scopeTypes.js","webpack:///external \"angular\""],"names":["root","factory","exports","module","require","define","amd","this","__WEBPACK_EXTERNAL_MODULE_1__","__WEBPACK_EXTERNAL_MODULE_8__","modules","__webpack_require__","moduleId","installedModules","id","loaded","call","m","c","p","_interopRequireDefault","obj","__esModule","default","Object","defineProperty","value","_scopeTypes","_scopeTypes2","angular","version","window","noopChecker","nullable","optional","ddo","_ref","undefined","arguments","strictDi","disabled","scopeTypes","_ref$disabled","_checkerUtils2","check","Error","stringOrFunc","oneOfType","string","func","ddoShape","shape","priority","number","template","ifNot","templateUrl","transclude","bool","restrict","oneOf","replace","templateNamespace","scope","objectOf","controller","injectableFunction","controllerAs","bindToController","typeOrArrayOf","compile","link","pre","post","strict","scopeTypesFunction","data","object","_checkerUtils","_injectableFunction","_injectableFunction2","_ddo","_ddo2","_ref$strictDi","$injectProperty","_apiCheck2","withProperties","$inject","arrayOf","arraySyntax","utils","checkerHelpers","setupChecker","val","name","location","Array","isArray","getError","array","type","copy","slice","fn","pop","arrayOfStringsChecker","notArrayOfStrings","isError","types","push","_apiCheck","scopeTypesFactory","validateDirective","scopeTypesController","$scope","checkOption","checker","$scopeTypesResults","apiCheckInstance","context","prefix","updateData","passedCount","failedCount","ignore","_angularFix2","forEach","result","indexOf","passed","__passed","__failed","typeDefinitions","warn","isDefined","isOptional","stopWatching","$watch","oldValue","extendController","originalController","newController","wrappedController","$controller","$element","$attrs","$transclude","$injector","locals","invoke","displayName","getWrappedControllerDisplayName","originalControllerName","config","output","defaultOutput","_ref$output","_checkers2","directive","_angularFix","_checkers"],"mappings":"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","file":"dist/angular-scope-types.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"api-check\"), require(\"angular\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"api-check\", \"angular\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"angularScopeTypes\"] = factory(require(\"api-check\"), require(\"angular\"));\n\telse\n\t\troot[\"angularScopeTypes\"] = factory(root[\"apiCheck\"], root[\"angular\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_8__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/","//! angular-scope-types version 1.0.0-beta.7 built with ♥ by Kent C. Dodds (http://kent.doddsfamily.us) (ó ì_í)=óò=(ì_í ò)\n\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"api-check\"), require(\"angular\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"api-check\", \"angular\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"angularScopeTypes\"] = factory(require(\"api-check\"), require(\"angular\"));\n\telse\n\t\troot[\"angularScopeTypes\"] = factory(root[\"apiCheck\"], root[\"angular\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_8__) {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _scopeTypes = __webpack_require__(7);\n\t\n\tvar _scopeTypes2 = _interopRequireDefault(_scopeTypes);\n\n\texports['default'] = _scopeTypes2['default'];\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 1 */\n/***/ function(module, exports) {\n\n\tmodule.exports = __WEBPACK_EXTERNAL_MODULE_1__;\n\n/***/ },\n/* 2 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// some versions of angular don't export the angular module properly,\n\t// so we get it from window in this case.\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\tvar angular = __webpack_require__(8);\n\t/* istanbul ignore next */\n\tif (!angular.version) {\n\t angular = window.angular;\n\t}\n\texports['default'] = angular;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 3 */\n/***/ function(module, exports) {\n\n\t\"use strict\";\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\tfunction noopChecker() {}\n\tnoopChecker.nullable = noopChecker;\n\tnoopChecker.nullable.optional = noopChecker;\n\t\n\texports[\"default\"] = { noopChecker: noopChecker };\n\tmodule.exports = exports[\"default\"];\n\n/***/ },\n/* 4 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\texports['default'] = ddo;\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _checkerUtils = __webpack_require__(3);\n\t\n\tvar _checkerUtils2 = _interopRequireDefault(_checkerUtils);\n\t\n\tfunction ddo() {\n\t var _ref = arguments[0] === undefined ? {\n\t strictDi: false, disabled: false\n\t } : arguments[0];\n\t\n\t var scopeTypes = _ref.scopeTypes;\n\t var _ref$strictDi = _ref.strictDi;\n\t var strictDi = _ref$strictDi === undefined ? false : _ref$strictDi;\n\t var _ref$disabled = _ref.disabled;\n\t var disabled = _ref$disabled === undefined ? false : _ref$disabled;\n\t\n\t if (disabled) {\n\t return _checkerUtils2['default'].noopChecker;\n\t }\n\t\n\t var check = scopeTypes;\n\t if (!check) {\n\t throw new Error('Must provide an instance of scopeTypes');\n\t }\n\t var stringOrFunc = scopeTypes.oneOfType([check.string, check.func]);\n\t var ddoShape = check.shape({\n\t priority: check.number.optional,\n\t template: check.shape.ifNot('templateUrl', stringOrFunc).optional,\n\t templateUrl: check.shape.ifNot('template', check.string).optional,\n\t transclude: check.bool.optional,\n\t restrict: check.oneOf(['A', 'E', 'C', 'AE', 'EA', 'AEC', 'AC', 'EC']).optional,\n\t replace: check.bool.optional,\n\t templateNamespace: check.oneOf(['html', 'svg', 'math']).optional,\n\t scope: check.oneOfType([check.bool, check.objectOf(check.string)]).optional, // TODO, make an advanced scope checker\n\t controller: check.injectableFunction.optional,\n\t controllerAs: check.string.optional,\n\t bindToController: check.oneOfType([check.bool, check.objectOf(check.string)]).optional,\n\t // TODO, tell the version of angular and use a scope checker for +1.4\n\t require: check.typeOrArrayOf(check.string).optional, // TODO make a pattern checker.\n\t // 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'],\n\t compile: check.func.optional,\n\t link: check.oneOfType([check.func, check.shape({\n\t pre: check.func.optional,\n\t post: check.func.optional\n\t }).strict]).optional,\n\t scopeTypes: check.func,\n\t scopeTypesFunction: check.oneOf(['warn', 'throw']).optional,\n\t data: check.object.optional\n\t }).strict;\n\t\n\t return check.oneOfType([check.func, ddoShape]);\n\t}\n\t\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 5 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _injectableFunction = __webpack_require__(6);\n\t\n\tvar _injectableFunction2 = _interopRequireDefault(_injectableFunction);\n\t\n\tvar _ddo = __webpack_require__(4);\n\t\n\tvar _ddo2 = _interopRequireDefault(_ddo);\n\t\n\texports['default'] = {\n\t injectableFunction: _injectableFunction2['default'], ddo: _ddo2['default']\n\t};\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 6 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\texports['default'] = injectableFunction;\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _apiCheck = __webpack_require__(1);\n\t\n\tvar _apiCheck2 = _interopRequireDefault(_apiCheck);\n\t\n\tfunction injectableFunction() {\n\t var _ref = arguments[0] === undefined ? { strictDi: false, disabled: false } : arguments[0];\n\t\n\t var _ref$strictDi = _ref.strictDi;\n\t var strictDi = _ref$strictDi === undefined ? false : _ref$strictDi;\n\t var _ref$disabled = _ref.disabled;\n\t var disabled = _ref$disabled === undefined ? false : _ref$disabled;\n\t\n\t var $injectProperty = _apiCheck2['default'].func.withProperties({\n\t $inject: _apiCheck2['default'].arrayOf(_apiCheck2['default'].string)\n\t });\n\t\n\t var arraySyntax = _apiCheck2['default'].utils.checkerHelpers.setupChecker(function arraySyntax(val, name, location) {\n\t if (!Array.isArray(val)) {\n\t return _apiCheck2['default'].utils.getError(name, location, _apiCheck2['default'].array.type);\n\t }\n\t var copy = val.slice();\n\t var fn = copy.pop();\n\t var arrayOfStringsChecker = _apiCheck2['default'].arrayOf(_apiCheck2['default'].string);\n\t var notArrayOfStrings = arrayOfStringsChecker(copy);\n\t if (_apiCheck2['default'].utils.isError(notArrayOfStrings)) {\n\t return _apiCheck2['default'].utils.getError(name, location, arrayOfStringsChecker.type);\n\t }\n\t if (typeof fn !== 'function') {\n\t return _apiCheck2['default'].utils.getError(name, location, _apiCheck2['default'].func.type);\n\t }\n\t }, { type: 'angular injectable function (array syntax)' }, disabled);\n\t\n\t var types = [$injectProperty, arraySyntax];\n\t\n\t if (!strictDi) {\n\t types.push(_apiCheck2['default'].func);\n\t }\n\t\n\t return _apiCheck2['default'].oneOfType(types);\n\t}\n\t\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 7 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _angularFix = __webpack_require__(2);\n\t\n\tvar _angularFix2 = _interopRequireDefault(_angularFix);\n\t\n\tvar _apiCheck = __webpack_require__(1);\n\t\n\tvar _apiCheck2 = _interopRequireDefault(_apiCheck);\n\t\n\tvar _checkers = __webpack_require__(5);\n\t\n\tvar _checkers2 = _interopRequireDefault(_checkers);\n\t\n\tvar defaultOutput = { prefix: 'angular-scope-types' };\n\t\n\texports['default'] = scopeTypesFactory;\n\t\n\tfunction scopeTypesFactory() {\n\t var _ref = arguments[0] === undefined ? {\n\t disabled: false,\n\t output: defaultOutput,\n\t apiCheckInstance: undefined\n\t } : arguments[0];\n\t\n\t var _ref$disabled = _ref.disabled;\n\t var disabled = _ref$disabled === undefined ? false : _ref$disabled;\n\t var _ref$output = _ref.output;\n\t var output = _ref$output === undefined ? defaultOutput : _ref$output;\n\t var apiCheckInstance = _ref.apiCheckInstance;\n\t\n\t var scopeTypes = (0, _apiCheck2['default'])({\n\t output: output,\n\t disabled: disabled\n\t });\n\t // manually adding checkers so we have an instance of scopeTypes to pass them.\n\t _angularFix2['default'].forEach(_checkers2['default'], function (factory, name) {\n\t scopeTypes[name] = factory({ scopeTypes: scopeTypes, disabled: disabled });\n\t });\n\t\n\t scopeTypes.directive = validateDirective;\n\t\n\t apiCheckInstance = apiCheckInstance || scopeTypes;\n\t\n\t return scopeTypes;\n\t\n\t function validateDirective(ddo) {\n\t if (scopeTypes.config.disabled || apiCheckInstance.config.disabled) {\n\t return ddo;\n\t }\n\t scopeTypes.warn(scopeTypes.ddo, ddo, { prefix: 'creating directive with scopeTypes' });\n\t // Would really love to not have to extend the ddo's controller\n\t // like this. Suggestions welcome!\n\t ddo.controller = extendController(ddo.controller, scopeTypesController);\n\t\n\t scopeTypesController.$inject = ['$scope'];\n\t function scopeTypesController($scope) {\n\t var context = $scope;\n\t if (ddo.bindToController) {\n\t context = context[ddo.controllerAs];\n\t }\n\t\n\t var typeDefinitions = ddo.scopeTypes(apiCheckInstance);\n\t scopeTypes.warn(scopeTypes.objectOf(scopeTypes.func).optional, typeDefinitions, { prefix: 'getting scope types for ' + ddo.name });\n\t\n\t $scope.$scopeTypesResults = { __passed: 0, __failed: 0 };\n\t\n\t _angularFix2['default'].forEach(typeDefinitions, function (check, name) {\n\t if (!_angularFix2['default'].isDefined(context[name]) && check.isOptional) {\n\t (function () {\n\t var prefix = ddo.controllerAs ? ddo.controllerAs + '.' : '';\n\t var stopWatching = $scope.$watch('' + prefix + '' + name, function (value, oldValue) {\n\t if (value !== oldValue) {\n\t stopWatching();\n\t checkOption(check, name);\n\t }\n\t });\n\t })();\n\t } else {\n\t checkOption(check, name);\n\t }\n\t });\n\t\n\t function checkOption(checker, name) {\n\t $scope.$scopeTypesResults[name] = apiCheckInstance[ddo.scopeTypesFunction || 'warn'](checker, context[name], { prefix: '' + ddo.name + 'Directive for \"' + name + '\"' });\n\t updateData();\n\t }\n\t\n\t function updateData() {\n\t var passedCount = 0;\n\t var failedCount = 0;\n\t var ignore = ['__passed', '__failed'];\n\t _angularFix2['default'].forEach($scope.$scopeTypesResults, function (result, name) {\n\t if (ignore.indexOf(name) === -1) {\n\t if (result.passed) {\n\t passedCount++;\n\t } else {\n\t failedCount++;\n\t }\n\t }\n\t });\n\t $scope.$scopeTypesResults.__passed = passedCount;\n\t $scope.$scopeTypesResults.__failed = failedCount;\n\t }\n\t }\n\t\n\t return ddo;\n\t\n\t function extendController(originalController, newController) {\n\t if (!_angularFix2['default'].isDefined(originalController)) {\n\t return newController;\n\t }\n\t function wrappedController($scope, $controller, $element, $attrs, $transclude, $injector) {\n\t var locals = { $scope: $scope, $element: $element, $attrs: $attrs, $transclude: $transclude };\n\t $injector.invoke(newController, this, locals);\n\t $injector.invoke(originalController, this, locals);\n\t }\n\t\n\t wrappedController.$inject = ['$scope', '$controller', '$element', '$attrs', '$transclude', '$injector'];\n\t wrappedController.displayName = getWrappedControllerDisplayName(originalController);\n\t return wrappedController;\n\t }\n\t\n\t function getWrappedControllerDisplayName(originalController) {\n\t var originalControllerName = originalController.displayName || originalController.name;\n\t var name = 'angular-scope-types controller wrapper';\n\t if (originalControllerName) {\n\t name = '' + name + ' for ' + originalControllerName;\n\t }\n\t return name;\n\t }\n\t }\n\t}\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 8 */\n/***/ function(module, exports) {\n\n\tmodule.exports = __WEBPACK_EXTERNAL_MODULE_8__;\n\n/***/ }\n/******/ ])\n});\n;\n\n\n/** WEBPACK FOOTER **\n ** dist/angular-scope-types.min.js\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 857925f8c38dd1dc86e2\n **/","import scopeTypes from './scopeTypes';\n\nexport default scopeTypes;\n\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader!./index.js\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_1__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"root\":\"apiCheck\",\"amd\":\"api-check\",\"commonjs2\":\"api-check\",\"commonjs\":\"api-check\"}\n ** module id = 1\n ** module chunks = 0\n **/","// some versions of angular don't export the angular module properly,\n// so we get it from window in this case.\nvar angular = require('angular');\n/* istanbul ignore next */\nif (!angular.version) {\n angular = window.angular;\n}\nexport default angular;\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader!./angular-fix/index.js\n **/","function noopChecker() {\n}\nnoopChecker.nullable = noopChecker;\nnoopChecker.nullable.optional = noopChecker;\n\nexport default {noopChecker};\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader!./checkers/checkerUtils.js\n **/","import checkerUtils from './checkerUtils';\n\nexport default function ddo({\n scopeTypes, strictDi = false, disabled = false\n } = {\n strictDi: false, disabled: false\n}) {\n if (disabled) {\n return checkerUtils.noopChecker;\n }\n\n const check = scopeTypes;\n if (!check) {\n throw new Error('Must provide an instance of scopeTypes');\n }\n const stringOrFunc = scopeTypes.oneOfType([check.string, check.func]);\n const ddoShape = check.shape({\n priority: check.number.optional,\n template: check.shape.ifNot('templateUrl', stringOrFunc).optional,\n templateUrl: check.shape.ifNot('template', check.string).optional,\n transclude: check.bool.optional,\n restrict: check.oneOf(['A', 'E', 'C', 'AE', 'EA', 'AEC', 'AC', 'EC']).optional,\n replace: check.bool.optional,\n templateNamespace: check.oneOf(['html', 'svg', 'math']).optional,\n scope: check.oneOfType([check.bool, check.objectOf(check.string)]).optional, // TODO, make an advanced scope checker\n controller: check.injectableFunction.optional,\n controllerAs: check.string.optional,\n bindToController: check.oneOfType([check.bool, check.objectOf(check.string)]).optional,\n // TODO, tell the version of angular and use a scope checker for +1.4\n require: check.typeOrArrayOf(check.string).optional, // TODO make a pattern checker.\n // 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'],\n compile: check.func.optional,\n link: check.oneOfType([\n check.func,\n check.shape({\n pre: check.func.optional,\n post: check.func.optional\n }).strict\n ]).optional,\n scopeTypes: check.func,\n scopeTypesFunction: check.oneOf(['warn', 'throw']).optional,\n data: check.object.optional\n }).strict;\n\n return check.oneOfType([check.func, ddoShape]);\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader!./checkers/ddo.js\n **/","import injectableFunction from './injectableFunction';\nimport ddo from './ddo';\n\nexport default {\n injectableFunction, ddo\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader!./checkers/index.js\n **/","import apiCheck from 'api-check';\n\nexport default function injectableFunction({strictDi = false, disabled = false} = {strictDi: false, disabled: false}) {\n const $injectProperty = apiCheck.func.withProperties({\n $inject: apiCheck.arrayOf(apiCheck.string)\n });\n\n const arraySyntax = apiCheck.utils.checkerHelpers.setupChecker(function arraySyntax(val, name, location) {\n if (!Array.isArray(val)) {\n return apiCheck.utils.getError(name, location, apiCheck.array.type);\n }\n let copy = val.slice();\n const fn = copy.pop();\n const arrayOfStringsChecker = apiCheck.arrayOf(apiCheck.string);\n const notArrayOfStrings = arrayOfStringsChecker(copy);\n if (apiCheck.utils.isError(notArrayOfStrings)) {\n return apiCheck.utils.getError(name, location, arrayOfStringsChecker.type);\n }\n if (typeof fn !== 'function') {\n return apiCheck.utils.getError(name, location, apiCheck.func.type);\n }\n }, {type: 'angular injectable function (array syntax)'}, disabled);\n\n const types = [$injectProperty, arraySyntax];\n\n if (!strictDi) {\n types.push(apiCheck.func);\n }\n\n return apiCheck.oneOfType(types);\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader!./checkers/injectableFunction.js\n **/","import angular from 'angular-fix';\nimport apiCheckFactory from 'api-check';\nimport checkerFactories from './checkers';\n\nconst defaultOutput = {prefix: 'angular-scope-types'};\n\nexport default scopeTypesFactory;\n\nfunction scopeTypesFactory({\n disabled = false,\n output = defaultOutput,\n apiCheckInstance\n } = {\n disabled: false,\n output: defaultOutput,\n apiCheckInstance: undefined\n}) {\n const scopeTypes = apiCheckFactory({\n output: output,\n disabled\n });\n // manually adding checkers so we have an instance of scopeTypes to pass them.\n angular.forEach(checkerFactories, (factory, name) => {\n scopeTypes[name] = factory({scopeTypes, disabled});\n });\n\n scopeTypes.directive = validateDirective;\n\n apiCheckInstance = apiCheckInstance || scopeTypes;\n\n return scopeTypes;\n\n function validateDirective(ddo) {\n if (scopeTypes.config.disabled || apiCheckInstance.config.disabled) {\n return ddo;\n }\n scopeTypes.warn(scopeTypes.ddo, ddo, {prefix: 'creating directive with scopeTypes'});\n // Would really love to not have to extend the ddo's controller\n // like this. Suggestions welcome!\n ddo.controller = extendController(ddo.controller, scopeTypesController);\n\n scopeTypesController.$inject = ['$scope'];\n function scopeTypesController($scope) {\n var context = $scope;\n if (ddo.bindToController) {\n context = context[ddo.controllerAs];\n }\n\n let typeDefinitions = ddo.scopeTypes(apiCheckInstance);\n scopeTypes.warn(\n scopeTypes.objectOf(scopeTypes.func).optional,\n typeDefinitions,\n {prefix: `getting scope types for ${ddo.name}`}\n );\n\n $scope.$scopeTypesResults = {__passed: 0, __failed: 0};\n\n angular.forEach(typeDefinitions, (check, name) => {\n if (!angular.isDefined(context[name]) && check.isOptional) {\n let prefix = ddo.controllerAs ? ddo.controllerAs + '.' : '';\n const stopWatching = $scope.$watch(`${prefix}${name}`, (value, oldValue) => {\n if (value !== oldValue) {\n stopWatching();\n checkOption(check, name);\n }\n });\n } else {\n checkOption(check, name);\n }\n });\n\n\n function checkOption(checker, name) {\n $scope.$scopeTypesResults[name] = apiCheckInstance[ddo.scopeTypesFunction || 'warn'](\n checker, context[name], {prefix: `${ddo.name}Directive for \"${name}\"`}\n );\n updateData();\n }\n\n function updateData() {\n let passedCount = 0;\n let failedCount = 0;\n const ignore = ['__passed', '__failed'];\n angular.forEach($scope.$scopeTypesResults, (result, name) => {\n if (ignore.indexOf(name) === -1) {\n if (result.passed) {\n passedCount++;\n } else {\n failedCount++;\n }\n }\n });\n $scope.$scopeTypesResults.__passed = passedCount;\n $scope.$scopeTypesResults.__failed = failedCount;\n }\n\n }\n\n return ddo;\n\n\n function extendController(originalController, newController) {\n if (!angular.isDefined(originalController)) {\n return newController;\n }\n function wrappedController($scope, $controller, $element, $attrs, $transclude, $injector) {\n const locals = {$scope, $element, $attrs, $transclude};\n $injector.invoke(newController, this, locals);\n $injector.invoke(originalController, this, locals);\n }\n\n wrappedController.$inject = ['$scope', '$controller', '$element', '$attrs', '$transclude', '$injector'];\n wrappedController.displayName = getWrappedControllerDisplayName(originalController);\n return wrappedController;\n }\n\n function getWrappedControllerDisplayName(originalController) {\n const originalControllerName = originalController.displayName || originalController.name;\n let name = 'angular-scope-types controller wrapper';\n if (originalControllerName) {\n name = `${name} for ${originalControllerName}`;\n }\n return name;\n }\n }\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader!./scopeTypes.js\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_8__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external \"angular\"\n ** module id = 8\n ** module chunks = 0\n **/"],"sourceRoot":""}
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = require('kcd-common-tools/shared/karma.conf');
2 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-scope-types",
3 | "version": "1.0.0-beta.7",
4 | "description": "checkers and other utilities for using api-check with angular",
5 | "main": "dist/angular-scope-types.js",
6 | "scripts": {
7 | "start": "npm run test",
8 | "test": "COVERAGE=true NODE_ENV=test karma start",
9 | "test:single": "COVERAGE=true NODE_ENV=test karma start --single-run",
10 | "test:debug": "echo 'WARNING: This is currently not working quite right...' && NODE_ENV=test karma start --browsers Chrome",
11 | "build:dist": "NODE_ENV=development webpack --config node_modules/kcd-common-tools/shared/webpack.config.js --progress --colors",
12 | "build:prod": "NODE_ENV=production webpack --config node_modules/kcd-common-tools/shared/webpack.config.js --progress --colors",
13 | "build": "npm run build:dist & npm run build:prod",
14 | "ci": "npm run code-checks && npm run test:single && npm run check-coverage && npm run build",
15 | "check-coverage": "./node_modules/istanbul/lib/cli.js check-coverage --statements 97 --branches 89 --functions 100 --lines 95",
16 | "report-coverage": "cat ./coverage/lcov.info | codecov",
17 | "deploy": "npm run deployClean && npm run deployCopy && npm run deploySurge",
18 | "deploySurge": "surge -p deploy.ignored -d angular-scope-types.surge.sh",
19 | "deployCopy": "cp demo/{index.html,script.js} deploy.ignored/ && cp dist/angular-scope-types.js deploy.ignored/ && cp node_modules/angular/angular.js deploy.ignored/ && cp node_modules/api-check/dist/api-check.js deploy.ignored/",
20 | "deployClean": "rm -rf deploy.ignored/ && mkdir deploy.ignored/",
21 | "only-check": "node node_modules/kcd-common-tools/shared/scripts/only-check.js",
22 | "code-checks": "eslint src/ && npm run only-check",
23 | "release": "npm run build && with-package git commit -am pkg.version && with-package git tag pkg.version && git push && npm publish && git push --tags",
24 | "release:beta": "npm run release && npm run tag:beta",
25 | "tag:beta": "with-package npm dist-tag add pkg.name@pkg.version beta"
26 | },
27 | "repository": {
28 | "type": "git",
29 | "url": "https://github.com/alianza-dev/angular-scope-types.git"
30 | },
31 | "keywords": [
32 | "api-check",
33 | "angular-scope-types",
34 | "react propTypes",
35 | "angular scopeTypes",
36 | "angular",
37 | "angularjs",
38 | "apiCheck.js"
39 | ],
40 | "author": "Kent C. Dodds (http://kent.doddsfamily.us)",
41 | "contributors": [
42 | "Kent C. Dodds (http://kent.doddsfamily.us)"
43 | ],
44 | "license": "MIT",
45 | "bugs": {
46 | "url": "https://github.com/alianza-dev/angular-scope-types/issues"
47 | },
48 | "homepage": "https://github.com/alianza-dev/angular-scope-types",
49 | "config": {
50 | "ghooks": {
51 | "pre-commit": "npm run ci"
52 | }
53 | },
54 | "peerDependencies": {
55 | "angular": "^1.2.x || >= 1.4.0-beta.0 || >= 1.5.0-beta.0",
56 | "api-check": "^7.2.0"
57 | },
58 | "devDependencies": {
59 | "angular": "1.4.1",
60 | "angular-mocks": "1.4.1",
61 | "api-check": "7.5.0",
62 | "babel": "5.5.8",
63 | "babel-core": "5.5.8",
64 | "babel-eslint": "3.1.17",
65 | "babel-loader": "5.1.4",
66 | "chai": "2.1.0",
67 | "codecov.io": "0.1.4",
68 | "eslint": "0.23.0",
69 | "eslint-loader": "0.14.0",
70 | "ghooks": "0.2.4",
71 | "isparta": "3.0.3",
72 | "isparta-loader": "0.2.0",
73 | "istanbul": "0.3.5",
74 | "karma": "0.12.36",
75 | "karma-chai": "0.1.0",
76 | "karma-chrome-launcher": "0.1.12",
77 | "karma-coverage": "0.4.2",
78 | "karma-firefox-launcher": "0.1.6",
79 | "karma-mocha": "0.1.10",
80 | "karma-sinon": "1.0.4",
81 | "karma-webpack": "1.5.1",
82 | "kcd-common-tools": "1.0.0-beta.9",
83 | "lodash": "3.9.3",
84 | "mocha": "2.1.0",
85 | "node-libs-browser": "^0.5.2",
86 | "sinon": "1.15.3",
87 | "surge": "0.14.2",
88 | "uglify-loader": "1.2.0",
89 | "webpack": "1.9.11",
90 | "with-package": "0.2.0"
91 | },
92 | "kcdCommon": {
93 | "webpack": "scripts/webpack-overrides.js",
94 | "karma": "scripts/karma-overrides.js"
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/scripts/karma-overrides.js:
--------------------------------------------------------------------------------
1 | var _ = require('lodash');
2 | var here = require('kcd-common-tools/utils/here');
3 |
4 | module.exports = function(defaultConfig) {
5 | defaultConfig.files = _.union([
6 | here('./node_modules/angular/angular.js'),
7 | here('./node_modules/angular-mocks/angular-mocks.js'),
8 | here('./node_modules/api-check/dist/api-check.js')
9 | ], defaultConfig.files);
10 | return defaultConfig;
11 | };
12 |
--------------------------------------------------------------------------------
/scripts/webpack-overrides.js:
--------------------------------------------------------------------------------
1 | var here = require('kcd-common-tools/utils/here');
2 | var _ = require('lodash');
3 | module.exports = function(defaultConfig) {
4 | return _.merge(defaultConfig, {
5 | output: {
6 | library: 'angularScopeTypes',
7 | libraryTarget: 'umd'
8 | },
9 | externals: {
10 | angular: 'angular',
11 | 'api-check': {
12 | root: 'apiCheck',
13 | amd: 'api-check',
14 | commonjs2: 'api-check',
15 | commonjs: 'api-check'
16 | }
17 | },
18 | resolve: {
19 | alias: {
20 | 'angular-fix': here('src/angular-fix')
21 | }
22 | }
23 | });
24 | };
25 |
--------------------------------------------------------------------------------
/src/angular-fix/index.js:
--------------------------------------------------------------------------------
1 | // some versions of angular don't export the angular module properly,
2 | // so we get it from window in this case.
3 | var angular = require('angular');
4 | /* istanbul ignore next */
5 | if (!angular.version) {
6 | angular = window.angular;
7 | }
8 | export default angular;
9 |
--------------------------------------------------------------------------------
/src/checkers/checkerUtils.js:
--------------------------------------------------------------------------------
1 | function noopChecker() {
2 | }
3 | noopChecker.nullable = noopChecker;
4 | noopChecker.nullable.optional = noopChecker;
5 |
6 | export default {noopChecker};
7 |
--------------------------------------------------------------------------------
/src/checkers/ddo.js:
--------------------------------------------------------------------------------
1 | import checkerUtils from './checkerUtils';
2 |
3 | export default function ddo({
4 | scopeTypes, strictDi = false, disabled = false
5 | } = {
6 | strictDi: false, disabled: false
7 | }) {
8 | if (disabled) {
9 | return checkerUtils.noopChecker;
10 | }
11 |
12 | const check = scopeTypes;
13 | if (!check) {
14 | throw new Error('Must provide an instance of scopeTypes');
15 | }
16 | const stringOrFunc = scopeTypes.oneOfType([check.string, check.func]);
17 | const ddoShape = check.shape({
18 | priority: check.number.optional,
19 | template: check.shape.ifNot('templateUrl', stringOrFunc).optional,
20 | templateUrl: check.shape.ifNot('template', check.string).optional,
21 | transclude: check.bool.optional,
22 | restrict: check.oneOf(['A', 'E', 'C', 'AE', 'EA', 'AEC', 'AC', 'EC']).optional,
23 | replace: check.bool.optional,
24 | templateNamespace: check.oneOf(['html', 'svg', 'math']).optional,
25 | scope: check.oneOfType([check.bool, check.objectOf(check.string)]).optional, // TODO, make an advanced scope checker
26 | controller: check.injectableFunction.optional,
27 | controllerAs: check.string.optional,
28 | bindToController: check.oneOfType([check.bool, check.objectOf(check.string)]).optional,
29 | // TODO, tell the version of angular and use a scope checker for +1.4
30 | require: check.typeOrArrayOf(check.string).optional, // TODO make a pattern checker.
31 | // 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'],
32 | compile: check.func.optional,
33 | link: check.oneOfType([
34 | check.func,
35 | check.shape({
36 | pre: check.func.optional,
37 | post: check.func.optional
38 | }).strict
39 | ]).optional,
40 | scopeTypes: check.func,
41 | scopeTypesFunction: check.oneOf(['warn', 'throw']).optional,
42 | data: check.object.optional
43 | }).strict;
44 |
45 | return check.oneOfType([check.func, ddoShape]);
46 | }
47 |
--------------------------------------------------------------------------------
/src/checkers/ddo.test.js:
--------------------------------------------------------------------------------
1 | import {expectPass, expectFail, link, controllers} from '../test.utils';
2 | import scopeTypesFactory from '../scopeTypes';
3 |
4 | import ddoFactory from './ddo';
5 |
6 | describe(`ddo checker`, () => {
7 |
8 | describe(`basic checker`, () => {
9 | let checker, scopeTypes;
10 | beforeEach(() => {
11 | scopeTypes = scopeTypesFactory();
12 | checker = ddoFactory({scopeTypes});
13 | });
14 |
15 | it(`should pass with a link function`, () => {
16 | expectPass(checker(link));
17 | });
18 |
19 | it(`should fail when the DDO has extra stuff`, () => {
20 | expectFail(checker({
21 | whatever: 'foo'
22 | }));
23 | });
24 |
25 | it(`should pass when given a valid DDO`, () => {
26 | expectPass(checker({
27 | template: 'Hello!',
28 | link,
29 | controllerAs: 'vm',
30 | controller: controllers.$inject,
31 | bindToController: true,
32 | replace: true,
33 | /* istanbul ignore next */
34 | scopeTypes: st => ({foo: st.shape({})})
35 | }));
36 | });
37 | });
38 |
39 | describe(`disabled`, () => {
40 | let checker, scopeTypes;
41 | beforeEach(() => {
42 | scopeTypes = scopeTypesFactory();
43 | checker = ddoFactory({scopeTypes, disabled: true});
44 | });
45 |
46 | it(`should pass regardless of anything`, () => {
47 | expectPass(checker());
48 | expectPass(checker('foo'));
49 | expectPass(checker(link));
50 | expectPass(checker([]));
51 | });
52 | });
53 | });
54 |
--------------------------------------------------------------------------------
/src/checkers/index.js:
--------------------------------------------------------------------------------
1 | import injectableFunction from './injectableFunction';
2 | import ddo from './ddo';
3 |
4 | export default {
5 | injectableFunction, ddo
6 | };
7 |
--------------------------------------------------------------------------------
/src/checkers/index.test.js:
--------------------------------------------------------------------------------
1 | export * from './injectableFunction.test';
2 | export * from './ddo.test';
3 |
--------------------------------------------------------------------------------
/src/checkers/injectableFunction.js:
--------------------------------------------------------------------------------
1 | import apiCheck from 'api-check';
2 |
3 | export default function injectableFunction({strictDi = false, disabled = false} = {strictDi: false, disabled: false}) {
4 | const $injectProperty = apiCheck.func.withProperties({
5 | $inject: apiCheck.arrayOf(apiCheck.string)
6 | });
7 |
8 | const arraySyntax = apiCheck.utils.checkerHelpers.setupChecker(function arraySyntax(val, name, location) {
9 | if (!Array.isArray(val)) {
10 | return apiCheck.utils.getError(name, location, apiCheck.array.type);
11 | }
12 | let copy = val.slice();
13 | const fn = copy.pop();
14 | const arrayOfStringsChecker = apiCheck.arrayOf(apiCheck.string);
15 | const notArrayOfStrings = arrayOfStringsChecker(copy);
16 | if (apiCheck.utils.isError(notArrayOfStrings)) {
17 | return apiCheck.utils.getError(name, location, arrayOfStringsChecker.type);
18 | }
19 | if (typeof fn !== 'function') {
20 | return apiCheck.utils.getError(name, location, apiCheck.func.type);
21 | }
22 | }, {type: 'angular injectable function (array syntax)'}, disabled);
23 |
24 | const types = [$injectProperty, arraySyntax];
25 |
26 | if (!strictDi) {
27 | types.push(apiCheck.func);
28 | }
29 |
30 | return apiCheck.oneOfType(types);
31 | }
32 |
--------------------------------------------------------------------------------
/src/checkers/injectableFunction.test.js:
--------------------------------------------------------------------------------
1 | import {expect} from 'chai';
2 | import {expectPass, expectFail, controllers} from '../test.utils';
3 | import injectableFunction from './injectableFunction';
4 |
5 | describe(`injectableFunction checker`, () => {
6 |
7 | describe(`basic checker info`, () => {
8 | let checker;
9 | beforeEach(() => {
10 | checker = injectableFunction();
11 | });
12 |
13 | it(`should have optional`, () => {
14 | expect(checker.optional).to.be.a('function');
15 | });
16 |
17 | it(`should have nullable with optional`, () => {
18 | expect(checker.nullable).to.be.a('function');
19 | expect(checker.nullable.optional).to.be.a('function');
20 | });
21 |
22 | it(`should pass with $inject property`, () => {
23 | expectPass(checker(controllers.$inject));
24 | });
25 |
26 | it(`should pass with Array syntax`, () => {
27 | expectPass(checker(controllers.array));
28 | });
29 |
30 | it(`should fail when given an array with non-strings before the function`, () => {
31 | expectFail(checker(['foo', 23, controllers.regular]));
32 | });
33 |
34 | it(`should fail when given an array with the function not last`, () => {
35 | expectFail(checker(['foo', controllers.regular, 'bar']));
36 | });
37 |
38 | it(`should fail when not given a function`, () => {
39 | expectFail(checker(['foo', 'baz', 'bar']));
40 | });
41 | });
42 |
43 | describe(`strictDi: false`, () => {
44 | let checker;
45 | beforeEach(() => {
46 | checker = injectableFunction();
47 | });
48 |
49 | it(`should pass with a function`, () => {
50 | expectPass(checker(controllers.regular));
51 | });
52 | });
53 |
54 | describe(`strictDi: true`, () => {
55 | let checker;
56 | beforeEach(() => {
57 | checker = injectableFunction({strictDi: true});
58 | });
59 |
60 | it(`should fail with a function`, () => {
61 | expectFail(checker(controllers.regular));
62 | });
63 | });
64 |
65 | describe(`disabled: true`, () => {
66 | let checker;
67 | beforeEach(() => {
68 | checker = injectableFunction({disabled: true});
69 | });
70 |
71 | it(`should succeed in any case`, () => {
72 | expectPass(checker('foo'));
73 | expectPass(checker(controllers.regular));
74 | });
75 | });
76 |
77 | });
78 |
79 |
80 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import scopeTypes from './scopeTypes';
2 |
3 | export default scopeTypes;
4 |
5 |
--------------------------------------------------------------------------------
/src/index.test.js:
--------------------------------------------------------------------------------
1 | export * from './checkers/index.test';
2 | export * from './scopeTypes.test';
3 |
--------------------------------------------------------------------------------
/src/scopeTypes.js:
--------------------------------------------------------------------------------
1 | import angular from 'angular-fix';
2 | import apiCheckFactory from 'api-check';
3 | import checkerFactories from './checkers';
4 |
5 | const defaultOutput = {prefix: 'angular-scope-types'};
6 |
7 | export default scopeTypesFactory;
8 |
9 | function scopeTypesFactory({
10 | disabled = false,
11 | output = defaultOutput,
12 | apiCheckInstance
13 | } = {
14 | disabled: false,
15 | output: defaultOutput,
16 | apiCheckInstance: undefined
17 | }) {
18 | const scopeTypes = apiCheckFactory({
19 | output: output,
20 | disabled
21 | });
22 | // manually adding checkers so we have an instance of scopeTypes to pass them.
23 | angular.forEach(checkerFactories, (factory, name) => {
24 | scopeTypes[name] = factory({scopeTypes, disabled});
25 | });
26 |
27 | scopeTypes.directive = validateDirective;
28 |
29 | apiCheckInstance = apiCheckInstance || scopeTypes;
30 |
31 | return scopeTypes;
32 |
33 | function validateDirective(ddo) {
34 | if (scopeTypes.config.disabled || apiCheckInstance.config.disabled) {
35 | return ddo;
36 | }
37 | scopeTypes.warn(scopeTypes.ddo, ddo, {prefix: 'creating directive with scopeTypes'});
38 | // Would really love to not have to extend the ddo's controller
39 | // like this. Suggestions welcome!
40 | ddo.controller = extendController(ddo.controller, scopeTypesController);
41 |
42 | scopeTypesController.$inject = ['$scope'];
43 | function scopeTypesController($scope) {
44 | var context = $scope;
45 | if (ddo.bindToController) {
46 | context = context[ddo.controllerAs];
47 | }
48 |
49 | let typeDefinitions = ddo.scopeTypes(apiCheckInstance);
50 | scopeTypes.warn(
51 | scopeTypes.objectOf(scopeTypes.func).optional,
52 | typeDefinitions,
53 | {prefix: `getting scope types for ${ddo.name}`}
54 | );
55 |
56 | $scope.$scopeTypesResults = {__passed: 0, __failed: 0};
57 |
58 | angular.forEach(typeDefinitions, (check, name) => {
59 | if (!angular.isDefined(context[name]) && check.isOptional) {
60 | let prefix = ddo.controllerAs ? ddo.controllerAs + '.' : '';
61 | const stopWatching = $scope.$watch(`${prefix}${name}`, (value, oldValue) => {
62 | if (value !== oldValue) {
63 | stopWatching();
64 | checkOption(check, name);
65 | }
66 | });
67 | } else {
68 | checkOption(check, name);
69 | }
70 | });
71 |
72 |
73 | function checkOption(checker, name) {
74 | $scope.$scopeTypesResults[name] = apiCheckInstance[ddo.scopeTypesFunction || 'warn'](
75 | checker, context[name], {prefix: `${ddo.name}Directive for "${name}"`}
76 | );
77 | updateData();
78 | }
79 |
80 | function updateData() {
81 | let passedCount = 0;
82 | let failedCount = 0;
83 | const ignore = ['__passed', '__failed'];
84 | angular.forEach($scope.$scopeTypesResults, (result, name) => {
85 | if (ignore.indexOf(name) === -1) {
86 | if (result.passed) {
87 | passedCount++;
88 | } else {
89 | failedCount++;
90 | }
91 | }
92 | });
93 | $scope.$scopeTypesResults.__passed = passedCount;
94 | $scope.$scopeTypesResults.__failed = failedCount;
95 | }
96 |
97 | }
98 |
99 | return ddo;
100 |
101 |
102 | function extendController(originalController, newController) {
103 | if (!angular.isDefined(originalController)) {
104 | return newController;
105 | }
106 | function wrappedController($scope, $controller, $element, $attrs, $transclude, $injector) {
107 | const locals = {$scope, $element, $attrs, $transclude};
108 | $injector.invoke(newController, this, locals);
109 | $injector.invoke(originalController, this, locals);
110 | }
111 |
112 | wrappedController.$inject = ['$scope', '$controller', '$element', '$attrs', '$transclude', '$injector'];
113 | wrappedController.displayName = getWrappedControllerDisplayName(originalController);
114 | return wrappedController;
115 | }
116 |
117 | function getWrappedControllerDisplayName(originalController) {
118 | const originalControllerName = originalController.displayName || originalController.name;
119 | let name = 'angular-scope-types controller wrapper';
120 | if (originalControllerName) {
121 | name = `${name} for ${originalControllerName}`;
122 | }
123 | return name;
124 | }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/scopeTypes.test.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console:0 */
2 | /* eslint max-nested-callbacks:0 */
3 | import {expect} from 'chai';
4 | import angular from 'angular-fix';
5 | import apiCheck from 'api-check';
6 |
7 | import scopeTypesFactory from './scopeTypes';
8 |
9 | describe(`scopeTypes`, () => {
10 | let scopeTypes, originalWarn, warnings;
11 | beforeEach(() => {
12 | warnings = [];
13 | originalWarn = console.warn;
14 | console.warn = fakeWarn;
15 | scopeTypes = scopeTypesFactory();
16 | });
17 |
18 | describe(`directive`, () => {
19 | it(`should fail when the DDO has extra stuff`, () => {
20 | scopeTypes.directive({
21 | whatever: 'foo'
22 | });
23 | expectWarning(/whatever(.|\n)*?foo/);
24 | });
25 |
26 | describe(`creating directives`, () => {
27 | let scope, el;
28 |
29 | const basicTemplate = '';
30 |
31 | it(`should allow me to create a type checked directive`, () => {
32 | createDirective();
33 | compileAndDigest({
34 | baz: 'hi',
35 | foo: {isFoo: true, isBar: false, someNum: 23}
36 | });
37 | expectNoWarning();
38 | });
39 |
40 | it(`should warn me when I pass something wrong to the directive`, () => {
41 | createDirective();
42 | compileAndDigest({
43 | baz: 'hi',
44 | foo: {isFoo: 'not a boolean', isBar: false, someNum: 23}
45 | });
46 | expectWarning(/not a boolean/);
47 | });
48 |
49 | it(`should warn if something that is not optional is not passed`, () => {
50 | createDirective();
51 | compileAndDigest({
52 | // missing baz
53 | });
54 | expectWarning(/Required/);
55 | });
56 |
57 |
58 | it(`should be able to be disabled`, () => {
59 | const myDisabledScopeTypes = scopeTypesFactory({disabled: true});
60 | const myDirName = 'dirName';
61 | const controller = sinon.spy();
62 | const scopeTypesSpy = sinon.spy(getScopeTypes);
63 | createDirective(myDirName, {controller}, myDisabledScopeTypes);
64 |
65 | compileAndDigest({
66 | baz: 'hi'
67 | }, '');
68 |
69 | angular.mock.inject(['$injector', $injector => {
70 | const ddo = $injector.get(`${myDirName}Directive`);
71 |
72 | expect(ddo[0].controller).to.eq(controller);
73 | expect(controller).to.have.been.called;
74 | expect(scopeTypesSpy).to.not.have.been.called;
75 | expectNoWarning();
76 | }]);
77 | });
78 |
79 | it(`should still allow the directive controller to use it's controller as`, () => {
80 | createDirective(undefined, {
81 | controller,
82 | controllerAs: 'vm',
83 | bindToController: true
84 | });
85 |
86 | function controller() {
87 | const vm = this;
88 |
89 | expect(vm.bar).to.eq('barString');
90 | }
91 | compileAndDigest({baz: 'hey'});
92 | expectNoWarning();
93 | });
94 |
95 | it(`should allow you to pass your own instance of an apiCheck`, () => {
96 | const myApiCheck = apiCheck({});
97 | const myScopeTypes = scopeTypesFactory({apiCheckInstance: myApiCheck});
98 | const myDirName = 'dirName';
99 | const scopeTypesSpy = sinon.spy();
100 | createDirective(myDirName, {scope: {}, scopeTypes: scopeTypesSpy}, myScopeTypes);
101 | compileAndDigest({}, '');
102 | angular.mock.inject(['$injector', $injector => {
103 | expect(scopeTypesSpy).to.have.been.called;
104 | expectNoWarning();
105 | }]);
106 | });
107 |
108 | it(`should allow you to pass your own scopeTypesFunction function`, () => {
109 | createDirective(undefined, {scopeTypesFunction: 'throw'});
110 | expect(() => compileAndDigest({})).to.throw();
111 | expectNoWarning();
112 | });
113 |
114 | function createDirective(name, definition, scopeTypesInstance = scopeTypes) {
115 | angular.mock.module(['$provide', '$compileProvider', function($provide, $compileProvider) {
116 | $provide.constant('myScopeTypes', scopeTypesInstance);
117 | $compileProvider.directive(name || 'scopeTypeDir', ['myScopeTypes', function(myScopeTypes) {
118 | return myScopeTypes.directive(angular.extend({
119 | template: 'foo',
120 | scope: {foo: '=', bar: '@', baz: '='},
121 | scopeTypes: getScopeTypes,
122 | controllerAs: 'vm',
123 | bindToController: true,
124 | controller: angular.noop
125 | }, definition));
126 | }]);
127 | }]);
128 | }
129 |
130 |
131 | function compileAndDigest(extraProps = {}, template = basicTemplate) {
132 | angular.mock.inject(['$compile', '$rootScope', ($compile, $rootScope) => {
133 | scope = $rootScope.$new();
134 | angular.extend(scope, extraProps);
135 | el = $compile(template)(scope);
136 | scope.$digest();
137 | }]);
138 | return el;
139 | }
140 |
141 | function getScopeTypes(st) {
142 | return {
143 | foo: st.shape({
144 | isFoo: st.bool,
145 | isBar: st.bool,
146 | someNum: st.number,
147 | someOptional: st.object.optional
148 | }).strict.optional,
149 | bar: st.oneOf(['fooString', 'barString']).optional,
150 | baz: st.string
151 | };
152 | }
153 | });
154 | });
155 |
156 | afterEach(() => {
157 | console.warn = originalWarn;
158 | });
159 |
160 | function fakeWarn() {
161 | warnings.push(arguments);
162 | }
163 |
164 | function expectWarning(warning) {
165 | if (!warnings.length) {
166 | throw new Error('Expected a warning, but non was logged');
167 | }
168 | expect(warnings[0]).to.have.length(1);
169 | expect(warnings[0][0]).to.match(warning);
170 | }
171 |
172 | function expectNoWarning() {
173 | if (warnings.length) {
174 | console.log(warnings);
175 | throw new Error('Expected no warning to be logged, but one was');
176 | }
177 | }
178 |
179 | });
180 |
--------------------------------------------------------------------------------
/src/test.utils.js:
--------------------------------------------------------------------------------
1 | import {expect} from 'chai';
2 |
3 | /* istanbul ignore next */
4 | const controllers = {
5 | regular: function RegularCtrl() {
6 | },
7 | array: ['foo', function ArrayCtrl(foo) {
8 | }],
9 | $inject: function $InjectCtrl(bar) {
10 | }
11 | };
12 | controllers.$inject.$inject = ['bar'];
13 |
14 | export {expectPass, expectFail, link, controllers};
15 |
16 |
17 | function expectPass(val) {
18 | expect(val).to.be.undefined;
19 | }
20 |
21 | function expectFail(val) {
22 | expect(val).to.be.an.instanceOf(Error);
23 | }
24 |
25 | /* istanbul ignore next */
26 | function link(scope, el, attrs, ctrl, transclude) {
27 | }
28 |
29 |
30 |
--------------------------------------------------------------------------------