11 |
12 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/css/main.css:
--------------------------------------------------------------------------------
1 | [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
2 | display: none !important;
3 | }
4 |
5 | body {
6 | padding-top: 60px;
7 | }
8 |
9 | textarea.document-text {
10 | font-family: Monaco, Andale Mono, monospace;
11 | font-size: smaller;
12 | resize: none;
13 | height: 300px;
14 |
15 | border: 0;
16 | border-bottom: 1px solid #ccc;
17 | border-radius: 0;
18 | }
19 |
20 | pre.error-value {
21 | border: 0;
22 | padding: 0;
23 | }
24 |
25 | table.validation-messages-table {
26 | table-layout: fixed;
27 | }
28 |
29 | td.error-path {
30 | word-break: break-word;
31 | }
32 |
33 | validation-messages .table {
34 | margin: 1em 0 0;
35 | }
--------------------------------------------------------------------------------
/src/dialogs/About.html:
--------------------------------------------------------------------------------
1 |
JSON Schema Lint is a JSON schema validator to help you write and test JSON Schemas that conform with various specification versions.
2 |
The author/maintainer is Nick Maynard . Fork this project on Github.
3 |
Thanks
4 |
5 | Github Gists for saving schemas/documents
6 | Gary Court's JSV for validating draft-01, draft-02, draft-03
7 | Evgeny Poberezkin's Ajv for validating draft-04 and up
8 | Jérémy Fairve's yaml.js
9 |
10 |
--------------------------------------------------------------------------------
/src/service-worker.js:
--------------------------------------------------------------------------------
1 | const CACHE_NAME = (new Date()).toISOString();
2 |
3 | // Eagerly cache everything when service worker is installed
4 | self.addEventListener('install', function (e) {
5 | e.waitUntil(
6 | caches.open(CACHE_NAME).then(function (cache) {
7 | return cache.addAll(global.serviceWorkerOption.assets);
8 | })
9 | );
10 | });
11 |
12 | // Fetch from cache if it's there
13 | self.addEventListener('fetch', function (event) {
14 | event.respondWith(
15 | caches.match(event.request).then(function (response) {
16 | return response || fetch(event.request);
17 | })
18 | );
19 | });
20 |
--------------------------------------------------------------------------------
/src/services/AlertService.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var app = angular.module('app', false);
4 |
5 | app.service('alertService', function ($q, $uibModal) {
6 |
7 | this.alert = function (params) {
8 | if (!params) {
9 | return $q.reject('params required');
10 | }
11 | return $uibModal.open({
12 | animation: false,
13 | template: `
${params.message}
`,
14 | ariaLabelledBy: 'modal-title-top',
15 | ariaDescribedBy: 'modal-body',
16 | controller: function () {},
17 | size: params.size || 'sm'
18 | }).result;
19 | };
20 |
21 | });
22 |
--------------------------------------------------------------------------------
/src/services/Gist.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var app = angular.module('app', false);
4 |
5 | var base = 'https://api.github.com/gists';
6 |
7 | app.service('gist', function ($q, $http, $log, $translate) {
8 |
9 | // Save the schema and document as a secret anonymous gist
10 | this.save = function(schema, doc) {
11 | return $http({
12 | method: 'POST',
13 | url: base,
14 | data: {
15 | 'description': 'jsonschemalint.com ' + (new Date().toISOString()),
16 | 'public': false,
17 | 'files': {
18 | 'schema': {
19 | 'content': schema
20 | },
21 | 'document': {
22 | 'content': doc
23 | }
24 | }
25 | }
26 | }).then(function(result) {
27 | $log.info('Saved gist successfully with ID', result.data.id);
28 | return result.data.id;
29 | }, function(error) {
30 | $log.error('Could not save gist', error);
31 | throw error.statusText;
32 | });
33 | };
34 |
35 | // Get the schema and document
36 | this.retrieve = function(gistId) {
37 | return $http({
38 | method: 'GET',
39 | url: base + '/' + gistId
40 | }).then(function(result) {
41 | // Sanity check!
42 | if(!result || !result.data || !result.data.files || !result.data.files['schema'] || !result.data.files['document']) {
43 | return $translate('ERROR_GIST_FORMAT').then(function(errorStr) {
44 | return $q.reject(errorStr);
45 | });
46 | }
47 | return {
48 | 'schema': result.data.files['schema'].content,
49 | 'document': result.data.files['document'].content
50 | };
51 | }, function(error) {
52 | $log.error('Could not retrieve gist', error);
53 | throw error.statusText;
54 | });
55 | };
56 |
57 | });
--------------------------------------------------------------------------------
/src/services/MarkupJson.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var app = angular.module('app', false);
4 |
5 | app.service('markupJson', function ($q) {
6 |
7 | this.parse = function (text) {
8 | return $q(function (resolve, reject) {
9 | try {
10 | var obj = JSON.parse(text);
11 | resolve(obj);
12 | } catch (err) {
13 | reject([{
14 | message_tid: 'ERROR_INVALID_JSON'
15 | }]);
16 | }
17 | });
18 | };
19 |
20 | this.prettyPrint = function(obj) {
21 | return $q.when(JSON.stringify(obj, null, ' '));
22 | };
23 |
24 | });
--------------------------------------------------------------------------------
/src/services/MarkupYaml.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var app = angular.module('app', false);
4 |
5 | app.service('markupYaml', function ($window, $q, alertService, $log) {
6 |
7 | var yaml;
8 |
9 | var _setupPromise;
10 | var setup = function() {
11 | return _setupPromise || (_setupPromise = $q(function(resolve, reject) {
12 | try {
13 | require.ensure([], function(require) {
14 | yaml = require('yamljs');
15 | $log.debug('MarkupYAML.setup()', 'Loaded yamljs');
16 | resolve(true);
17 | });
18 | } catch (error) {
19 | $log.error('MarkupYAML.setup()', 'Could not load yamljs', error);
20 | alertService.alert({
21 | title: '{{ "ERROR_MODULE_LOADING_FAILED_TITLE" | translate }}',
22 | message: '{{ "ERROR_MODULE_LOADING_FAILED_CONTENT" | translate }}'
23 | });
24 | reject(error);
25 | }
26 | }));
27 | };
28 |
29 | this.parse = function (text) {
30 | return setup().then(function () {
31 | try {
32 | var obj = yaml.parse(text);
33 | return obj;
34 | } catch (err) {
35 | throw [{
36 | message_tid: 'ERROR_INVALID_YAML'
37 | }];
38 | }
39 | });
40 | };
41 |
42 | this.prettyPrint = function (obj) {
43 | // We wrap this in $q otherwise the digest doesn't fire correctly
44 | return setup().then(function () {
45 | return yaml.stringify(obj, 4, 2);
46 | });
47 | };
48 |
49 | });
50 |
--------------------------------------------------------------------------------
/src/services/MetaSchemaLoader.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.draft4 = require('../../node_modules/ajv/lib/refs/json-schema-draft-04.json');
4 | exports.draft6 = require('../../node_modules/ajv/lib/refs/json-schema-draft-06.json');
5 | exports.draft7 = require('../../node_modules/ajv/lib/refs/json-schema-draft-07.json');
6 |
--------------------------------------------------------------------------------
/src/services/TextService.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var app = angular.module('app', false);
4 |
5 | app.service('textService', function($q, $window, $log) {
6 |
7 | var self = this;
8 |
9 | this._schemaString;
10 | this._documentString;
11 |
12 | // Accessors
13 | this.getSchema = function() {
14 | return self._schemaString;
15 | };
16 | this.setSchema = function(str) {
17 | if (str !== self._schemaString) {
18 | $window.ga('send', {
19 | hitType: 'event',
20 | eventCategory: 'Content',
21 | eventAction: 'Schema-Change'
22 | });
23 | }
24 | self._schemaString = str;
25 | };
26 | this.getDocument = function() {
27 | return self._documentString;
28 | };
29 | this.setDocument = function(str) {
30 | if (str !== self._documentString) {
31 | $window.ga('send', {
32 | hitType: 'event',
33 | eventCategory: 'Content',
34 | eventAction: 'Document-Change'
35 | });
36 | }
37 | self._documentString = str;
38 | };
39 |
40 | this.reset = function() {
41 | // Analytics
42 | $window.ga('send', {
43 | hitType: 'event',
44 | eventCategory: 'Content',
45 | eventAction: 'Reset'
46 | });
47 |
48 | delete self._schemaString;
49 | delete self._documentString;
50 | ls.removeItem('data');
51 | ls.removeItem('schema');
52 | };
53 |
54 | // Load document & schema from localstorage
55 | var ls = $window['localStorage'];
56 | if (ls.getItem('data')) {
57 | $log.info('Loading document from local storage');
58 | self._documentString = ls.getItem('data');
59 | }
60 | if (ls.getItem('schema')) {
61 | $log.info('Loading schema from local storage');
62 | self._schemaString = ls.getItem('schema');
63 | }
64 |
65 | // Save form data to localstorage before unload
66 | $window.addEventListener('beforeunload', function() {
67 | if (self._documentString) {
68 | ls.setItem('data', self._documentString);
69 | } else {
70 | ls.removeItem('data');
71 | }
72 | if (self._schemaString) {
73 | ls.setItem('schema', self._schemaString);
74 | } else {
75 | ls.removeItem('schema');
76 | }
77 | });
78 |
79 | });
80 |
--------------------------------------------------------------------------------
/src/services/ValidatorFactoryAJV.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var app = angular.module('app', false);
4 |
5 | // Handles draft-04 and up
6 | app.factory('validatorFactoryAJV', function ($window, $q, alertService, $log) {
7 |
8 | var Validator = function (version) {
9 | // Initially unset for lazy-loading
10 | var validator;
11 |
12 | var _setupPromise;
13 | var setup = function () {
14 | return _setupPromise || (_setupPromise = $q(function(resolve, reject) {
15 | try {
16 | require.ensure([], function(require) {
17 | var ajv = require('ajv');
18 | var schemas = require('./MetaSchemaLoader');
19 | $log.debug('ValidatorFactoryAJV.setup()', 'Loaded AJV');
20 |
21 | validator = ajv({
22 | verbose: true,
23 | allErrors: true,
24 | meta: false, // Don't load a meta-schema by default
25 | //
26 | // Loading logic follows guidance at
27 | // https://github.com/epoberezkin/ajv/releases/tag/5.0.0
28 | // and
29 | // https://github.com/epoberezkin/ajv/releases/tag/v6.0.0
30 | //
31 | unknownFormats: 'draft-04' === version ? 'ignore' : undefined,
32 | extendRefs: 'draft-04' === version ? true : undefined,
33 | schemaId: 'draft-04' === version ? 'id': undefined
34 | });
35 |
36 | if (version === 'draft-04') {
37 | validator.addMetaSchema(schemas.draft4);
38 | validator._opts.defaultMeta = schemas.draft4.id;
39 | validator._refs['http://json-schema.org/schema'] = 'http://json-schema.org/draft-04/schema';
40 | validator.removeKeyword('propertyNames');
41 | validator.removeKeyword('contains');
42 | validator.removeKeyword('const');
43 | }
44 | else if (version === 'draft-06') {
45 | validator.addMetaSchema(schemas.draft6);
46 | validator._opts.defaultMeta = schemas.draft6.$id;
47 | }
48 | else if (version === 'draft-07') {
49 | validator.addMetaSchema(schemas.draft7);
50 | validator._opts.defaultMeta = schemas.draft7.$id;
51 | }
52 | resolve(true);
53 | });
54 | } catch (error) {
55 | $log.error('ValidatorFactoryAJV.setup()', 'Could not load AJV', error);
56 | alertService.alert({
57 | title: '{{ "ERROR_MODULE_LOADING_FAILED_TITLE" | translate }}',
58 | message: '{{ "ERROR_MODULE_LOADING_FAILED_CONTENT" | translate }}'
59 | });
60 | reject(error);
61 | }
62 | }));
63 | };
64 |
65 | this.validateSchema = function (schemaObject) {
66 | $log.debug('ValidatorFactoryAJV.validateSchema()');
67 | return setup().then(function () {
68 | if (validator.validateSchema(schemaObject)) {
69 | $log.debug('ValidatorFactoryAJV.validateSchema()', validator.errorsText(validator.errors));
70 | return true;
71 | } else {
72 | $log.debug('ValidatorFactoryAJV.validateSchema()', validator.errorsText(validator.errors));
73 | throw validator.errors;
74 | }
75 | });
76 | };
77 |
78 | this.validate = function (schemaObject, documentObject) {
79 | $log.debug('ValidatorFactoryAJV.validate()');
80 | return setup().then(function () {
81 | var result;
82 | try {
83 | result = validator.validate(schemaObject, documentObject);
84 | } catch (e) {
85 | // Some errors are thrown by Ajv, not wrapped up in its nice validator.errors interface
86 | $log.error('ValidatorFactoryAJV.validate()', e.message);
87 | // Wrap the exception into our standard format
88 | throw [{ message: e.message }];
89 | }
90 | // Validation completed - check the results
91 | if(result) {
92 | $log.debug('ValidatorFactoryAJV.validate()', 'success');
93 | return true;
94 | } else {
95 | $log.error('ValidatorFactoryAJV.validate()', validator.errorsText(validator.errors));
96 | throw validator.errors;
97 | }
98 | });
99 | };
100 | };
101 |
102 | // Factory for AJV validators
103 | return function (version) {
104 | return new Validator(version);
105 | };
106 |
107 | });
108 |
--------------------------------------------------------------------------------
/src/services/ValidatorFactoryJSV.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var app = angular.module('app', false);
4 |
5 | // Handles draft-01, draft-02, draft-03
6 | app.factory('validatorFactoryJSV', function ($window, $q, alertService, $log) {
7 |
8 | var Validator = function (version) {
9 | // Initially unset for lazy-loading
10 | var validator;
11 | var schemaSchema;
12 |
13 | var _setupPromise;
14 | var setup = function () {
15 | // We wrap this in $q otherwise the digest doesn't fire correctly
16 | return _setupPromise || (_setupPromise = $q(function(resolve, reject) {
17 | try {
18 | require.ensure([], function(require) {
19 | var JSV = require('JSV');
20 | $log.debug('ValidatorFactoryJSV.setup()', 'Loaded JSV');
21 | var jsv = JSV.JSV;
22 | //
23 | // VERSION DETERMINATION LOGIC
24 | //
25 | validator = jsv.createEnvironment('json-schema-' + version);
26 | schemaSchema = validator.getDefaultSchema();
27 | resolve(true);
28 | });
29 | } catch (error) {
30 | $log.error('ValidatorFactoryJSV.setup()', 'Could not load JSV', error);
31 | alertService.alert({
32 | title: '{{ "ERROR_MODULE_LOADING_FAILED_TITLE" | translate }}',
33 | message: '{{ "ERROR_MODULE_LOADING_FAILED_CONTENT" | translate }}'
34 | });
35 | reject(error);
36 | }
37 | }));
38 | };
39 |
40 | // Convert JSV errors into something the tables understand
41 | var mapError = function (e) {
42 | var field = e.uri.substring(e.uri.indexOf('#') + 1);
43 | return {
44 | dataPath: field,
45 | message: e.message,
46 | data: e.details.length ? e.details[0] : ''
47 | };
48 | };
49 |
50 | this.validateSchema = function (schemaObject) {
51 | $log.debug('ValidatorFactoryJSV.validateSchema()');
52 | return setup().then(angular.bind(this, function () {
53 | var results = validator.validate(schemaObject, schemaSchema);
54 | if (!results.errors || !results.errors.length) {
55 | $log.debug('ValidatorFactoryJSV.validateSchema()', 'success');
56 | return true;
57 | } else {
58 | $log.debug('ValidatorFactoryJSV.validateSchema()', 'failure', results.errors);
59 | throw results.errors.map(mapError);
60 | }
61 | }));
62 | };
63 |
64 | this.validate = function (schemaObject, documentObject) {
65 | $log.debug('ValidatorFactoryJSV.validate()');
66 | return setup().then(angular.bind(this, function () {
67 | var results = validator.validate(documentObject, schemaObject);
68 | if (!results.errors || !results.errors.length) {
69 | $log.debug('ValidatorFactoryJSV.validate()', 'success');
70 | return true;
71 | } else {
72 | $log.debug('ValidatorFactoryJSV.validate()', 'failure', results.errors);
73 | throw results.errors.map(mapError);
74 | }
75 | }));
76 | };
77 | };
78 |
79 | // Factory for JSV validators
80 | return function (version) {
81 | return new Validator(version);
82 | };
83 |
84 | });
85 |
--------------------------------------------------------------------------------
/src/services/index.js:
--------------------------------------------------------------------------------
1 | require('./AlertService');
2 | require('./Gist');
3 | require('./MarkupJson');
4 | require('./MarkupYaml');
5 | require('./MetaSchemaLoader');
6 | require('./TextService');
7 | require('./ValidatorFactoryAJV');
8 | require('./ValidatorFactoryJSV');
--------------------------------------------------------------------------------
/src/vendor.js:
--------------------------------------------------------------------------------
1 | // This file contains "vendor" packages that should be pulled out of the app.js chunk created by webpack
2 | require('babel-polyfill');
3 | require('bootstrap/dist/css/bootstrap.min.css');
4 | require('angular');
5 | require('angular-route');
6 | require('angular-sanitize');
7 | require('angular-translate');
8 | require('angular-translate-loader-static-files');
9 | require('angular-ui-bootstrap');
10 |
--------------------------------------------------------------------------------
/tests/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "no-unused-vars": [0]
4 | },
5 | "globals": {
6 | "beforeEach": true,
7 | "expect": true,
8 | "describe": true,
9 | "it": true,
10 | "element": true,
11 | "by": true,
12 | "browser": true,
13 | "inject": true,
14 | "register": true,
15 | "chai": true,
16 | "protractor": true,
17 | "jasmine": true
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tests/components/ValidationMessages.spec.js:
--------------------------------------------------------------------------------
1 | describe('ValidationMessages', function() {
2 | var $compile, $rootScope, $scope;
3 |
4 | // Load the app module, which contains the component
5 | beforeEach(module('app'));
6 |
7 | // Store references to $rootScope and $compile
8 | // so they are available to all tests in this describe block
9 | beforeEach(inject(function(_$compile_, _$rootScope_){
10 | // The injector unwraps the underscores (_) from around the parameter names when matching
11 | $compile = _$compile_;
12 | $rootScope = _$rootScope_;
13 | $scope = $rootScope.$new();
14 | }));
15 |
16 | it('mounts the component', function() {
17 | var element = $compile('
')($scope);
18 | $rootScope.$digest();
19 |
20 | // Must have compiled and inserted a scope properly - check that $scope has a child scope
21 | expect($scope.$$childHead.$ctrl).to.be.ok;
22 | });
23 |
24 | it('doesn\'t mount a misnamed component', function() {
25 | var element = $compile('
')($scope);
26 | $rootScope.$digest();
27 |
28 | // Should not have compiled and inserted a scope properly
29 | expect($scope.$$childHead).not.to.be.ok;
30 | });
31 |
32 | it('is empty when given no data', function() {
33 | var element = $compile('
')($scope);
34 | $rootScope.$digest();
35 |
36 | expect(element[0].querySelectorAll('*')).to.have.length(0);
37 | });
38 |
39 | it('has a row for each message', function() {
40 | var element = $compile('
')($scope);
41 | $rootScope.$digest();
42 |
43 | var $ctrl = $scope.$$childHead.$ctrl;
44 |
45 | // Simple messages
46 | $scope.scopeProp = [ { 'message':'foo' }, { 'message':'foo' } ];
47 | $rootScope.$digest();
48 |
49 | expect(element[0].querySelectorAll('tbody tr')).to.have.length(2);
50 |
51 | // Complex messages
52 | $scope.scopeProp = [ { 'message':'foo', 'dataPath': 'bar' }, { 'message':'foo', 'dataPath': 'bar2' }, { 'message':'foo', 'dataPath': 'bar3' } ];
53 | $rootScope.$digest();
54 |
55 | expect(element[0].querySelectorAll('tbody tr')).to.have.length(3);
56 |
57 | });
58 |
59 | it('correctly classifies simple and error messages', function() {
60 | var element = $compile('
')($scope);
61 | $rootScope.$digest();
62 |
63 | var $ctrl = $scope.$$childHead.$ctrl;
64 |
65 | expect($ctrl.simpleMessages([{ message: 'foo' }])).to.have.length(1);
66 | expect($ctrl.errorMessages([{ message: 'foo' }])).to.have.length(0);
67 |
68 | expect($ctrl.simpleMessages([{ message: 'foo', 'dataPath': '' }])).to.have.length(0);
69 | expect($ctrl.errorMessages([{ message: 'foo', 'dataPath': '' }])).to.have.length(1);
70 |
71 | expect($ctrl.simpleMessages([{ message: 'foo', 'dataPath': 'bar' }])).to.have.length(0);
72 | expect($ctrl.errorMessages([{ message: 'foo', 'dataPath': 'bar' }])).to.have.length(1);
73 | });
74 | });
75 |
--------------------------------------------------------------------------------
/tests/components/Validator.spec.js:
--------------------------------------------------------------------------------
1 | describe('Validator', function() {
2 | var $compile,
3 | $rootScope,
4 | $scope,
5 | $q;
6 |
7 | // Load the app module, which contains the component
8 | beforeEach(module('app'));
9 |
10 | // Store references to $rootScope and $compile
11 | // so they are available to all tests in this describe block
12 | beforeEach(inject(function(_$compile_, _$rootScope_, _$q_) {
13 | // The injector unwraps the underscores (_) from around the parameter names when matching
14 | $q = _$q_;
15 | $compile = _$compile_;
16 | $rootScope = _$rootScope_;
17 | $scope = $rootScope.$new();
18 | }));
19 |
20 | // // Debug logging logic
21 | // var $log;
22 | //
23 | // // Inject the $log service
24 | // beforeEach(inject(function(_$log_){
25 | // $log = _$log_;
26 | // }));
27 | //
28 | // // Log debug messages in Karma
29 | // afterEach(function(){
30 | // console.log($log.debug.logs);
31 | // });
32 |
33 | // Utility method to create an element and get a reference to its controller, from some injected HTML
34 | const _createInstance = (html) => {
35 | let element = $compile(html)($scope);
36 | $rootScope.$digest();
37 |
38 | let $ctrl = $scope.$$childHead.$ctrl;
39 |
40 | return {element, $ctrl};
41 | };
42 |
43 | it('mounts the component', function() {
44 | const {element, $ctrl} = _createInstance('
');
45 |
46 | // Must have compiled and inserted a scope properly - check that $scope has a child scope
47 | expect($scope.$$childHead.$ctrl).to.be.ok;
48 | });
49 |
50 | it('accepts a validate function', function() {
51 | $scope.echo = function(a) {
52 | return a;
53 | };
54 |
55 | const {element, $ctrl} = _createInstance('
');
56 |
57 | expect($ctrl).to.be.ok;
58 | expect($ctrl.validate).to.be.a.function;
59 | expect($ctrl.validate('foo')).to.eql('foo');
60 | });
61 |
62 | it('accepts a parse function', function() {
63 | $scope.echo = function(a) {
64 | return a;
65 | };
66 |
67 | const {element, $ctrl} = _createInstance('
');
68 |
69 | expect($ctrl).to.be.ok;
70 | expect($ctrl.parse).to.be.a.function;
71 | expect($ctrl.parse('foo')).to.eql('foo');
72 | });
73 |
74 | it('contains a form with a document text area', function() {
75 | const {element, $ctrl} = _createInstance('
');
76 |
77 | expect(element[0].querySelector('form textarea.validator-document')).not.to.be.empty;
78 | });
79 |
80 | it('binds its document textarea to its document model', function() {
81 | $scope.scopeProp = 'foo';
82 |
83 | const {element, $ctrl} = _createInstance('
');
84 |
85 | var textarea = element[0].querySelector('form textarea.validator-document');
86 | expect(textarea.value).to.eql('foo');
87 | });
88 |
89 | it('doesn\'t call update when nothing is changed', function() {
90 | const {element, $ctrl} = _createInstance('
');
91 |
92 | var spy = chai.spy.on($ctrl, 'update');
93 |
94 | // Run a digest
95 | $rootScope.$digest();
96 |
97 | expect(spy).to.not.have.been.called();
98 | });
99 |
100 | it('calls update when the validate function is changed', function() {
101 | const {element, $ctrl} = _createInstance('
');
102 |
103 | var spy = chai.spy.on($ctrl, 'update');
104 |
105 | // Change the function
106 | $scope.fn = function() {
107 | // blah
108 | };
109 | $rootScope.$digest();
110 |
111 | expect(spy).to.have.been.called.once;
112 | });
113 |
114 | it('calls update when the parse function is changed', function() {
115 | const {element, $ctrl} = _createInstance('
');
116 |
117 | var spy = chai.spy.on($ctrl, 'update');
118 |
119 | // Change the function
120 | $scope.fn = function() {
121 | // blah
122 | };
123 | $rootScope.$digest();
124 |
125 | expect(spy).to.have.been.called.once;
126 | });
127 |
128 | it('calls update when the injected document changes', function() {
129 | const {element, $ctrl} = _createInstance('
');
130 |
131 | var spy = chai.spy.on($ctrl, 'update');
132 |
133 | // Change the injected document
134 | $scope.upperDoc = 'flibble!'
135 | $rootScope.$digest();
136 |
137 | expect(spy).to.have.been.called.once;
138 | });
139 |
140 | it('doesn\'t call update when the injected document changes, but it\'s identical to the internal document', function() {
141 | const {element, $ctrl} = _createInstance('
');
142 |
143 | // Set up the internal state
144 | $ctrl.myDoc = 'flibble!';
145 | $ctrl.update($ctrl.myDoc);
146 | $rootScope.$digest();
147 |
148 | var spy = chai.spy.on($ctrl, 'update');
149 |
150 | // Change the injected document
151 | $scope.upperDoc = 'flibble!'
152 | $rootScope.$digest();
153 |
154 | expect(spy).to.not.have.been.called();
155 | });
156 |
157 | it('calls on-update-obj with null when the injected document doesn\'t validate', function() {
158 | const spy = chai.spy(function(params) {});
159 | $scope.onUpdateObj = spy;
160 |
161 | const {element, $ctrl} = _createInstance('
');
162 |
163 | // We *must* use $q else the promises don't resolve properly :/
164 | // Pretend it parses
165 | $ctrl.parse = () => $q.resolve({});
166 | // But that it doesn't validate
167 | $ctrl.validate = () => $q.reject([]);
168 | $rootScope.$digest();
169 |
170 | // Change the injected document
171 | $scope.upperDoc = 'flibble!'
172 | $rootScope.$digest();
173 |
174 | expect(spy).to.have.been.called.once;
175 | expect(spy).to.have.been.always.with.exactly(null);
176 | });
177 |
178 | it('calls on-update-obj with null when the injected document doesn\'t parse', function() {
179 | const spy = chai.spy(function(params) {});
180 | $scope.onUpdateObj = spy;
181 |
182 | const {element, $ctrl} = _createInstance('
');
183 |
184 | // We *must* use $q else the promises don't resolve properly :/
185 | // Pretend it doesn't parse
186 | $ctrl.parse = () => $q.reject([]);
187 | // But that it does (somehow! magic!) validate
188 | $ctrl.validate = () => $q.resolve({});
189 | $rootScope.$digest();
190 |
191 | // Change the injected document
192 | $scope.upperDoc = 'flibble!'
193 | $rootScope.$digest();
194 |
195 | expect(spy).to.have.been.called.once;
196 | expect(spy).to.have.been.always.with.exactly(null);
197 | });
198 |
199 | it('calls on-update-obj with a value when the injected document parses and validates', function() {
200 | const spy = chai.spy(function(params) {});
201 | $scope.onUpdateObj = spy;
202 |
203 | const {element, $ctrl} = _createInstance('
');
204 |
205 | // We *must* use $q else the promises don't resolve properly :/
206 | // Pretend it parses
207 | $ctrl.parse = () => $q.resolve({foo: 'bar'});
208 | // And that it validates
209 | $ctrl.validate = () => $q.resolve({});
210 | $rootScope.$digest();
211 |
212 | // Change the injected document
213 | $scope.upperDoc = 'flibble!'
214 | $rootScope.$digest();
215 |
216 | expect(spy).to.have.been.called.once;
217 | expect(spy).to.have.been.always.with.exactly({foo: 'bar'});
218 | });
219 |
220 | it('calls on-update-doc with a value when the injected document changes', function() {
221 | const spy = chai.spy(function(params) {});
222 | $scope.onUpdateDoc = spy;
223 |
224 | const {element, $ctrl} = _createInstance('
');
225 | $rootScope.$digest();
226 |
227 | expect($ctrl.onUpdateDoc).to.be.a.function;
228 |
229 | // Change the injected document
230 | $scope.upperDoc = 'flibble!'
231 | $rootScope.$digest();
232 |
233 | expect(spy).to.have.been.called.once;
234 | expect(spy).to.have.been.always.with.exactly('flibble!');
235 | });
236 |
237 | });
238 |
--------------------------------------------------------------------------------
/webpack.common.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 | var ngAnnotatePlugin = require('ng-annotate-webpack-plugin');
3 | var HtmlWebpackPlugin = require('html-webpack-plugin');
4 | var CopyWebpackPlugin = require('copy-webpack-plugin');
5 | var ExtractTextPlugin = require('extract-text-webpack-plugin');
6 | var WebpackMd5Hash = require('webpack-md5-hash');
7 | var path = require('path');
8 |
9 | module.exports = {
10 | cache: true,
11 | entry: {
12 | app: './src/app.js',
13 | vendor: './src/vendor.js',
14 | },
15 | output: {
16 | path: path.resolve(__dirname, 'dist'),
17 | publicPath: '',
18 | filename: '[name].[chunkhash].js',
19 | chunkFilename: '[id].[chunkhash].js'
20 | },
21 | stats: {
22 | // Configure the console output
23 | colors: true,
24 | modules: true,
25 | reasons: true
26 | },
27 | module: {
28 | loaders: [
29 | {
30 | test: /\.js?$/,
31 | loader: 'babel-loader',
32 | exclude: /node_modules/,
33 | query: {
34 | presets: [
35 | ['env', {
36 | 'targets': {
37 | 'browsers': ['last 2 versions']
38 | }
39 | }]
40 | ]
41 | }
42 | },
43 | { test: /\.css$/, loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader' })},
44 | { test: /\.(woff2?|ttf|eot|svg)$/, loader: 'file-loader?name=fonts/[name].[ext]' },
45 | ]
46 | },
47 | plugins: [
48 | new WebpackMd5Hash(),
49 | new webpack.optimize.CommonsChunkPlugin({
50 | name: ['app', 'vendor']
51 | }),
52 | new CopyWebpackPlugin([
53 | { from: 'www' }
54 | ]),
55 | new HtmlWebpackPlugin({
56 | template: 'html-loader!./www/index.html',
57 | }),
58 | new ExtractTextPlugin('[name].[chunkhash].css'),
59 | new webpack.ProvidePlugin({
60 | 'Promise': 'es6-promise' // Thanks Aaron (https://gist.github.com/Couto/b29676dd1ab8714a818f#gistcomment-1584602)
61 | }),
62 | new ngAnnotatePlugin({add: true}),
63 | new webpack.optimize.UglifyJsPlugin({
64 | compress: {
65 | warnings: false
66 | },
67 | sourceMap: true
68 | })
69 | ],
70 | node: {
71 | fs: 'empty'
72 | },
73 | profile: true
74 | };
75 |
--------------------------------------------------------------------------------
/webpack.dev.config.js:
--------------------------------------------------------------------------------
1 | var webpackMerge = require('webpack-merge');
2 | var commonConfig = require('./webpack.common.config.js');
3 |
4 | module.exports = webpackMerge(commonConfig, {
5 | devtool: 'cheap-module-eval-source-map',
6 | devServer: {
7 | historyApiFallback: true,
8 | stats: 'minimal',
9 | contentBase: __dirname + "/www/",
10 | }
11 | });
12 |
--------------------------------------------------------------------------------
/webpack.prod.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 | var webpackMerge = require('webpack-merge');
3 | var commonConfig = require('./webpack.common.config.js');
4 |
5 | module.exports = webpackMerge(commonConfig, {
6 | plugins: [
7 | new webpack.optimize.UglifyJsPlugin({
8 | compress: {
9 | warnings: false
10 | },
11 | sourceMap: true
12 | })
13 | ]
14 | });
15 |
--------------------------------------------------------------------------------
/www/.htaccess:
--------------------------------------------------------------------------------
1 |
2 | Order Allow,Deny
3 | Deny from all
4 |
5 |
6 | ExpiresActive On
7 | ExpiresDefault "access plus 1 week"
8 |
--------------------------------------------------------------------------------
/www/draft3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Please update your bookmarks - this is not a valid URL.
11 |
12 |
13 | Redirecting you in 10 seconds.
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/www/draft4/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Please update your bookmarks - this is not a valid URL.
11 |
12 |
13 | Redirecting you in 10 seconds.
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/www/draft5/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Please update your bookmarks - this is not a valid URL.
11 |
12 |
13 | Redirecting you in 10 seconds.
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/www/ga.js:
--------------------------------------------------------------------------------
1 | window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
2 | ga('create', 'UA-30596645-1', 'auto');
3 | ga('set', 'anonymizeIp', true); // Anonymise IP
4 | ga('set', 'allowAdFeatures', false); // Disable ad features regardless of dashboard settings
5 | ga('set', 'forceSSL', true);
6 | // ga('send', 'pageview'); // We do this on hashchange
--------------------------------------------------------------------------------
/www/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
JSON Schema Lint :: JSON Schema Validator
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 |
25 |
26 | Error:
27 | This application requires JavaScript to run. Please enable JavaScript to continue.
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/www/samples/draft4/invalid.document.json:
--------------------------------------------------------------------------------
1 | {
2 | "foo": "this is a string, not a number",
3 | "bar": "this is a string that isn't allowed"
4 | }
5 |
--------------------------------------------------------------------------------
/www/samples/draft4/invalid.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "Any validation failures are shown in the right-hand Messages pane.",
3 | "type": "object",
4 | "properties": {
5 | "foo": {
6 | "type": "number"
7 | },
8 | "bar": {
9 | "type": "string",
10 | "enum": [
11 | "a",
12 | "b",
13 | "c"
14 | ]
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/www/samples/draft4/valid.document.json:
--------------------------------------------------------------------------------
1 | {
2 | "foo": 12345,
3 | "bar": "a"
4 | }
5 |
--------------------------------------------------------------------------------
/www/samples/draft4/valid.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "Any validation failures are shown in the right-hand Messages pane.",
3 | "type": "object",
4 | "properties": {
5 | "foo": {
6 | "type": "number"
7 | },
8 | "bar": {
9 | "type": "string",
10 | "enum": [
11 | "a",
12 | "b",
13 | "c"
14 | ]
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/www/samples/draft6/invalid.document.json:
--------------------------------------------------------------------------------
1 | {
2 | "foo": "Not a number",
3 | "bar": "Doesn't equal constant",
4 | "baz": {
5 | "staticProperty": ["This array needs at least one number"],
6 | "property1": "The propertyNames keyword is an alternative to patternProperties",
7 | "pr()perty2": "All property names must match supplied conditions (in this case, it's a regex)"
8 | }
9 | }
--------------------------------------------------------------------------------
/www/samples/draft6/invalid.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "object",
3 | "properties": {
4 | "foo": {
5 | "type": "number"
6 | },
7 | "bar": {
8 | "const": "Must equal this value"
9 | },
10 | "baz": {
11 | "type": "object",
12 | "properties": {
13 | "staticProperty": {
14 | "type": "array",
15 | "contains": {
16 | "type": "number"
17 | }
18 | }
19 | },
20 | "propertyNames": {
21 | "pattern": "^([0-9a-zA-Z]*)$"
22 | },
23 | "additionalProperties": {
24 | "type": "string"
25 | }
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/www/samples/draft6/valid.document.json:
--------------------------------------------------------------------------------
1 | {
2 | "foo": 32,
3 | "bar": "Must equal this value",
4 | "baz": {
5 | "staticProperty": ["This needs at least one number", 32],
6 | "property1": "The propertyNames keyword is an alternative to patternProperties",
7 | "property2": "All property names must match supplied conditions (in this case, it's a regex)"
8 | }
9 | }
--------------------------------------------------------------------------------
/www/samples/draft6/valid.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "object",
3 | "properties": {
4 | "foo": {
5 | "type": "number"
6 | },
7 | "bar": {
8 | "const": "Must equal this value"
9 | },
10 | "baz": {
11 | "type": "object",
12 | "properties": {
13 | "staticProperty": {
14 | "type": "array",
15 | "contains": {
16 | "type": "number"
17 | }
18 | }
19 | },
20 | "propertyNames": {
21 | "pattern": "^([0-9a-zA-Z]*)$"
22 | },
23 | "additionalProperties": {
24 | "type": "string"
25 | }
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/www/samples/experimental/invalid.document.json:
--------------------------------------------------------------------------------
1 | {
2 | "foo": "Should be equal to bar",
3 | "bar": "These should be identical",
4 | "baz": {
5 | "staticProperty": ["This needs at least one number"],
6 | "prop erty1": "The propertyNames keyword is an alternative to patternProperties",
7 | "pr()perty2": "All property names must match supplied conditions (in this case, it's a regex)"
8 | },
9 | "rangeExample": 6,
10 | "ifExample": {
11 | "foo": true,
12 | "bar": "Where is baz?"
13 | }
14 | }
--------------------------------------------------------------------------------
/www/samples/experimental/invalid.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "object",
3 | "properties": {
4 | "foo": {
5 | "const": {
6 | "$data": "/bar"
7 | }
8 | },
9 | "bar": {
10 | "type": "string"
11 | },
12 | "baz": {
13 | "type": "object",
14 | "properties": {
15 | "staticProperty": {
16 | "type": "array",
17 | "contains": {
18 | "type": "number"
19 | }
20 | }
21 | },
22 | "propertyNames": {
23 | "pattern": "^([0-9a-zA-Z]*)$"
24 | },
25 | "additionalProperties": {
26 | "type": "string"
27 | }
28 | },
29 | "rangeExample": {
30 | "type": "number",
31 | "range": [0,5]
32 | },
33 | "ifExample": {
34 | "type": "object",
35 | "if": {
36 | "enum": [true]
37 | },
38 | "then": {
39 | "required": ["bar"]
40 | },
41 | "else": {
42 | "required": ["baz"]
43 | }
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/www/samples/experimental/valid.document.json:
--------------------------------------------------------------------------------
1 | {
2 | "foo": "These should be identical",
3 | "bar": "These should be identical",
4 | "baz": {
5 | "staticProperty": ["This needs at least one number", 32],
6 | "property1": "The propertyNames keyword is an alternative to patternProperties",
7 | "property2": "All property names must match supplied conditions (in this case, it's a regex)"
8 | },
9 | "rangeExample": 3,
10 | "ifExample": {
11 | "foo": true,
12 | "baz": 32
13 | }
14 | }
--------------------------------------------------------------------------------
/www/samples/experimental/valid.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "object",
3 | "properties": {
4 | "foo": {
5 | "const": {
6 | "$data": "/bar"
7 | }
8 | },
9 | "bar": {
10 | "type": "string"
11 | },
12 | "baz": {
13 | "type": "object",
14 | "properties": {
15 | "staticProperty": {
16 | "type": "array",
17 | "contains": {
18 | "type": "number"
19 | }
20 | }
21 | },
22 | "propertyNames": {
23 | "pattern": "^([0-9a-zA-Z]*)$"
24 | },
25 | "additionalProperties": {
26 | "type": "string"
27 | }
28 | },
29 | "rangeExample": {
30 | "type": "number",
31 | "range": [0,5]
32 | },
33 | "ifExample": {
34 | "type": "object",
35 | "if": {
36 | "enum": [true]
37 | },
38 | "then": {
39 | "required": ["bar"]
40 | },
41 | "else": {
42 | "required": ["baz"]
43 | }
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/www/samples/v5-unofficial/invalid.document.json:
--------------------------------------------------------------------------------
1 | {
2 | "foo": 12345,
3 | "moreThanFoo": 12344,
4 | "bar": "I love the constant keyword!",
5 | "sameAsBar": "I hate the constant keyword.",
6 | "baz": {
7 | "foo": 1234,
8 | "foobaz": "This is one of many ways to incorrectly format data with this switch schema."
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/www/samples/v5-unofficial/invalid.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "Any validation failures are shown in the right-hand Messages pane.",
3 | "type": "object",
4 | "properties": {
5 | "foo": {
6 | "type": "number"
7 | },
8 | "moreThanFoo": {
9 | "type": "number",
10 | "minimum": {
11 | "$data": "1/foo"
12 | },
13 | "exclusiveMinimum": true
14 | },
15 | "bar": {
16 | "type":"string"
17 | },
18 | "sameAsBar": {
19 | "constant": {
20 | "$data": "1/bar"
21 | }
22 | },
23 | "baz": {
24 | "type": "object",
25 | "switch": [
26 | {
27 | "if": {
28 | "properties": {
29 | "foo": {
30 | "constant": {
31 | "$data": "2/foo"
32 | }
33 | }
34 | },
35 | "required": ["foo"]
36 | },
37 | "then": {
38 | "properties": {
39 | "foobaz": {
40 | "type": "string"
41 | }
42 | },
43 | "required": ["foobaz"]
44 | }
45 | },
46 | {
47 | "if": {
48 | "properties": {
49 | "bar": {
50 | "constant": {
51 | "$data": "2/bar"
52 | }
53 | }
54 | },
55 | "required": ["bar"]
56 | },
57 | "then": {
58 | "properties": {
59 | "barbaz": {
60 | "type": "number"
61 | }
62 | },
63 | "required": ["barbaz"]
64 | }
65 | },
66 | {
67 | "then": false
68 | }
69 | ]
70 | }
71 | }
72 | }
--------------------------------------------------------------------------------
/www/samples/v5-unofficial/valid.document.json:
--------------------------------------------------------------------------------
1 | {
2 | "foo": 12345,
3 | "moreThanFoo": 12346,
4 | "bar": "I love the constant keyword!",
5 | "sameAsBar": "I love the constant keyword!",
6 | "baz": {
7 | "foo": 12345,
8 | "foobaz": "Switch statements can get really complicated."
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/www/samples/v5-unofficial/valid.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "Any validation failures are shown in the right-hand Messages pane.",
3 | "type": "object",
4 | "properties": {
5 | "foo": {
6 | "type": "number"
7 | },
8 | "moreThanFoo": {
9 | "type": "number",
10 | "minimum": {
11 | "$data": "1/foo"
12 | },
13 | "exclusiveMinimum": true
14 | },
15 | "bar": {
16 | "type":"string"
17 | },
18 | "sameAsBar": {
19 | "constant": {
20 | "$data": "1/bar"
21 | }
22 | },
23 | "baz": {
24 | "type": "object",
25 | "switch": [
26 | {
27 | "if": {
28 | "properties": {
29 | "foo": {
30 | "constant": {
31 | "$data": "2/foo"
32 | }
33 | }
34 | },
35 | "required": ["foo"]
36 | },
37 | "then": {
38 | "properties": {
39 | "foobaz": {
40 | "type": "string"
41 | }
42 | },
43 | "required": ["foobaz"]
44 | }
45 | },
46 | {
47 | "if": {
48 | "properties": {
49 | "bar": {
50 | "constant": {
51 | "$data": "2/bar"
52 | }
53 | }
54 | },
55 | "required": ["bar"]
56 | },
57 | "then": {
58 | "properties": {
59 | "barbaz": {
60 | "type": "number"
61 | }
62 | },
63 | "required": ["barbaz"]
64 | }
65 | },
66 | {
67 | "then": false
68 | }
69 | ]
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/www/translations/locale-en.json:
--------------------------------------------------------------------------------
1 | {
2 | "FORMAT": "Format",
3 | "SAMPLES": "Samples",
4 | "RESET": "Reset",
5 | "SAVE_AS_GIST": "Save as Gist",
6 | "MARKUP_LANGUAGE": "Markup language",
7 | "OFFICIAL_SPEC_VERSION": "Official spec version",
8 | "UNOFFICIAL_SPEC_VERSION": "Unofficial spec version",
9 | "SCHEMA": "Schema",
10 | "DOCUMENT": "Document",
11 | "MESSAGE": "Message",
12 | "FIELD": "Field",
13 | "ERROR": "Error",
14 | "VALUE": "Value",
15 | "TOGGLE_NAVIGATION": "Toggle navigation",
16 | "ABOUT": "About",
17 |
18 | "OK": "OK",
19 |
20 | "GIST_SAVED": "Saved as Gist",
21 | "GIST_VISIT": "Visit saved schema/document pair",
22 |
23 | "sample_titles": {
24 | "draft-04-valid": "Sample draft-04 schema and valid document",
25 | "draft-04-invalid": "Sample draft-04 schema and
invalid document",
26 | "draft-06-valid": "Sample draft-06 schema and valid document",
27 | "draft-06-invalid": "Sample draft-06 schema and
invalid document",
28 | "v5-unofficial-valid": "Sample v5-unofficial schema and valid document",
29 | "v5-unofficial-invalid": "Sample v5-unofficial schema and
invalid document",
30 | "experimental-valid": "Sample experimental schema and valid document",
31 | "experimental-invalid": "Sample experimental schema and
invalid document"
32 | },
33 |
34 | "WARNING_V5_UNOFFICIAL": "
RETIRED schema version. Please use the latest official version instead.
This schema version, v5-unofficial, was a prototype for a draft version that was eventually scrapped. Previously, JSON Schema Lint offered this prototype as \"draft-05\", as it was originally meant to supersede draft-04.
This was not, and will never be, an official JSON Schema version.",
35 | "WARNING_EXPERIMENTAL": "
RETIRED schema version. Please use the latest official version instead.
This was an experimental meta-schema used for testing new features.",
36 |
37 | "SCHEMA_VALID_MESSAGE": "Schema is valid according to {{name}}.",
38 | "DOCUMENT_VALID_MESSAGE": "Document validates against the schema, spec version {{name}}.",
39 |
40 | "ERROR_GIST_SAVING": "Error saving Gist",
41 | "ERROR_GIST_LOADING": "Error loading Gist",
42 |
43 | "ERROR_GIST_FORMAT": "Gist is not in JSON Schema Lint format",
44 |
45 | "ERROR_SAMPLE_LOADING": "Error loading sample",
46 |
47 | "ERROR_INVALID_JSON": "Document is invalid JSON. Try
JSONLint to fix it.",
48 | "ERROR_INVALID_YAML": "Document is invalid YAML. Try
YAML Validator to fix it.",
49 |
50 | "ERROR_INVALID_MARKUP": "Invalid markup language '{{markupLanguage}}'.",
51 | "ERROR_INVALID_VERSION": "Invalid schema version '{{specVersion}}'.",
52 |
53 | "ERROR_INVALID_SCHEMA": "Invalid schema.",
54 |
55 | "ERROR_INVALID_MARKUP_BUTTON": "???",
56 | "ERROR_INVALID_VERSION_BUTTON": "???",
57 |
58 | "ERROR_MODULE_LOADING_FAILED_TITLE": "Could not load module",
59 | "ERROR_MODULE_LOADING_FAILED_CONTENT": "We couldn't load a vital part of the application. This is probably due to network conditions. We recommend reloading the page once conditions improve."
60 |
61 | }
62 |
--------------------------------------------------------------------------------