@miso.ai/client-sdk-codegen 1.12.0 → 1.12.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,9 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.decodeParameters = decodeParameters;
7
- exports.encodeParameters = encodeParameters;
8
- function encodeParameters(params) {
6
+ exports.decodeConfig = decodeConfig;
7
+ exports.encodeConfig = encodeConfig;
8
+ function encodeConfig(params) {
9
9
  if (params === undefined || params === null) {
10
10
  return undefined;
11
11
  }
@@ -15,7 +15,7 @@ function encodeParameters(params) {
15
15
  // JSON string -> base64
16
16
  return base64Encode(JSON.stringify(params));
17
17
  }
18
- function decodeParameters(params) {
18
+ function decodeConfig(params) {
19
19
  if (params === undefined || params === null) {
20
20
  return undefined;
21
21
  }
package/dist/cjs/index.js CHANGED
@@ -10,15 +10,15 @@ var _exportNames = {
10
10
  exports.ui = exports.spec = void 0;
11
11
  var _spec = _interopRequireWildcard(require("./spec/index.js"));
12
12
  exports.spec = _spec;
13
- var _params = require("./params.js");
14
- Object.keys(_params).forEach(function (key) {
13
+ var _encoding = require("./encoding.js");
14
+ Object.keys(_encoding).forEach(function (key) {
15
15
  if (key === "default" || key === "__esModule") return;
16
16
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
17
- if (key in exports && exports[key] === _params[key]) return;
17
+ if (key in exports && exports[key] === _encoding[key]) return;
18
18
  Object.defineProperty(exports, key, {
19
19
  enumerable: true,
20
20
  get: function () {
21
- return _params[key];
21
+ return _encoding[key];
22
22
  }
23
23
  });
24
24
  });
@@ -8,27 +8,61 @@ var _utils = require("./utils.js");
8
8
  var _workflowsSlug = require("./workflows.slug.js");
9
9
  const _excluded = ["slug", "workflows"];
10
10
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
11
- var _default = exports.default = [{
12
- slug: 'use-api',
13
- workflows: '*'
11
+ const DEFAULT_BOOLEAN_OPTIONS = [{
12
+ name: 'Off',
13
+ value: undefined
14
14
  }, {
15
+ name: 'On',
16
+ value: true
17
+ }];
18
+ var _default = exports.default = [
19
+ /*
20
+ {
21
+ slug: 'use-api',
22
+ workflows: '*',
23
+ },
24
+ */
25
+ /*
26
+ {
15
27
  slug: 'use-link',
16
- workflows: 'ahes'
17
- }, {
28
+ workflows: 'ahes',
29
+ options: DEFAULT_BOOLEAN_OPTIONS,
30
+ },
31
+ */
32
+ {
18
33
  slug: 'autocomplete',
19
- workflows: 'hs'
20
- }, {
34
+ workflows: 'hs',
35
+ options: DEFAULT_BOOLEAN_OPTIONS
36
+ },
37
+ /*
38
+ {
21
39
  slug: 'pagination',
22
- workflows: 'hs'
23
- }, {
40
+ workflows: 'hs',
41
+ options: DEFAULT_BOOLEAN_OPTIONS,
42
+ },
43
+ */
44
+ {
24
45
  slug: 'facets',
25
- workflows: 'hs'
46
+ workflows: 'hs',
47
+ options: [{
48
+ name: 'Off',
49
+ value: undefined
50
+ }, {
51
+ name: 'Categories',
52
+ value: ['categories']
53
+ }]
54
+ }, {
55
+ slug: 'answer-box',
56
+ workflows: 'h',
57
+ options: DEFAULT_BOOLEAN_OPTIONS
26
58
  }, {
27
59
  slug: 'follow-up',
28
- workflows: 'a'
60
+ workflows: 'a',
61
+ options: DEFAULT_BOOLEAN_OPTIONS
29
62
  }, {
30
63
  slug: 'auto-query',
31
- workflows: 'ahes'
64
+ workflows: 'ahes',
65
+ options: DEFAULT_BOOLEAN_OPTIONS
32
66
  }].reduce((map, _ref) => {
33
67
  let {
34
68
  slug,
@@ -9,6 +9,18 @@ Object.defineProperty(exports, "features", {
9
9
  return _features.default;
10
10
  }
11
11
  });
12
+ Object.defineProperty(exports, "resolvePreset", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _presets.resolvePreset;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "sdks", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _sdks.default;
22
+ }
23
+ });
12
24
  Object.defineProperty(exports, "workflows", {
13
25
  enumerable: true,
14
26
  get: function () {
@@ -17,4 +29,6 @@ Object.defineProperty(exports, "workflows", {
17
29
  });
18
30
  var _workflows = _interopRequireDefault(require("./workflows.js"));
19
31
  var _features = _interopRequireDefault(require("./features.js"));
32
+ var _sdks = _interopRequireDefault(require("./sdks.js"));
33
+ var _presets = require("./presets.js");
20
34
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -3,14 +3,18 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.search = exports.hybridSearch = void 0;
6
+ exports.hybridSearch = void 0;
7
+ exports.resolvePreset = resolvePreset;
8
+ exports.search = void 0;
9
+ var _commons = require("@miso.ai/commons");
10
+ const _excluded = ["workflow", "preset"];
11
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
7
12
  const hybridSearch = exports.hybridSearch = Object.freeze({
8
13
  standard: Object.freeze({
9
14
  workflow: 'hybrid-search',
10
15
  autoQuery: true,
11
16
  autocomplete: true,
12
- facets: ['categories'],
13
- answerBox: true
17
+ facets: ['categories']
14
18
  }),
15
19
  minimal: Object.freeze({
16
20
  workflow: 'hybrid-search'
@@ -26,4 +30,35 @@ const search = exports.search = Object.freeze({
26
30
  minimal: Object.freeze({
27
31
  workflow: 'search'
28
32
  })
29
- });
33
+ });
34
+ const PRESETS = {
35
+ ['hybrid-search']: hybridSearch,
36
+ search
37
+ };
38
+ function resolvePreset(_ref = {}) {
39
+ let {
40
+ workflow,
41
+ preset
42
+ } = _ref,
43
+ options = _objectWithoutPropertiesLoose(_ref, _excluded);
44
+ if (!workflow) {
45
+ throw new Error('Workflow is required');
46
+ }
47
+ workflow = (0, _commons.lowerCamelToKebab)(workflow); // just in case
48
+ const presets = PRESETS[workflow];
49
+ if (!presets) {
50
+ throw new Error(`Workflow "${workflow}" presets not found`);
51
+ }
52
+ if (!preset) {
53
+ return Object.assign({
54
+ workflow
55
+ }, options);
56
+ }
57
+ if (!presets[preset]) {
58
+ throw new Error(`Preset "${preset}" not found in workflow "${workflow}"`);
59
+ }
60
+ // let rest of options override
61
+ return Object.assign({
62
+ workflow
63
+ }, presets[preset], options);
64
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _default = exports.default = [{
8
+ slug: 'misocmd',
9
+ name: '3rd-party script',
10
+ description: 'Load SDK from a CDN script tag.'
11
+ }, {
12
+ slug: 'module',
13
+ name: 'Module',
14
+ description: 'Import SDK as a module to be bundled with your app.'
15
+ }];
@@ -9,6 +9,7 @@ var _utils = require("./utils.js");
9
9
  var _workflowsSlug = require("./workflows.slug.js");
10
10
  var _features = _interopRequireDefault(require("./features.js"));
11
11
  var presets = _interopRequireWildcard(require("./presets.js"));
12
+ var _sdks = _interopRequireDefault(require("./sdks.js"));
12
13
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
13
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
15
  function getFeatures(features, slug) {
@@ -26,7 +27,8 @@ var _default = exports.default = _workflowsSlug.WORKFLOW_SLUGS.reduce((obj, slug
26
27
  slug,
27
28
  name: (0, _utils.toName)(slug),
28
29
  features: getFeatures(_features.default, slug),
29
- presets: getPresets(presets, slug)
30
+ presets: getPresets(presets, slug),
31
+ sdks: _sdks.default
30
32
  });
31
33
  return obj;
32
34
  }, {});
@@ -4,16 +4,25 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.autoQuery = autoQuery;
7
- exports.facets = facets;
7
+ exports.autocomplete = autocomplete;
8
8
  var _helpers = require("./helpers.js");
9
- function facets(options) {
10
- return options ? `workflow.useFacets(${(0, _helpers.format)(options, {
9
+ /**
10
+ * @param {boolean | object} options
11
+ * - false => ''
12
+ * - true => `workflow.autoQuery();`
13
+ * - object => `workflow.autoQuery({ ... });`
14
+ */
15
+ function autoQuery(options) {
16
+ return options ? `// start query if URL parameter is present\nworkflow.autoQuery(${(0, _helpers.format)(options === true ? undefined : options, {
11
17
  multiline: true
12
18
  })});` : '';
13
19
  }
14
- function autoQuery(options) {
15
- // TODO: consider when options === false
16
- return options ? `workflow.autoQuery(${typeof options === 'object' ? (0, _helpers.format)(options, {
17
- multiline: true
18
- }) : ''});` : '';
20
+
21
+ /**
22
+ * @param {boolean} options
23
+ * - false => ''
24
+ * - true => `workflow.autocomplete.enable();`
25
+ */
26
+ function autocomplete(options) {
27
+ return options ? `workflow.autocomplete.enable();` : '';
19
28
  }
@@ -7,12 +7,9 @@ exports.blocks = blocks;
7
7
  exports.format = format;
8
8
  exports.indent = indent;
9
9
  exports.paragraphs = paragraphs;
10
- exports.resolvePreset = resolvePreset;
11
- const _excluded = ["preset"];
12
- function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
13
10
  function indent(str, level = 1) {
14
- // TODO: trim and deal with blank lines
15
- return str.replace(/\n/g, '\n' + ' '.repeat(level));
11
+ const spaces = ' '.repeat(level);
12
+ return str.split('\n').map(removeTrailingSpace).map(line => line ? spaces + line : '').join('\n');
16
13
  }
17
14
 
18
15
  /**
@@ -23,8 +20,12 @@ function indent(str, level = 1) {
23
20
  * @returns {string}
24
21
  */
25
22
  function format(value, {
26
- multiline = false
23
+ multiline = false,
24
+ omitUndefined = true
27
25
  } = {}) {
26
+ if (omitUndefined && value === undefined) {
27
+ return '';
28
+ }
28
29
  // use single quote
29
30
  // no quote for simple key in object
30
31
  return JSON.stringify(value, null, multiline ? 2 : 0).replace(/"/g, "'").replace(/\s*:\s*/g, ': ');
@@ -36,7 +37,7 @@ function format(value, {
36
37
  * @returns {string}
37
38
  */
38
39
  function blocks(...blocks) {
39
- return blocks.map(block => block.trim()).filter(block => block).join('\n');
40
+ return blocks.map(removeTrailingSpace).map(removeStartingNewLine).filter(block => block).join('\n');
40
41
  }
41
42
 
42
43
  /**
@@ -45,28 +46,12 @@ function blocks(...blocks) {
45
46
  * @returns {string}
46
47
  */
47
48
  function paragraphs(...paragraphs) {
48
- return paragraphs.map(paragraph => paragraph.trim()).filter(paragraph => paragraph).join('\n\n');
49
+ return paragraphs.map(removeTrailingSpace).map(removeStartingNewLine).filter(paragraph => paragraph).join('\n\n');
49
50
  }
50
-
51
- /**
52
- * Resolve preset options
53
- * @param {Object} presets - Available presets
54
- * @param {Object} options - Options to resolve
55
- * @param {string} options.preset - Preset to use
56
- * @param {Object} options - Other options
57
- * @returns {Object} Resolved options
58
- */
59
- function resolvePreset(presets, _ref = {}) {
60
- let {
61
- preset
62
- } = _ref,
63
- options = _objectWithoutPropertiesLoose(_ref, _excluded);
64
- if (!preset) {
65
- return options;
66
- }
67
- if (!presets[preset]) {
68
- throw new Error(`Preset "${preset}" is not found`);
69
- }
70
- // let rest of options override
71
- return Object.assign({}, presets[preset], options);
51
+ function removeTrailingSpace(str) {
52
+ return str.replace(/\s+$/g, '');
53
+ }
54
+ function removeStartingNewLine(str) {
55
+ // remove only leading newlines, preserve other leading whitespace
56
+ return str.replace(/^[\r\n]+/g, '');
72
57
  }
@@ -8,15 +8,15 @@ var _exportNames = {
8
8
  helpers: true
9
9
  };
10
10
  exports.helpers = exports.features = void 0;
11
- var _entrypoints = require("./entrypoints.js");
12
- Object.keys(_entrypoints).forEach(function (key) {
11
+ var _sdk = require("./sdk.js");
12
+ Object.keys(_sdk).forEach(function (key) {
13
13
  if (key === "default" || key === "__esModule") return;
14
14
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
15
- if (key in exports && exports[key] === _entrypoints[key]) return;
15
+ if (key in exports && exports[key] === _sdk[key]) return;
16
16
  Object.defineProperty(exports, key, {
17
17
  enumerable: true,
18
18
  get: function () {
19
- return _entrypoints[key];
19
+ return _sdk[key];
20
20
  }
21
21
  });
22
22
  });
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.misocmd = misocmd;
7
+ exports.module = _module;
8
+ exports.sdk = sdk;
9
+ var _helpers = require("./helpers.js");
10
+ function sdk({
11
+ sdk = 'misocmd'
12
+ } = {}, body) {
13
+ switch (sdk) {
14
+ case 'module':
15
+ return _module(body);
16
+ case 'misocmd':
17
+ return misocmd(body);
18
+ default:
19
+ throw new Error(`Invalid SDK setup option: ${sdk}`);
20
+ }
21
+ }
22
+ function misocmd(body) {
23
+ return `
24
+ const misocmd = window.misocmd || (window.misocmd = []);
25
+ misocmd.push(async () => {
26
+ ${(0, _helpers.indent)(body, 2)}
27
+ });
28
+ `.trim();
29
+ }
30
+ function _module(body) {
31
+ return `
32
+ import MisoClient from '@miso.ai/client-sdk';
33
+
34
+ ${body}
35
+ `.trim();
36
+ }
@@ -4,9 +4,8 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.hybridSearch = hybridSearch;
7
- var _presets = require("../spec/presets.js");
8
- var _helpers = require("../template/helpers.js");
9
- var _index = require("../template/index.js");
7
+ var _index = require("../spec/index.js");
8
+ var _index2 = require("../template/index.js");
10
9
  var _features = require("../template/features.js");
11
10
  const _excluded = ["facets"];
12
11
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
@@ -24,10 +23,10 @@ function normalizeOptions(_ref = {}) {
24
23
  });
25
24
  }
26
25
  function hybridSearch(options) {
27
- options = normalizeOptions((0, _helpers.resolvePreset)(_presets.hybridSearch, options));
26
+ options = normalizeOptions((0, _index.resolvePreset)(options));
28
27
  const items = [{
29
28
  type: 'html',
30
- name: 'HTML',
29
+ name: 'HTML (Main)',
31
30
  content: html(options)
32
31
  }, {
33
32
  type: 'js',
@@ -37,33 +36,58 @@ function hybridSearch(options) {
37
36
  return items;
38
37
  }
39
38
  function js(options) {
40
- // TODO: support loading from Node module
41
39
  // TODO: useLink
42
- return (0, _index.misocmd)(`
43
- // client
44
- ${(0, _index.createClient)(options)}
45
-
46
- // workflow
47
- const workflow = client.ui.hybridSearch;
48
-
49
- // setup: TODO
50
-
51
- ${jsElements(options)}
52
-
53
- ${(0, _features.autoQuery)(options.autoQuery)}
54
- `);
40
+ return (0, _index2.sdk)(options, _index2.helpers.paragraphs(client(options), workflow(options), setup(options), views(options), (0, _features.autoQuery)(options.autoQuery)));
41
+ }
42
+ function client(options) {
43
+ return `
44
+ // access Miso client
45
+ ${(0, _index2.createClient)(options)}`;
46
+ }
47
+ function workflow(options) {
48
+ return `
49
+ // access workflow
50
+ const workflow = client.ui.hybridSearch;`;
51
+ }
52
+ function setup(options) {
53
+ const items = [];
54
+ const useApiCall = useApi(options);
55
+ if (useApiCall) {
56
+ items.push(useApiCall);
57
+ }
58
+ if (options.autocomplete) {
59
+ items.push((0, _features.autocomplete)(options.autocomplete));
60
+ }
61
+ return items.length ? _index2.helpers.blocks(`// setup`, ...items) : '';
55
62
  }
56
- function jsElements(options) {
63
+ function useApi(options) {
64
+ const params = {};
65
+ if (options.facets) {
66
+ params.facets = options.facets;
67
+ }
68
+ return Object.keys(params).length ? `workflow.useApi(${_index2.helpers.format(params, {
69
+ multiline: true
70
+ })});` : '';
71
+ }
72
+ function views(options) {
57
73
  if (options.elements === false) {
58
74
  return '';
59
75
  }
76
+ const templatesHelpersUsed = [`templates`];
77
+ let templatesRootParams = undefined;
78
+ if (options.answerBox) {
79
+ templatesHelpersUsed.push(`wireAnswerBox`);
80
+ templatesRootParams = Object.assign({}, templatesRootParams, {
81
+ answerBox: true
82
+ });
83
+ }
60
84
  return `
61
85
  // render Miso elements
62
86
  await client.ui.ready;
63
- const { templates, wireAnswerBox } = MisoClient.ui.defaults.hybridSearch;
87
+ const { ${templatesHelpersUsed.join(', ')} } = MisoClient.ui.defaults.hybridSearch;
64
88
  const rootElement = document.querySelector('#miso-hybrid-search-combo');
65
- rootElement.innerHTML = templates.root();
66
- wireAnswerBox(client, rootElement);
89
+ rootElement.innerHTML = templates.root(${_index2.helpers.format(templatesRootParams)});
90
+ ${options.answerBox ? `wireAnswerBox(client, rootElement);` : ''}
67
91
  `.trim();
68
92
  }
69
93
  function html(options) {
@@ -4,9 +4,8 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.search = search;
7
- var _presets = require("../spec/presets.js");
8
- var _helpers = require("../template/helpers.js");
9
- var _index = require("../template/index.js");
7
+ var _index = require("../spec/index.js");
8
+ var _index2 = require("../template/index.js");
10
9
  var _features = require("../template/features.js");
11
10
  const _excluded = ["facets"];
12
11
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
@@ -23,7 +22,7 @@ function normalizeOptions(_ref = {}) {
23
22
  });
24
23
  }
25
24
  function search(options) {
26
- options = normalizeOptions((0, _helpers.resolvePreset)(_presets.search, options));
25
+ options = normalizeOptions((0, _index.resolvePreset)(options));
27
26
  // TODO: extra styles for concatenate format
28
27
  const items = [];
29
28
  if (options.elements !== false) {
@@ -45,29 +44,40 @@ function search(options) {
45
44
  return items;
46
45
  }
47
46
  function js(options) {
48
- // TODO: support loading from Node module
49
- return (0, _index.misocmd)(`
50
- // client
51
- ${(0, _index.createClient)(options)}
52
-
53
- // workflow
54
- const workflow = client.ui.search;
55
-
56
- // setup: TODO
57
- ${(0, _features.facets)(options.facets)}
58
-
59
- ${(0, _features.autoQuery)(options.autoQuery)}
60
- `);
47
+ return (0, _index2.sdk)(options, _index2.helpers.paragraphs(client(options), workflow(options), setup(options), (0, _features.autoQuery)(options.autoQuery)));
61
48
  }
62
- function html(options) {
63
- if (options.elements === false) {
64
- return '';
65
- }
49
+ function client(options) {
66
50
  return `
67
- ${htmlSearchBox(options)}
68
- <hr>
69
- ${htmlResults(options)}
70
- `.trim();
51
+ // access Miso client
52
+ ${(0, _index2.createClient)(options)}`;
53
+ }
54
+ function workflow(options) {
55
+ return `
56
+ // access workflow
57
+ const workflow = client.ui.search;`;
58
+ }
59
+ function setup(options) {
60
+ const items = [];
61
+ const useApiCall = useApi(options);
62
+ if (useApiCall) {
63
+ items.push(useApiCall);
64
+ }
65
+ if (options.autocomplete) {
66
+ items.push(autocomplete(options.autocomplete));
67
+ }
68
+ return items.length ? _index2.helpers.blocks(`// setup`, ...items) : '';
69
+ }
70
+ function useApi(options) {
71
+ const params = {};
72
+ if (options.facets) {
73
+ params.facets = options.facets;
74
+ }
75
+ return Object.keys(params).length ? `workflow.useApi(${_index2.helpers.format(params, {
76
+ multiline: true
77
+ })});` : '';
78
+ }
79
+ function autocomplete(options) {
80
+ return options ? `workflow.autocomplete.enable();` : '';
71
81
  }
72
82
  function htmlSearchBox(options) {
73
83
  return `
package/dist/cjs/ui/ui.js CHANGED
@@ -6,22 +6,22 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.ui = ui;
7
7
  var _hybridSearch = require("./hybrid-search.js");
8
8
  var _search = require("./search.js");
9
- const _excluded = ["workflow"];
9
+ const _excluded = ["apiKey"];
10
10
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
11
- const workflows = {
11
+ const WORKFLOWS = {
12
12
  ['hybrid-search']: _hybridSearch.hybridSearch,
13
13
  search: _search.search
14
14
  };
15
15
  function normalizeOptions(_ref = {}) {
16
16
  let {
17
- workflow
17
+ apiKey = 'your_api_key'
18
18
  } = _ref,
19
19
  options = _objectWithoutPropertiesLoose(_ref, _excluded);
20
- if (!workflow) {
20
+ if (!options.workflow) {
21
21
  throw new Error('Workflow is required');
22
22
  }
23
23
  return Object.assign({
24
- workflow
24
+ apiKey
25
25
  }, options);
26
26
  }
27
27
  function ui(options) {
@@ -29,8 +29,8 @@ function ui(options) {
29
29
  const {
30
30
  workflow
31
31
  } = options;
32
- if (!workflows[workflow]) {
32
+ if (!WORKFLOWS[workflow]) {
33
33
  throw new Error(`Workflow "${workflow}" is not found`);
34
34
  }
35
- return workflows[workflow](options);
35
+ return WORKFLOWS[workflow](options);
36
36
  }
package/package.json CHANGED
@@ -26,7 +26,7 @@
26
26
  "url": "https://github.com/MisoAI/miso-client-js-sdk/issues"
27
27
  },
28
28
  "dependencies": {
29
- "@miso.ai/commons": "1.12.0"
29
+ "@miso.ai/commons": "1.12.1-beta.0"
30
30
  },
31
- "version": "1.12.0"
31
+ "version": "1.12.1-beta.0"
32
32
  }
@@ -1,4 +1,4 @@
1
- export function encodeParameters(params) {
1
+ export function encodeConfig(params) {
2
2
  if (params === undefined || params === null) {
3
3
  return undefined;
4
4
  }
@@ -9,7 +9,7 @@ export function encodeParameters(params) {
9
9
  return base64Encode(JSON.stringify(params));
10
10
  }
11
11
 
12
- export function decodeParameters(params) {
12
+ export function decodeConfig(params) {
13
13
  if (params === undefined || params === null) {
14
14
  return undefined;
15
15
  }
package/src/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export * as spec from './spec/index.js';
2
- export * from './params.js';
2
+ export * from './encoding.js';
3
3
  export * from './codegen.js';
4
4
  export * as ui from './ui/index.js';
@@ -1,34 +1,59 @@
1
1
  import { toName } from './utils.js';
2
2
  import { resolveWorkflows } from './workflows.slug.js';
3
3
 
4
+ const DEFAULT_BOOLEAN_OPTIONS = [
5
+ { name: 'Off', value: undefined },
6
+ { name: 'On', value: true },
7
+ ];
8
+
4
9
  export default [
10
+ /*
5
11
  {
6
12
  slug: 'use-api',
7
13
  workflows: '*',
8
14
  },
15
+ */
16
+ /*
9
17
  {
10
18
  slug: 'use-link',
11
19
  workflows: 'ahes',
20
+ options: DEFAULT_BOOLEAN_OPTIONS,
12
21
  },
22
+ */
13
23
  {
14
24
  slug: 'autocomplete',
15
25
  workflows: 'hs',
26
+ options: DEFAULT_BOOLEAN_OPTIONS,
16
27
  },
28
+ /*
17
29
  {
18
30
  slug: 'pagination',
19
31
  workflows: 'hs',
32
+ options: DEFAULT_BOOLEAN_OPTIONS,
20
33
  },
34
+ */
21
35
  {
22
36
  slug: 'facets',
23
37
  workflows: 'hs',
38
+ options: [
39
+ { name: 'Off', value: undefined },
40
+ { name: 'Categories', value: ['categories'] },
41
+ ],
42
+ },
43
+ {
44
+ slug: 'answer-box',
45
+ workflows: 'h',
46
+ options: DEFAULT_BOOLEAN_OPTIONS,
24
47
  },
25
48
  {
26
49
  slug: 'follow-up',
27
50
  workflows: 'a',
51
+ options: DEFAULT_BOOLEAN_OPTIONS,
28
52
  },
29
53
  {
30
54
  slug: 'auto-query',
31
55
  workflows: 'ahes',
56
+ options: DEFAULT_BOOLEAN_OPTIONS,
32
57
  },
33
58
  ].reduce((map, { slug, workflows, ...rest }) => {
34
59
  map[slug] = Object.freeze({
package/src/spec/index.js CHANGED
@@ -1,2 +1,4 @@
1
1
  export { default as workflows } from './workflows.js';
2
2
  export { default as features } from './features.js';
3
+ export { default as sdks } from './sdks.js';
4
+ export { resolvePreset } from './presets.js';
@@ -1,10 +1,11 @@
1
+ import { lowerCamelToKebab } from '@miso.ai/commons';
2
+
1
3
  export const hybridSearch = Object.freeze({
2
4
  standard: Object.freeze({
3
5
  workflow: 'hybrid-search',
4
6
  autoQuery: true,
5
7
  autocomplete: true,
6
8
  facets: ['categories'],
7
- answerBox: true,
8
9
  }),
9
10
  minimal: Object.freeze({
10
11
  workflow: 'hybrid-search',
@@ -22,3 +23,34 @@ export const search = Object.freeze({
22
23
  workflow: 'search',
23
24
  }),
24
25
  });
26
+
27
+ const PRESETS = {
28
+ ['hybrid-search']: hybridSearch,
29
+ search,
30
+ };
31
+
32
+ export function resolvePreset({ workflow, preset, ...options } = {}) {
33
+ if (!workflow) {
34
+ throw new Error('Workflow is required');
35
+ }
36
+ workflow = lowerCamelToKebab(workflow); // just in case
37
+ const presets = PRESETS[workflow];
38
+ if (!presets) {
39
+ throw new Error(`Workflow "${workflow}" presets not found`);
40
+ }
41
+ if (!preset) {
42
+ return {
43
+ workflow,
44
+ ...options,
45
+ };
46
+ }
47
+ if (!presets[preset]) {
48
+ throw new Error(`Preset "${preset}" not found in workflow "${workflow}"`);
49
+ }
50
+ // let rest of options override
51
+ return {
52
+ workflow,
53
+ ...presets[preset],
54
+ ...options,
55
+ };
56
+ }
@@ -0,0 +1,12 @@
1
+ export default [
2
+ {
3
+ slug: 'misocmd',
4
+ name: '3rd-party script',
5
+ description: 'Load SDK from a CDN script tag.',
6
+ },
7
+ {
8
+ slug: 'module',
9
+ name: 'Module',
10
+ description: 'Import SDK as a module to be bundled with your app.',
11
+ },
12
+ ];
@@ -3,6 +3,7 @@ import { toName } from './utils.js';
3
3
  import { WORKFLOW_SLUGS } from './workflows.slug.js';
4
4
  import features from './features.js';
5
5
  import * as presets from './presets.js';
6
+ import { default as sdks } from './sdks.js';
6
7
 
7
8
  function getFeatures(features, slug) {
8
9
  return Object.values(features).filter(feature => feature.workflows.includes(slug));
@@ -22,6 +23,7 @@ export default WORKFLOW_SLUGS.reduce((obj, slug) => {
22
23
  name: toName(slug),
23
24
  features: getFeatures(features, slug),
24
25
  presets: getPresets(presets, slug),
26
+ sdks,
25
27
  });
26
28
  return obj;
27
29
  }, {});
@@ -1,10 +1,20 @@
1
1
  import { format } from './helpers.js';
2
2
 
3
- export function facets(options) {
4
- return options ? `workflow.useFacets(${format(options, { multiline: true })});` : '';
3
+ /**
4
+ * @param {boolean | object} options
5
+ * - false => ''
6
+ * - true => `workflow.autoQuery();`
7
+ * - object => `workflow.autoQuery({ ... });`
8
+ */
9
+ export function autoQuery(options) {
10
+ return options ? `// start query if URL parameter is present\nworkflow.autoQuery(${format(options === true ? undefined : options, { multiline: true })});` : '';
5
11
  }
6
12
 
7
- export function autoQuery(options) {
8
- // TODO: consider when options === false
9
- return options ? `workflow.autoQuery(${typeof options === 'object' ? format(options, { multiline: true }) : ''});` : '';
13
+ /**
14
+ * @param {boolean} options
15
+ * - false => ''
16
+ * - true => `workflow.autocomplete.enable();`
17
+ */
18
+ export function autocomplete(options) {
19
+ return options ? `workflow.autocomplete.enable();` : '';
10
20
  }
@@ -1,6 +1,6 @@
1
1
  export function indent(str, level = 1) {
2
- // TODO: trim and deal with blank lines
3
- return str.replace(/\n/g, '\n' + ' '.repeat(level));
2
+ const spaces = ' '.repeat(level);
3
+ return str.split('\n').map(removeTrailingSpace).map(line => line ? spaces + line : '').join('\n');
4
4
  }
5
5
 
6
6
  /**
@@ -10,7 +10,10 @@ export function indent(str, level = 1) {
10
10
  * @param {boolean} options.multiline - Whether to use multiline
11
11
  * @returns {string}
12
12
  */
13
- export function format(value, { multiline = false } = {}) {
13
+ export function format(value, { multiline = false, omitUndefined = true } = {}) {
14
+ if (omitUndefined && value === undefined) {
15
+ return '';
16
+ }
14
17
  // use single quote
15
18
  // no quote for simple key in object
16
19
  return JSON.stringify(value, null, multiline ? 2 : 0).replace(/"/g, "'").replace(/\s*:\s*/g, ': ');
@@ -22,7 +25,11 @@ export function format(value, { multiline = false } = {}) {
22
25
  * @returns {string}
23
26
  */
24
27
  export function blocks(...blocks) {
25
- return blocks.map(block => block.trim()).filter(block => block).join('\n');
28
+ return blocks
29
+ .map(removeTrailingSpace)
30
+ .map(removeStartingNewLine)
31
+ .filter(block => block)
32
+ .join('\n');
26
33
  }
27
34
 
28
35
  /**
@@ -31,27 +38,18 @@ export function blocks(...blocks) {
31
38
  * @returns {string}
32
39
  */
33
40
  export function paragraphs(...paragraphs) {
34
- return paragraphs.map(paragraph => paragraph.trim()).filter(paragraph => paragraph).join('\n\n');
41
+ return paragraphs
42
+ .map(removeTrailingSpace)
43
+ .map(removeStartingNewLine)
44
+ .filter(paragraph => paragraph)
45
+ .join('\n\n');
35
46
  }
36
47
 
37
- /**
38
- * Resolve preset options
39
- * @param {Object} presets - Available presets
40
- * @param {Object} options - Options to resolve
41
- * @param {string} options.preset - Preset to use
42
- * @param {Object} options - Other options
43
- * @returns {Object} Resolved options
44
- */
45
- export function resolvePreset(presets, { preset, ...options } = {}) {
46
- if (!preset) {
47
- return options;
48
- }
49
- if (!presets[preset]) {
50
- throw new Error(`Preset "${preset}" is not found`);
51
- }
52
- // let rest of options override
53
- return {
54
- ...presets[preset],
55
- ...options,
56
- };
48
+ function removeTrailingSpace(str) {
49
+ return str.replace(/\s+$/g, '');
50
+ }
51
+
52
+ function removeStartingNewLine(str) {
53
+ // remove only leading newlines, preserve other leading whitespace
54
+ return str.replace(/^[\r\n]+/g, '');
57
55
  }
@@ -1,4 +1,4 @@
1
- export * from './entrypoints.js';
1
+ export * from './sdk.js';
2
2
  export * from './client.js';
3
3
  export * as features from './features.js';
4
4
  export * as helpers from './helpers.js';
@@ -0,0 +1,29 @@
1
+ import { indent } from './helpers.js';
2
+
3
+ export function sdk({ sdk = 'misocmd' } = {}, body) {
4
+ switch (sdk) {
5
+ case 'module':
6
+ return module(body);
7
+ case 'misocmd':
8
+ return misocmd(body);
9
+ default:
10
+ throw new Error(`Invalid SDK setup option: ${sdk}`);
11
+ }
12
+ }
13
+
14
+ export function misocmd(body) {
15
+ return `
16
+ const misocmd = window.misocmd || (window.misocmd = []);
17
+ misocmd.push(async () => {
18
+ ${indent(body, 2)}
19
+ });
20
+ `.trim();
21
+ }
22
+
23
+ export function module(body) {
24
+ return `
25
+ import MisoClient from '@miso.ai/client-sdk';
26
+
27
+ ${body}
28
+ `.trim();
29
+ }
@@ -1,7 +1,6 @@
1
- import { hybridSearch as presets } from '../spec/presets.js';
2
- import { resolvePreset } from '../template/helpers.js';
3
- import { misocmd, createClient } from '../template/index.js';
4
- import { autoQuery } from '../template/features.js';
1
+ import { resolvePreset } from '../spec/index.js';
2
+ import { sdk, createClient, helpers as h } from '../template/index.js';
3
+ import { autoQuery, autocomplete } from '../template/features.js';
5
4
 
6
5
  // TODO: refactor these
7
6
  function normalizeOptions({ facets, ...options } = {}) {
@@ -15,11 +14,11 @@ function normalizeOptions({ facets, ...options } = {}) {
15
14
  }
16
15
 
17
16
  export function hybridSearch(options) {
18
- options = normalizeOptions(resolvePreset(presets, options));
17
+ options = normalizeOptions(resolvePreset(options));
19
18
  const items = [
20
19
  {
21
20
  type: 'html',
22
- name: 'HTML',
21
+ name: 'HTML (Main)',
23
22
  content: html(options),
24
23
  },
25
24
  {
@@ -32,34 +31,65 @@ export function hybridSearch(options) {
32
31
  }
33
32
 
34
33
  function js(options) {
35
- // TODO: support loading from Node module
36
34
  // TODO: useLink
37
- return misocmd(`
38
- // client
39
- ${createClient(options)}
35
+ return sdk(options, h.paragraphs(
36
+ client(options),
37
+ workflow(options),
38
+ setup(options),
39
+ views(options),
40
+ autoQuery(options.autoQuery),
41
+ ));
42
+ }
40
43
 
41
- // workflow
42
- const workflow = client.ui.hybridSearch;
44
+ function client(options) {
45
+ return `
46
+ // access Miso client
47
+ ${createClient(options)}`;
48
+ }
43
49
 
44
- // setup: TODO
50
+ function workflow(options) {
51
+ return `
52
+ // access workflow
53
+ const workflow = client.ui.hybridSearch;`;
54
+ }
45
55
 
46
- ${jsElements(options)}
56
+ function setup(options) {
57
+ const items = [];
58
+ const useApiCall = useApi(options);
59
+ if (useApiCall) {
60
+ items.push(useApiCall);
61
+ }
62
+ if (options.autocomplete) {
63
+ items.push(autocomplete(options.autocomplete));
64
+ }
65
+ return items.length ? h.blocks(`// setup`, ...items) : '';
66
+ }
47
67
 
48
- ${autoQuery(options.autoQuery)}
49
- `);
68
+ function useApi(options) {
69
+ const params = {};
70
+ if (options.facets) {
71
+ params.facets = options.facets;
72
+ }
73
+ return Object.keys(params).length ? `workflow.useApi(${h.format(params, { multiline: true })});` : '';
50
74
  }
51
75
 
52
- function jsElements(options) {
76
+ function views(options) {
53
77
  if (options.elements === false) {
54
78
  return '';
55
79
  }
80
+ const templatesHelpersUsed = [`templates`];
81
+ let templatesRootParams = undefined;
82
+ if (options.answerBox) {
83
+ templatesHelpersUsed.push(`wireAnswerBox`);
84
+ templatesRootParams = { ...templatesRootParams, answerBox: true };
85
+ }
56
86
  return `
57
87
  // render Miso elements
58
88
  await client.ui.ready;
59
- const { templates, wireAnswerBox } = MisoClient.ui.defaults.hybridSearch;
89
+ const { ${templatesHelpersUsed.join(', ')} } = MisoClient.ui.defaults.hybridSearch;
60
90
  const rootElement = document.querySelector('#miso-hybrid-search-combo');
61
- rootElement.innerHTML = templates.root();
62
- wireAnswerBox(client, rootElement);
91
+ rootElement.innerHTML = templates.root(${h.format(templatesRootParams)});
92
+ ${options.answerBox ? `wireAnswerBox(client, rootElement);` : ''}
63
93
  `.trim();
64
94
  }
65
95
 
package/src/ui/search.js CHANGED
@@ -1,7 +1,6 @@
1
- import { search as presets } from '../spec/presets.js';
2
- import { resolvePreset } from '../template/helpers.js';
3
- import { misocmd, createClient } from '../template/index.js';
4
- import { facets, autoQuery } from '../template/features.js';
1
+ import { resolvePreset } from '../spec/index.js';
2
+ import { sdk, createClient, helpers as h } from '../template/index.js';
3
+ import { autoQuery } from '../template/features.js';
5
4
 
6
5
  function normalizeOptions({ facets, ...options } = {}) {
7
6
  if (facets === true) {
@@ -14,7 +13,7 @@ function normalizeOptions({ facets, ...options } = {}) {
14
13
  }
15
14
 
16
15
  export function search(options) {
17
- options = normalizeOptions(resolvePreset(presets, options));
16
+ options = normalizeOptions(resolvePreset(options));
18
17
  // TODO: extra styles for concatenate format
19
18
  const items = [];
20
19
  if (options.elements !== false) {
@@ -42,30 +41,48 @@ export function search(options) {
42
41
  }
43
42
 
44
43
  function js(options) {
45
- // TODO: support loading from Node module
46
- return misocmd(`
47
- // client
48
- ${createClient(options)}
44
+ return sdk(options, h.paragraphs(
45
+ client(options),
46
+ workflow(options),
47
+ setup(options),
48
+ autoQuery(options.autoQuery),
49
+ ));
50
+ }
49
51
 
50
- // workflow
51
- const workflow = client.ui.search;
52
+ function client(options) {
53
+ return `
54
+ // access Miso client
55
+ ${createClient(options)}`;
56
+ }
52
57
 
53
- // setup: TODO
54
- ${facets(options.facets)}
58
+ function workflow(options) {
59
+ return `
60
+ // access workflow
61
+ const workflow = client.ui.search;`;
62
+ }
55
63
 
56
- ${autoQuery(options.autoQuery)}
57
- `);
64
+ function setup(options) {
65
+ const items = [];
66
+ const useApiCall = useApi(options);
67
+ if (useApiCall) {
68
+ items.push(useApiCall);
69
+ }
70
+ if (options.autocomplete) {
71
+ items.push(autocomplete(options.autocomplete));
72
+ }
73
+ return items.length ? h.blocks(`// setup`, ...items) : '';
58
74
  }
59
75
 
60
- function html(options) {
61
- if (options.elements === false) {
62
- return '';
76
+ function useApi(options) {
77
+ const params = {};
78
+ if (options.facets) {
79
+ params.facets = options.facets;
63
80
  }
64
- return `
65
- ${htmlSearchBox(options)}
66
- <hr>
67
- ${htmlResults(options)}
68
- `.trim();
81
+ return Object.keys(params).length ? `workflow.useApi(${h.format(params, { multiline: true })});` : '';
82
+ }
83
+
84
+ function autocomplete(options) {
85
+ return options ? `workflow.autocomplete.enable();` : '';
69
86
  }
70
87
 
71
88
  function htmlSearchBox(options) {
package/src/ui/ui.js CHANGED
@@ -1,17 +1,17 @@
1
1
  import { hybridSearch } from './hybrid-search.js';
2
2
  import { search } from './search.js';
3
3
 
4
- const workflows = {
4
+ const WORKFLOWS = {
5
5
  ['hybrid-search']: hybridSearch,
6
6
  search,
7
7
  };
8
8
 
9
- function normalizeOptions({ workflow, ...options } = {}) {
10
- if (!workflow) {
9
+ function normalizeOptions({ apiKey = 'your_api_key', ...options } = {}) {
10
+ if (!options.workflow) {
11
11
  throw new Error('Workflow is required');
12
12
  }
13
13
  return {
14
- workflow,
14
+ apiKey,
15
15
  ...options,
16
16
  };
17
17
  }
@@ -19,8 +19,8 @@ function normalizeOptions({ workflow, ...options } = {}) {
19
19
  export function ui(options) {
20
20
  options = normalizeOptions(options);
21
21
  const { workflow } = options;
22
- if (!workflows[workflow]) {
22
+ if (!WORKFLOWS[workflow]) {
23
23
  throw new Error(`Workflow "${workflow}" is not found`);
24
24
  }
25
- return workflows[workflow](options);
25
+ return WORKFLOWS[workflow](options);
26
26
  }
@@ -1,15 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.misocmd = misocmd;
7
- var _helpers = require("./helpers.js");
8
- function misocmd(body) {
9
- return `
10
- const misocmd = window.misocmd || (window.misocmd = []);
11
- misocmd.push(async () => {
12
- ${(0, _helpers.indent)(body, 2)}
13
- });
14
- `.trim();
15
- }
@@ -1,10 +0,0 @@
1
- import { indent } from './helpers.js';
2
-
3
- export function misocmd(body) {
4
- return `
5
- const misocmd = window.misocmd || (window.misocmd = []);
6
- misocmd.push(async () => {
7
- ${indent(body, 2)}
8
- });
9
- `.trim();
10
- }