1247N/AProvides a DataSchema implementation which can be used to work with JSON data. 1247N/AProvides a DataSchema implementation which can be used to work with JSON data. 1247N/ASee the `apply` method for usage. 1247N/A // TODO: I don't think the calls to Base.* need to be done via Base since 1247N/A // Base is mixed into SchemaJSON. Investigate for later. 1247N/A///////////////////////////////////////////////////////////////////////////// 1247N/A///////////////////////////////////////////////////////////////////////////// 1247N/A * Utility function converts JSON locator strings into walkable paths 1247N/A * @param locator {String} JSON value locator. 1247N/A * @return {String[]} Walkable path to data value. 1247N/A // Strip the ["string keys"] and [1] array indexes 1247N/A // TODO: the first two steps can probably be reduced to one with 1247N/A // /\[\s*(['"])?(.*?)\1\s*\]/g, but the array indices would be 1247N/A // stored as strings. This is not likely an issue. 1247N/A function (x,$1,$2) {keys[i]=$2;return '.@
'+(i++);}). 1247N/A function (x,$1) {keys[i]=parseInt($1,10)|0;return '.@
'+(i++);}). 1247N/A replace(/^\./,''); // remove leading dot 1247N/A // Validate against problematic characters. 1247N/A // should be safe. I'm not sure what makes a locator invalid. 1247N/A //if (!/[^\w\.\$@]/.test(locator)) { 1247N/A Y.log("Invalid locator: " + locator, "error", "dataschema-json"); 1247N/A * Utility function to walk a path and return the value located there. 1247N/A * @param path {String[]} Locator path. 1247N/A * @param data {String} Data to traverse. 1247N/A * @return {Object} Data value at location. 1247N/A Applies a schema to an array of data located in a JSON structure, returning 1247N/A a normalized object with results in the `results` property. Additional 1247N/A information can be parsed out of the JSON for inclusion in the `meta` 1247N/A property of the response object. If an error is encountered during 1247N/A processing, an `error` property will be added. 1247N/A The input _data_ is expected to be an object or array. If it is a string, 1247N/A If _data_ contains an array of data records to normalize, specify the 1247N/A _schema.resultListLocator_ as a dot separated path string just as you would 1247N/A reference it in JavaScript. So if your _data_ object has a record array at 1247N/A _data.response.results_, use _schema.resultListLocator_ = 1247N/A "response.results". Bracket notation can also be used for array indices or 1247N/A object properties (e.g. "response['results']"); This is called a "path 1247N/A Field data in the result list is extracted with field identifiers in 1247N/A _schema.resultFields_. Field identifiers are objects with the following 1247N/A * `key` : <strong>(required)</strong> The path locator (String) 1247N/A * `parser`: A function or the name of a function on `Y.Parsers` used 1247N/A to convert the input value into a normalized type. Parser 1247N/A functions are passed the value as input and are expected to 1247N/A If no value parsing is needed, you can use path locators (strings) 1247N/A instead of field identifiers (objects) -- see example below. 1247N/A If no processing of the result list array is needed, _schema.resultFields_ 1247N/A can be omitted; the `response.results` will point directly to the array. 1247N/A If the result list contains arrays, `response.results` will contain an 1247N/A array of objects with key:value pairs assuming the fields in 1247N/A _schema.resultFields_ are ordered in accordance with the data array 1247N/A If the result list contains objects, the identified _schema.resultFields_ 1247N/A will be used to extract a value from those objects for the output result. 1247N/A To extract additional information from the JSON, include an array of 1247N/A path locators in _schema.metaFields_. The collected values will be 1247N/A resultListLocator: 'produce.fruit', 1247N/A resultFields: [ 'name', 'color' ] 1247N/A // response.results[0] is { name: "Banana", color: "yellow" } 1247N/A // Process array of objects + some metadata 1247N/A schema.metaFields = [ 'lastInventory' ]; 1247N/A { name: 'Banana', color: 'yellow', price: '1.96' }, 1247N/A { name: 'Orange', color: 'orange', price: '2.04' }, 1247N/A { name: 'Eggplant', color: 'purple', price: '4.31' } 1247N/A lastInventory: '2011-07-19' 1247N/A // response.results[0] is { name: "Banana", color: "yellow" } 1247N/A // response.meta.lastInventory is '2001-07-19' 1247N/A parser: function (val) { return val.toUpperCase(); } 1247N/A parser: 'number' // Uses Y.Parsers.number 1247N/A // Note price was converted from a numeric string to a number 1247N/A // response.results[0] looks like { fruit: "BANANA", price: 1.96 } 1247N/A @param {Object} [schema] Schema to apply. Supported configuration 1247N/A @param {String} [schema.resultListLocator] Path locator for the 1247N/A location of the array of records to flatten into `response.results` 1247N/A @param {Array} [schema.resultFields] Field identifiers to 1247N/A @param {Array} [schema.metaFields] Path locators to extract extra 1247N/A non-record related information from the data object. 1247N/A @param {Object|Array|String} data JSON data or its string serialization. 1247N/A @return {Object} An Object with properties `results` and `meta` 1247N/A // Convert incoming JSON strings 1247N/A * Schema-parsed list of results from full data 1247N/A * @param schema {Object} Schema to parse against. 1247N/A * @param json_in {Object} JSON to parse. 1247N/A * @param data_out {Object} In-progress parsed data to update. 1247N/A * @return {Object} Parsed data object. 1247N/A // Fall back to treat resultListLocator as a simple key 1247N/A // Or if no resultListLocator is supplied, use the input 1247N/A // if no result fields are passed in, then just take 1247N/A // the results array whole-hog Sometimes you're getting 1247N/A // an array of strings, or want the whole object, so 1247N/A // resultFields don't make sense. 1247N/A * Get field data values out of list of full results 1247N/A * @param fields {Array} Fields to find. 1247N/A * @param array_in {Array} Results to parse. 1247N/A * @param data_out {Object} In-progress parsed data to update. 1247N/A * @return {Object} Parsed data object. 1247N/A // First collect hashes of simple paths, complex paths, and parsers 1247N/A // Validate and store locators for later 1247N/A Y.
log(
"Invalid key syntax: " +
key,
"warn",
"dataschema-json");
1247N/A // Validate and store parsers for later 1247N/A //TODO: use Y.DataSchema.parse? 1247N/A // Traverse list of array_in, creating records of simple fields, 1247N/A // complex fields, and applying parsers as necessary 1247N/A // Cycle through complexLocators 1247N/A // Fail over keys like "foo.bar" from nested parsing 1247N/A // to single token parsing if a value is found in 1247N/A // Don't try to process the path as complex 1247N/A // Cycle through simpleLocators 1247N/A // Bug 1777850: The result might be an array instead of object 1247N/A // Cycle through fieldParsers 1247N/A * Parses results data according to schema 1247N/A * @param metaFields {Object} Metafields definitions. 1247N/A * @param json_in {Object} JSON to parse. 1247N/A * @param data_out {Object} In-progress parsed data to update. 1247N/A * @return {Object} Schema-parsed meta data. 1247N/A// TODO: Y.Object + mix() might be better here