/* global lunr */
import lunr from 'lunr'
import mongoose from 'mongoose'
// const lunr = require('lunr')
// console.debug('<>><><><<>><><><><><><><', lunr)
/**
* @author Eduardo Perotta de Almeida <web2solucoes@gmail.com>
* @module utils
* */
/**
* createMethodSignature
* Create default signature method object
* @function
* @param {string|object} error - The string or error object if have any
* @param {object|array|number|string|boolean} data - Information about method execution
* @return {object} signature - Default methods signature format { error, data }
* @return {string|object} signature.error - Execution error
* @return {object|array|number|string|boolean} signature.data - Execution data
*/
export const createMethodSignature = (error = null, data = null) => {
const response = { error, data }
return response
}
/**
* uuid
* generates a Universally unique identifier string
* @function
* @return {string} guid / uuid
*/
export function uuid () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0
const v = c === 'x' ? r : (r & 0x3) | 0x8
return v.toString(16)
})
}
/**
* genDbName
* generates a database name
* @function
* @param {string} appName - Voodux Application Instance name
* @return {string} dbName / uuid
*/
export function genDbName(appName = '') {
appName = appName.toLowerCase().replace(/ /g, '_')
const dbName = `VooduX_${appName}`
return dbName
}
/**
* toJSON - stringify and parse an object<br> It uses native JSON internally.
* @function
* @param {string|object} obj - Valid JSON object or string
* @return {object} new JSON object
*/
export function toJSON (obj = '') {
if (typeof obj === 'string') {
return JSON.parse(obj)
}
return JSON.parse(JSON.stringify(obj))
}
/**
* mongooseToDexieTableString
* convert given Mongoose schema to a Dexie Table columns configuration. <br>
* All columns inside returned configuration are indexed at IndexedDB
* prepend __id as local primary key and _id for remote primary key
* Local primary key is integer and auto incremented
* @function
* @return {string} Dexie table configuration string
*/
export function mongooseToDexieTableString(schema) {
// console.log('XXXXXXX mongooseToDexieTableString')
const cols = []
const notIndexed = []
for (let propertyName in schema.paths) {
if (Object.prototype.hasOwnProperty.call(schema.paths, propertyName)) {
const property = schema.paths[propertyName]
// instance is type
// _index can be boolean or object {unique: true}
// options { default, index, required, unique }
const { instance, _index, options: { unique = false }, /* isRequired */ } = property
if (propertyName === '_id' || propertyName === '__id') {
continue
}
if (!_index) {
notIndexed.push(propertyName)
continue
}
if (instance === 'Array') {
propertyName = `*${propertyName}`// * is MultiEntry Index on Dexie
}
if (unique) {
propertyName = `&${propertyName}` // & is unique Index on Dexie
}
cols.push(propertyName)
} // end if has property
}// end for
const compoundIndexes = getCompoundIndexes(notIndexed, schema)
if (compoundIndexes.length > 0) {
// console.log(`++__id,_id,${compoundIndexes.join(',')}${cols.length > 0 ? (',' + cols.join(',')) : ''}`)
return `++__id,_id,${compoundIndexes.join(',')}${cols.length > 0 ? (',' + cols.join(',')) : ''}`
} else {
// console.log(`++__id,_id${cols.length > 0 ? ',' + cols.join(',') : ''}`)
return `++__id,_id${cols.length > 0 ? ',' + cols.join(',') : ''}`
}
}
/**
* getCompoundIndexes
* @summary PRIVATE getCompoundIndexes() - get compound indexes in a schema
* @description
* Compound keys are NOT initially indexed on schema property level,<br>
* then we need to iterate over schema._index[0], which is the arrray containing all indexes including the compounds
* @function
* @param {array} notIndexed - name of not indexes columns/properties.
* @param {object} schema - data schema object instance
* @return {array} compoundIndexes
*/
function getCompoundIndexes(notIndexed, schema) {
let compoundIndexes = []
const compoundKeys = []
// console.error('>>>>>>>>>>>> schema._indexes.length', schema._indexes.length)
if (schema._indexes.length === 0) {
return compoundIndexes
}
for (let x = 0; x < notIndexed.length; x++) {
const propertyName = notIndexed[x]
// check if this property is listed on compoundKeys
if (compoundKeys.indexOf(propertyName) > -1) {
continue
}
// console.error('>>>>>>>>>>>>', schema._indexes)
const __indexes = schema._indexes[0] // get array of indexes
for (let y = 0; y < __indexes.length; y++) {
const _index = __indexes[y]
const keys = Object.keys(_index)
// if property is a key of current _index then it is compound
if (keys.indexOf(propertyName) > -1) {
compoundIndexes.push(`[${keys[0]}+${keys[1]}]`)
keys.forEach(k => (compoundKeys.push(k)))
// we already built the compound index,
// there is no need to continue to iterate over __indexes
break
}
}
// remove keys from notIndexed array if it is component
}
return compoundIndexes
}
/**
* getSearchTokenStream
* generates a lunr search token. See {@link https://lunrjs.com/guides/searching.html|lunr search}
* @function
* @return {array} token
*/
export function getSearchTokenStream(text = '') {
// console.log('xxxxxxxxx')
// console.log('xxxxxxxxx', index)
// const index = lunr()
// return index.pipeline.run(lunr.tokenizer(text))
const token = (lunr.tokenizer(text)).map(t => (t.str))
return token
// return lunr.tokenizer(text)
}
export const Schema = mongoose.Schema