UNPKG

@patternplate/client

Version:

Universal javascript client application for patternplate

361 lines (332 loc) 10.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.selectActiveItem = exports.selectSuggestion = exports.selectDocs = exports.selectLegend = exports.selectPatterns = exports.selectFound = void 0; var _search = require("@patternplate/search"); var _lodash = require("lodash"); var _reselect = require("reselect"); var _semver = _interopRequireDefault(require("semver")); var _pool = require("./pool"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const FLAGS = { alpha: 0, beta: 1, rc: 2, stable: 3, deprecated: 4 }; const FIELDS = [ /* { type: "field", key: "depends", value: "depends", description: "patterns depending on id", operators: ["=", "!=", "^=", "~="] }, */ { type: "field", key: "version", value: "version", description: "having version of [value]", operators: ["=", "!=", ">", ">=", "<", "<=", "^=", "~="] }, { type: "field", key: "flag", value: "flag", description: "being flagged as [value]", operators: ["=", "!=", ">", ">=", "<", "<=", "^=", "~="] }, /* { type: "field", key: "provides", value: "provides", description: "patterns providing for id", operators: ["=", "!=", "^=", "~="] }, */ { type: "field", key: "tags", value: "tags", description: "having a tag of [value]", operators: ["=", "!=", "^=", "~="] }, { type: "field", key: "path", value: "path", description: "saved at [value] relative to patternplate.config.js", operators: ["=", "*="] }, { type: "field", key: "is", value: "is", description: "being of type [value]", operators: ["=", "!="] }, { type: "field", key: "has", value: "has", description: "having data of [value]", operators: ["=", "!="] }]; const OPERATORS = [{ type: "op", key: "=", description: "exact match" }, { type: "op", key: "!=", description: "negated match" }, { type: "op", key: ">", description: "greater than" }, { type: "op", key: ">=", description: "greater than or equal" }, { type: "op", key: "<", description: "lesser than" }, { type: "op", key: "<=", description: "lesser than or equal" }, { type: "op", key: "^=", description: "starts with" }, { type: "op", key: "~=", description: "contains" }, { type: "op", key: "*=", description: "matches" }]; const selectSearch = (0, _reselect.createSelector)(_pool.flat, _search.createSearch); const selectMatches = (0, _reselect.createSelector)(selectSearch, state => state.search, (search, queryString) => { if (typeof queryString !== "string" || queryString.length < 3) { return []; } return search(queryString); }); const selectParsedValue = (0, _reselect.createSelector)(state => state.searchValue, search => _search.Query.parse(search)); const selectLastQuery = (0, _reselect.createSelector)(selectParsedValue, parsed => last(parsed)); function last(query) { switch (query.type) { case "string": return query.value; case "and": case "or": default: { const q = query || {}; const values = q.values || []; const cand = values[values.length - 1]; return cand ? last(cand) : ""; } } } const selectFields = (0, _reselect.createSelector)(selectLastQuery, query => FIELDS.filter(f => f.value.startsWith(query))); const selectFieldHit = (0, _reselect.createSelector)(state => state.searchValue, selectLastQuery, (value, query) => { if (query.length === 0) { return null; } return FIELDS.find(f => query.startsWith(f.value)); }); const selectParsedQuery = (0, _reselect.createSelector)(selectLastQuery, query => _search.Term.parse(query)); const selectOps = (0, _reselect.createSelector)(selectParsedQuery, selectFieldHit, (parsed, hit) => { if (!hit) { return []; } return hit.operators.map(o => OPERATORS.find(op => op.key === o)).filter(o => !parsed.operators || o.key.includes(parsed.operators)).map(o => { o.value = `${hit.value}${o.key}`; return o; }); }); const selectOpsHit = (0, _reselect.createSelector)(selectParsedQuery, selectOps, (query, ops) => { return ops.find(i => { if (query.negated) { return i.key === `!${query.operators}`; } return i.key === query.operators; }); }); const selectFound = (0, _reselect.createSelector)(_pool.flat, selectMatches, (pool, matches) => { const sorted = (0, _lodash.uniqBy)((0, _lodash.sortBy)(matches.map(match => pool.find(p => p.id === match)), "contentType"), "id"); return sorted.map((s, i) => { s.index = i; return s; }); }); exports.selectFound = selectFound; const selectPatterns = (0, _reselect.createSelector)(selectFound, found => found.filter(f => f.contentType === "pattern")); exports.selectPatterns = selectPatterns; const selectPatternPool = (0, _reselect.createSelector)(_pool.flat, pool => pool.filter(f => f.contentType === "pattern")); const selectOptions = (0, _reselect.createSelector)(selectPatternPool, selectParsedQuery, selectFieldHit, selectOpsHit, (patterns, parsed, field, op) => { if (!field || !op) { return []; } switch (field.key) { case "has": return [{ type: "quality", key: "docs", value: [field.key, op.key, "docs"].join(""), description: "colocated markdown" }, /* { type: "quality", key: "dependencies", value: [field.key, op.key, "dependencies"].join(""), description: "patterns with dependencies" }, { type: "quality", key: "dependents", value: [field.key, op.key, "dependents"].join(""), description: "patterns with dependents" }, */ { type: "quality", key: "flag", value: [field.key, op.key, "flag"].join(""), description: "flag specified" }, { type: "quality", key: "version", value: [field.key, op.key, "version"].join(""), description: "version specified" }, { type: "quality", key: "description", value: [field.key, op.key, "description"].join(""), description: "description provided" }, { type: "quality", key: "displayName", value: [field.key, op.key, "displayName"].join(""), description: "display name provided" }, { type: "quality", key: "tags", value: [field.key, op.key, "tags"].join(""), description: "tag attached" }]; case "depends": case "provides": return patterns.filter(item => item.id.startsWith(parsed.value || "")).map(item => { return { type: "pattern", key: item.id, value: [field.key, op.key, item.id].join(""), description: `${item.id}` }; }); case "tags": return (0, _lodash.uniq)((0, _lodash.flatten)(patterns.map(item => item.manifest.tags))).filter(Boolean).map(tag => { return { type: "tag", key: tag, value: [field.key, op.key, tag].join(""), description: tag }; }); case "version": { const versions = (0, _lodash.uniqBy)(patterns.filter(item => item.manifest.version.startsWith(parsed.value || "")).map(item => item.manifest.version)).filter(version => _semver.default.valid(version)).sort((a, b) => _semver.default.gt(a, b) ? 1 : -1); return versions.map(v => { return { type: "version", key: v, value: [field.key, op.key, v].join(""), description: `${v}` }; }); } case "flag": { const flags = (0, _lodash.uniqBy)(patterns.filter(item => item.manifest.flag.startsWith(parsed.value || "")).map(item => item.manifest.flag)).filter(flag => typeof flag === "string").sort((a, b) => { const delta = (FLAGS[a] || 0) - (FLAGS[b] || 0); return delta === 0 ? a.localeCompare(b) : delta; }); return flags.map(f => { return { type: "flag", key: f, value: [field.key, op.key, f].join(""), description: `${f}` }; }); } case "is": return [{ type: "is", key: "pattern", value: [field.key, op.key, "pattern"].join(""), description: "is a pattern" }, { type: "is", key: "doc", value: [field.key, op.key, "doc"].join(""), description: "is a doc" }]; default: return []; } }); const selectOptionsHit = (0, _reselect.createSelector)(selectParsedQuery, selectOptions, (query, ops) => ops.some(o => o.value === query.raw)); const selectLegend = (0, _reselect.createSelector)(selectParsedValue, selectParsedQuery, selectFields, selectFieldHit, selectOps, selectOpsHit, selectOptions, selectOptionsHit, (parsedValue, parsed, fields, fieldHit, ops, opsHit, options, optionsHit) => { if (!fieldHit) { return { name: "Fields", items: fields }; } if (!opsHit && !parsed.value) { return { name: "Operators", items: ops }; } if (!optionsHit && fieldHit && opsHit) { return { name: fieldHit.key, items: options }; } return { name: "", items: [] }; }); exports.selectLegend = selectLegend; const selectDocs = (0, _reselect.createSelector)(selectFound, found => found.filter(f => f.contentType === "doc")); exports.selectDocs = selectDocs; const selectSuggestion = (0, _reselect.createSelector)(state => state.searchValue, _pool.flat, selectLegend, (search, pool, legend) => { if (typeof search !== "string" || search.length === 0) { return ""; } const match = pool.find(m => [m.id, m.name, (m.manifest || {}).displayName].some(k => k && k.startsWith(search))); if (match) { return [match.id, match.name, match.manifest.displayName].find(k => k && k.startsWith(search)) || ""; } const lmatch = (legend.items || []).find(i => i.value.startsWith(search)); return lmatch ? lmatch.value : null; }); exports.selectSuggestion = selectSuggestion; const selectActiveItem = (0, _reselect.createSelector)(state => state, selectFound, state => state.searchPreview, (state, found, preview) => { const index = Math.min(preview, found.length - 1); const item = found[index]; return item ? Object.assign({}, item, { index, dependents: [], // rel("dependents"), dependencies: [] // rel("dependencies") }) : item; }); exports.selectActiveItem = selectActiveItem; //# sourceMappingURL=found.js.map