Best Python code snippet using Contexts
util.js
Source:util.js
1// Copyright 2014 The ChromeOS IME Authors. All Rights Reserved.2// limitations under the License.3// See the License for the specific language governing permissions and4// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.5// distributed under the License is distributed on an "AS-IS" BASIS,6// Unless required by applicable law or agreed to in writing, software7//8// http://www.apache.org/licenses/LICENSE-2.09//10// You may obtain a copy of the License at11// you may not use this file except in compliance with the License.12// Licensed under the Apache License, Version 2.0 (the "License");13//14goog.provide('i18n.input.chrome.inputview.content.util');15goog.require('goog.array');16goog.require('i18n.input.chrome.ElementType');17goog.require('i18n.input.chrome.inputview.Css');18goog.require('i18n.input.chrome.inputview.Direction');19goog.require('i18n.input.chrome.inputview.SpecNodeName');20goog.require('i18n.input.chrome.inputview.StateType');21goog.scope(function() {22var ElementType = i18n.input.chrome.ElementType;23var SpecNodeName = i18n.input.chrome.inputview.SpecNodeName;24/**25 * The prefix of the key id.26 *27 * @type {string}28 * @private29 */30i18n.input.chrome.inputview.content.util.keyIdPrefix_ = 'sk-';31/**32 * Creates the hide keyboard key.33 *34 * @return {!Object} The hide keyboard key.35 */36i18n.input.chrome.inputview.content.util.createHideKeyboardKey = function() {37 var spec = {};38 spec[SpecNodeName.ICON_CSS_CLASS] =39 i18n.input.chrome.inputview.Css.HIDE_KEYBOARD_ICON;40 spec[SpecNodeName.TYPE] = ElementType.HIDE_KEYBOARD_KEY;41 spec[SpecNodeName.ID] = 'HideKeyboard';42 return i18n.input.chrome.inputview.content.util.createKey(spec);43};44/**45 * Creates a shift key.46 *47 * @param {boolean} isLeft True if this is the left shift key.48 * @param {boolean=} opt_supportSticky True if support sticky shift key.49 * @return {!Object} The shift key.50 */51i18n.input.chrome.inputview.content.util.createShiftKey = function(isLeft,52 opt_supportSticky) {53 var spec = {};54 spec[SpecNodeName.TO_STATE] = i18n.input.chrome.inputview.StateType.SHIFT;55 spec[SpecNodeName.ICON_CSS_CLASS] =56 i18n.input.chrome.inputview.Css.SHIFT_ICON;57 spec[SpecNodeName.TYPE] = ElementType.MODIFIER_KEY;58 spec[SpecNodeName.ID] = isLeft ? 'ShiftLeft' : 'ShiftRight';59 spec[SpecNodeName.SUPPORT_STICKY] = !!opt_supportSticky;60 return i18n.input.chrome.inputview.content.util.createKey(spec);61};62/**63 * Creates a globe key.64 *65 * @return {!Object} The globe key.66 */67i18n.input.chrome.inputview.content.util.createGlobeKey = function() {68 var spec = {};69 spec[SpecNodeName.ICON_CSS_CLASS] =70 i18n.input.chrome.inputview.Css.GLOBE_ICON;71 spec[SpecNodeName.TYPE] = ElementType.GLOBE_KEY;72 spec[SpecNodeName.ID] = 'Globe';73 return i18n.input.chrome.inputview.content.util.createKey(spec);74};75/**76 * Creates a menu key.77 *78 * @param {string=} opt_toKeyset The compact keyboard id.79 * @return {!Object} The menu key.80 */81i18n.input.chrome.inputview.content.util.createMenuKey = function(82 opt_toKeyset) {83 var spec = {};84 spec[SpecNodeName.ICON_CSS_CLASS] =85 i18n.input.chrome.inputview.Css.MENU_ICON;86 spec[SpecNodeName.TO_KEYSET] = opt_toKeyset;87 spec[SpecNodeName.TYPE] = ElementType.MENU_KEY;88 spec[SpecNodeName.ID] = 'Menu';89 return i18n.input.chrome.inputview.content.util.createKey(spec);90};91/**92 * Create the Emoji switch key.93 *94 * @param {string} id The emoji key id.95 * @param {number} toKeyset The keyset that the tabbar represents.96 * @param {i18n.input.chrome.inputview.Css}97 * iconCssClass The icon css for the tabbar.98 * @return {!Object} The emoji key.99 */100i18n.input.chrome.inputview.content.util.createTabBarKey =101 function(id, toKeyset, iconCssClass) {102 var spec = {};103 spec[SpecNodeName.ICON_CSS_CLASS] = iconCssClass;104 spec[SpecNodeName.TYPE] = ElementType.TAB_BAR_KEY;105 spec[SpecNodeName.ID] = id;106 spec[SpecNodeName.TO_KEYSET] = toKeyset;107 return i18n.input.chrome.inputview.content.util.createKey(spec);108};109/**110 * Create the indicator111 *112 * @param {string} id The indicator id.113 * @return {!Object} The indicator.114 */115i18n.input.chrome.inputview.content.util.createPageIndicator =116 function(id) {117 var spec = {};118 spec[SpecNodeName.TYPE] = ElementType.PAGE_INDICATOR;119 spec[SpecNodeName.ID] = id;120 return i18n.input.chrome.inputview.content.util.createKey(spec);121};122/**123 * Create the back key for emoji124 *125 * @return {!Object} The back key.126 */127i18n.input.chrome.inputview.content.util.createBackKey = function() {128 var spec = {};129 spec[SpecNodeName.ICON_CSS_CLASS] =130 i18n.input.chrome.inputview.Css.EMOJI_BACK;131 spec[SpecNodeName.TYPE] = ElementType.BACK_BUTTON;132 spec[SpecNodeName.ID] = 'backkey';133 return i18n.input.chrome.inputview.content.util.createKey(spec);134};135/**136 * Create the key which leads to keyboard from emoji/hwt.137 *138 * @return {!Object} The back key.139 */140i18n.input.chrome.inputview.content.util.createBackToKeyboardKey = function() {141 var spec = {};142 spec[SpecNodeName.ICON_CSS_CLASS] =143 i18n.input.chrome.inputview.Css.BACK_TO_KEYBOARD_ICON;144 spec[SpecNodeName.TYPE] = ElementType.BACK_TO_KEYBOARD;145 spec[SpecNodeName.ID] = 'backToKeyboard';146 return i18n.input.chrome.inputview.content.util.createKey(spec);147};148/**149 * Creates a ctrl key.150 *151 * @return {!Object} The ctrl key.152 */153i18n.input.chrome.inputview.content.util.createCtrlKey = function() {154 var spec = {};155 spec[SpecNodeName.TO_STATE] = i18n.input.chrome.inputview.StateType.CTRL;156 spec[SpecNodeName.NAME] = 'ctrl';157 spec[SpecNodeName.TYPE] = ElementType.MODIFIER_KEY;158 spec[SpecNodeName.ID] = 'ControlLeft';159 return i18n.input.chrome.inputview.content.util.createKey(spec);160};161/**162 * Creates a alt key.163 *164 * @return {!Object} The alt key.165 */166i18n.input.chrome.inputview.content.util.createAltKey = function() {167 var spec = {};168 spec[SpecNodeName.TO_STATE] = i18n.input.chrome.inputview.StateType.ALT;169 spec[SpecNodeName.NAME] = 'alt';170 spec[SpecNodeName.TYPE] = ElementType.MODIFIER_KEY;171 spec[SpecNodeName.ID] = 'AltLeft';172 return i18n.input.chrome.inputview.content.util.createKey(spec);173};174/**175 * Creates a altgr key.176 *177 * @return {!Object} The altgr key.178 */179i18n.input.chrome.inputview.content.util.createAltgrKey = function() {180 var spec = {};181 spec[SpecNodeName.TO_STATE] = i18n.input.chrome.inputview.StateType.ALTGR;182 spec[SpecNodeName.NAME] = 'alt gr';183 spec[SpecNodeName.TYPE] = ElementType.MODIFIER_KEY;184 spec[SpecNodeName.ID] = 'AltRight';185 return i18n.input.chrome.inputview.content.util.createKey(spec);186};187/**188 * Creates a key used to switch to english.189 *190 * @return {!Object} The enSwitcher key.191 */192i18n.input.chrome.inputview.content.util.createEnSwitcherKey =193 function() {194 var spec = {};195 spec[SpecNodeName.TYPE] = ElementType.EN_SWITCHER;196 spec[SpecNodeName.ID] = 'enSwitcher';197 return i18n.input.chrome.inputview.content.util.createKey(spec);198};199/**200 * Creates a capslock key.201 *202 * @return {!Object} The capslock key.203 */204i18n.input.chrome.inputview.content.util.createCapslockKey = function() {205 var spec = {};206 spec[SpecNodeName.TO_STATE] = i18n.input.chrome.inputview.StateType.CAPSLOCK;207 spec[SpecNodeName.NAME] = 'caps lock';208 spec[SpecNodeName.TYPE] = ElementType.MODIFIER_KEY;209 spec[SpecNodeName.ID] = 'OsLeft';210 return i18n.input.chrome.inputview.content.util.createKey(spec);211};212/**213 * Creates a enter key.214 *215 * @return {!Object} The enter key.216 */217i18n.input.chrome.inputview.content.util.createEnterKey = function() {218 var spec = {};219 spec[SpecNodeName.ICON_CSS_CLASS] =220 i18n.input.chrome.inputview.Css.ENTER_ICON;221 spec[SpecNodeName.TYPE] = ElementType.ENTER_KEY;222 spec[SpecNodeName.ID] = 'Enter';223 return i18n.input.chrome.inputview.content.util.createKey(spec);224};225/**226 * Creates a tab key.227 *228 * @return {!Object} The tab key.229 */230i18n.input.chrome.inputview.content.util.createTabKey = function() {231 var spec = {};232 spec[SpecNodeName.ICON_CSS_CLASS] = i18n.input.chrome.inputview.Css.TAB_ICON;233 spec[SpecNodeName.TYPE] = ElementType.TAB_KEY;234 spec[SpecNodeName.ID] = 'Tab';235 return i18n.input.chrome.inputview.content.util.createKey(spec);236};237/**238 * Creates a backspace key.239 *240 * @return {!Object} The backspace key.241 */242i18n.input.chrome.inputview.content.util.createBackspaceKey = function() {243 var spec = {};244 spec[SpecNodeName.ICON_CSS_CLASS] =245 i18n.input.chrome.inputview.Css.BACKSPACE_ICON;246 spec[SpecNodeName.TYPE] = ElementType.BACKSPACE_KEY;247 spec[SpecNodeName.ID] = 'Backspace';248 return i18n.input.chrome.inputview.content.util.createKey(spec);249};250/**251 * Creates a space key.252 *253 * @return {!Object} The space key.254 */255i18n.input.chrome.inputview.content.util.createSpaceKey = function() {256 var spec = {};257 spec[SpecNodeName.NAME] = ' ';258 spec[SpecNodeName.TYPE] = ElementType.SPACE_KEY;259 spec[SpecNodeName.ID] = 'Space';260 return i18n.input.chrome.inputview.content.util.createKey(spec);261};262/**263 * Create an IME switch key.264 *265 * @param {string} id .266 * @param {string} name .267 * @param {string} css .268 * @return {!Object} The JP IME switch key.269 */270i18n.input.chrome.inputview.content.util.createIMESwitchKey =271 function(id, name, css) {272 var spec = {};273 spec[SpecNodeName.NAME] = name;274 spec[SpecNodeName.TYPE] = ElementType.IME_SWITCH;275 spec[SpecNodeName.ID] = id;276 spec[SpecNodeName.TEXT_CSS_CLASS] = css;277 return i18n.input.chrome.inputview.content.util.createKey(spec);278};279/**280 * Creates a normal key.281 *282 * @param {!Object} spec The specification.283 * @return {!Object} The normal key.284 */285i18n.input.chrome.inputview.content.util.createNormalKey = function(spec) {286 spec[SpecNodeName.TYPE] = ElementType.CHARACTER_KEY;287 return i18n.input.chrome.inputview.content.util.createKey(spec);288};289/**290 * Creates an arrow key.291 *292 * @param {!i18n.input.chrome.inputview.Direction} direction The direction.293 * @return {!Object} The arrow key.294 */295i18n.input.chrome.inputview.content.util.createArrowKey = function(direction) {296 var spec = {};297 spec[SpecNodeName.ICON_CSS_CLASS] =298 i18n.input.chrome.inputview.Css.ARROW_KEY + ' ';299 if (direction == i18n.input.chrome.inputview.Direction.UP) {300 spec[SpecNodeName.ID] = 'ArrowUp';301 spec[SpecNodeName.ICON_CSS_CLASS] += i18n.input.chrome.inputview.Css.UP_KEY;302 spec[SpecNodeName.TYPE] = ElementType.ARROW_UP;303 } else if (direction == i18n.input.chrome.inputview.Direction.DOWN) {304 spec[SpecNodeName.ID] = 'ArrowDown';305 spec[SpecNodeName.ICON_CSS_CLASS] +=306 i18n.input.chrome.inputview.Css.DOWN_KEY;307 spec[SpecNodeName.TYPE] = ElementType.ARROW_DOWN;308 } else if (direction == i18n.input.chrome.inputview.Direction.LEFT) {309 spec[SpecNodeName.ID] = 'ArrowLeft';310 spec[SpecNodeName.ICON_CSS_CLASS] +=311 i18n.input.chrome.inputview.Css.LEFT_KEY;312 spec[SpecNodeName.TYPE] = ElementType.ARROW_LEFT;313 } else if (direction == i18n.input.chrome.inputview.Direction.RIGHT) {314 spec[SpecNodeName.ID] = 'ArrowRight';315 spec[SpecNodeName.ICON_CSS_CLASS] +=316 i18n.input.chrome.inputview.Css.RIGHT_KEY;317 spec[SpecNodeName.TYPE] = ElementType.ARROW_RIGHT;318 }319 return i18n.input.chrome.inputview.content.util.createKey(spec);320};321/**322 * Creates a soft key.323 *324 * @param {!Object} spec The specification.325 * @return {!Object} The soft key.326 */327i18n.input.chrome.inputview.content.util.createKey = function(spec) {328 var newSpec = {};329 for (var key in spec) {330 newSpec[key] = spec[key];331 }332 return {333 'spec': newSpec334 };335};336/**337 * The physical key codes.338 *339 * @type {!Array.<string>}340 */341i18n.input.chrome.inputview.content.util.KEY_CODES_101 = [342 'Backquote',343 'Digit1',344 'Digit2',345 'Digit3',346 'Digit4',347 'Digit5',348 'Digit6',349 'Digit7',350 'Digit8',351 'Digit9',352 'Digit0',353 'Minus',354 'Equal',355 'KeyQ',356 'KeyW',357 'KeyE',358 'KeyR',359 'KeyT',360 'KeyY',361 'KeyU',362 'KeyI',363 'KeyO',364 'KeyP',365 'BracketLeft',366 'BracketRight',367 'Backslash',368 'KeyA',369 'KeyS',370 'KeyD',371 'KeyF',372 'KeyG',373 'KeyH',374 'KeyJ',375 'KeyK',376 'KeyL',377 'Semicolon',378 'Quote',379 'KeyZ',380 'KeyX',381 'KeyC',382 'KeyV',383 'KeyB',384 'KeyN',385 'KeyM',386 'Comma',387 'Period',388 'Slash'389];390/**391 * The physical key codes for 102 keyboard.392 *393 * @type {!Array.<string>}394 */395i18n.input.chrome.inputview.content.util.KEY_CODES_102 = [396 'Backquote',397 'Digit1',398 'Digit2',399 'Digit3',400 'Digit4',401 'Digit5',402 'Digit6',403 'Digit7',404 'Digit8',405 'Digit9',406 'Digit0',407 'Minus',408 'Equal',409 'KeyQ',410 'KeyW',411 'KeyE',412 'KeyR',413 'KeyT',414 'KeyY',415 'KeyU',416 'KeyI',417 'KeyO',418 'KeyP',419 'BracketLeft',420 'BracketRight',421 'KeyA',422 'KeyS',423 'KeyD',424 'KeyF',425 'KeyG',426 'KeyH',427 'KeyJ',428 'KeyK',429 'KeyL',430 'Semicolon',431 'Quote',432 'Backslash',433 'IntlBackslash',434 'KeyZ',435 'KeyX',436 'KeyC',437 'KeyV',438 'KeyB',439 'KeyN',440 'KeyM',441 'Comma',442 'Period',443 'Slash'444];445/**446 * Creates the key data.447 *448 * @param {!Array.<!Array.<string>>} keyCharacters The key characters.449 * @param {string} viewIdPrefix The prefix of the view.450 * @param {boolean} is102 True if it is a 102 keyboard.451 * @param {boolean} hasAltGrKey True if there is altgr key.452 * @param {!Array.<!Array.<number>>=} opt_keyCodes The key codes.453 * @param {string=} opt_compactKeyboardId The compact keyboard id.454 * @return {!Object} The key data.455 */456i18n.input.chrome.inputview.content.util.createData = function(keyCharacters,457 viewIdPrefix, is102, hasAltGrKey, opt_keyCodes, opt_compactKeyboardId) {458 var keyList = [];459 var mapping = {};460 var keyCodes = opt_keyCodes || [];461 var keyIds = is102 ? i18n.input.chrome.inputview.content.util.KEY_CODES_102 :462 i18n.input.chrome.inputview.content.util.KEY_CODES_101;463 // The keys shows the shift character in Default state. In material design,464 // Only the first 11 keys will show shift character.465 var keysShowShift = 11;466 for (var i = 0; i < keyCharacters.length - 1; i++) {467 var spec = {};468 spec[SpecNodeName.ID] = keyIds[i];469 spec[SpecNodeName.TYPE] = ElementType.CHARACTER_KEY;470 spec[SpecNodeName.CHARACTERS] = keyCharacters[i];471 spec[SpecNodeName.KEY_CODE] = keyCodes[i];472 if (i < keysShowShift) {473 spec[SpecNodeName.ENABLE_SHIFT_RENDERING] = true;474 }475 var key = i18n.input.chrome.inputview.content.util.createKey(spec);476 keyList.push(key);477 }478 i18n.input.chrome.inputview.content.util.insertModifierKeys_(keyList,479 is102, opt_compactKeyboardId);480 for (var i = 0; i < keyList.length; i++) {481 var key = keyList[i];482 mapping[key['spec'][SpecNodeName.ID]] = viewIdPrefix + i;483 }484 var layout = is102 ? '102kbd' : '101kbd';485 var result = {};486 result[SpecNodeName.KEY_LIST] = keyList;487 result[SpecNodeName.MAPPING] = mapping;488 result[SpecNodeName.LAYOUT] = layout;489 result[SpecNodeName.HAS_ALTGR_KEY] = hasAltGrKey;490 result[SpecNodeName.SHOW_MENU_KEY] = true;491 return result;492};493/**494 * Creates a switcher key which will switch between keyboards.495 *496 * @param {string} id The id.497 * @param {string} name The name.498 * @param {string|undefined} toKeyset The id of keyset this swicher key should499 * switch to.500 * @param {string} toKeysetName The name of the keyset.501 * @param {string=} opt_iconCssClass The css class for the icon.502 * @param {boolean=} opt_record True to record and next time the keyset will503 * be recalled.504 * @return {!Object} The switcher key.505 */506i18n.input.chrome.inputview.content.util.createSwitcherKey = function(507 id, name, toKeyset, toKeysetName, opt_iconCssClass, opt_record) {508 var spec = {};509 spec[SpecNodeName.ID] = id;510 spec[SpecNodeName.NAME] = name;511 spec[SpecNodeName.TO_KEYSET] = toKeyset;512 spec[SpecNodeName.TO_KEYSET_NAME] = toKeysetName;513 spec[SpecNodeName.ICON_CSS_CLASS] = opt_iconCssClass;514 spec[SpecNodeName.TYPE] = ElementType.SWITCHER_KEY;515 spec[SpecNodeName.RECORD] = !!opt_record;516 return i18n.input.chrome.inputview.content.util.createKey(spec);517};518/**519 * Inserts modifier keys into the key list.520 *521 * @param {!Array.<!Object>} keyList The key list.522 * @param {boolean} is102 True if it is a 102 keyboard.523 * @param {string=} opt_compactKeyboardId The compact keyboard id.524 * @private525 */526i18n.input.chrome.inputview.content.util.insertModifierKeys_ = function(527 keyList, is102, opt_compactKeyboardId) {528 goog.array.insertAt(keyList, i18n.input.chrome.inputview.content.util.529 createBackspaceKey(), 13);530 goog.array.insertAt(keyList, i18n.input.chrome.inputview.content.util.531 createTabKey(), 14);532 goog.array.insertAt(keyList, i18n.input.chrome.inputview.content.util.533 createCapslockKey(), is102 ? 27 : 28);534 goog.array.insertAt(keyList, i18n.input.chrome.inputview.content.util.535 createEnterKey(), 40);536 goog.array.insertAt(keyList, i18n.input.chrome.inputview.content.util.537 createShiftKey(true), 41);538 keyList.push(i18n.input.chrome.inputview.content.util.createShiftKey(false));539 i18n.input.chrome.inputview.content.util.addLastRowKeys(540 keyList, is102, opt_compactKeyboardId);541};542/**543 * Inserts modifier keys into the key list.544 *545 * @param {!Array.<!Object>} keyList The key list.546 * @param {boolean} is102 True if it is a 102 keyboard.547 * @param {string=} opt_compactKeyboardId The compact keyboard id.548 */549i18n.input.chrome.inputview.content.util.addLastRowKeys =550 function(keyList, is102, opt_compactKeyboardId) {551 keyList.push(i18n.input.chrome.inputview.content.util.createGlobeKey());552 keyList.push(i18n.input.chrome.inputview.content.util.createMenuKey(553 opt_compactKeyboardId));554 keyList.push(i18n.input.chrome.inputview.content.util.createCtrlKey());555 keyList.push(i18n.input.chrome.inputview.content.util.createAltKey());556 keyList.push(i18n.input.chrome.inputview.content.util.createSpaceKey());557 keyList.push(i18n.input.chrome.inputview.content.util.createEnSwitcherKey());558 keyList.push(i18n.input.chrome.inputview.content.util.createAltgrKey());559 keyList.push(i18n.input.chrome.inputview.content.util.createArrowKey(560 i18n.input.chrome.inputview.Direction.LEFT));561 keyList.push(i18n.input.chrome.inputview.content.util.createArrowKey(562 i18n.input.chrome.inputview.Direction.RIGHT));563 keyList.push(i18n.input.chrome.inputview.content.util.564 createHideKeyboardKey());565};...
index.js
Source:index.js
1/**2 * @fileOverview main file3 * @module index4 */5require('./index');6const _merge = require('lodash.merge');7const fs = require('fs');8const path = require('path');9const swaggerUi = require('swagger-ui-express');10const utils = require('./lib/utils');11const { generateMongooseModelsSpec } = require('./lib/mongoose');12const { generateTagsSpec, matchingTags } = require('./lib/tags');13const { convertOpenApiVersionToV3, getSpecByVersion, versions } = require('./lib/openapi');14const processors = require('./lib/processors');15const listEndpoints = require('express-list-endpoints');16const { logger } = require('./lib/logger');17const { ensureDirectoryExistence } = require('./lib/file');18const SPEC_OUTPUT_FILE_BEHAVIOR = {19 PRESERVE: 'PRESERVE',20 RECREATE: 'RECREATE'21};22const DEFAULT_SWAGGER_UI_SERVE_PATH = 'api-docs';23const DEFAULT_IGNORE_NODE_ENVIRONMENTS = ['production'];24const UNDEFINED_NODE_ENV_ERROR = ignoredNodeEnvironments => `WARNING!!! process.env.NODE_ENV is not defined.\25To disable the module set process.env.NODE_ENV to any of the supplied ignoredNodeEnvironments: ${ignoredNodeEnvironments.join()}`;26const WRONG_MIDDLEWARE_ORDER_ERROR = `27Express oas generator:28you miss-placed the **response** and **request** middlewares!29Please, make sure to:301. place the RESPONSE middleware FIRST,31right after initializing the express app,322. and place the REQUEST middleware LAST,33inside the app.listen callback34For more information, see https://github.com/mpashkovskiy/express-oas-generator#Advanced-usage-recommended35`;36let packageJsonPath = `${process.cwd()}/package.json`;37let packageInfo;38let app;39/**40 * @param {function|object} predefinedSpec either the Swagger specification41 * or a function with one argument producing it.42 */43let swaggerUiServePath;44let predefinedSpec;45let spec = {};46let mongooseModelsSpecs;47let tagsSpecs;48let ignoredNodeEnvironments;49let serveDocs;50let specOutputPath;51let specOutputFileBehavior;52/**53 * @type { typeof import('./index').SwaggerUiOptions }54*/55let swaggerDocumentOptions;56/**57 * @param {boolean} [responseMiddlewareHasBeenApplied=false]58 *59 * @note make sure to reset this variable once you've done your checks.60 *61 * @description used make sure the *order* of which the middlewares are applied is correct62 *63 * The `response` middleware MUST be applied FIRST,64 * before the `request` middleware is applied.65 *66 * We'll use this to make sure the order is correct.67 * If not - we'll throw an informative error.68 */69let responseMiddlewareHasBeenApplied = false;70/**71 *72 */73function updateSpecFromPackage() {74 /* eslint global-require : off */75 packageInfo = fs.existsSync(packageJsonPath) ? require(packageJsonPath) : {};76 spec.info = spec.info || {};77 78 if (packageInfo.name) {79 spec.info.title = packageInfo.name;80 }81 if (packageInfo.version) {82 spec.info.version = packageInfo.version;83 }84 if (packageInfo.license) {85 spec.info.license = { name: packageInfo.license };86 }87 packageInfo.baseUrlPath = packageInfo.baseUrlPath || '';88 const v2link = `[${versions.OPEN_API_V2}](${packageInfo.baseUrlPath}/api-spec/${versions.OPEN_API_V2})`;89 const v3link = `[${versions.OPEN_API_V3}](${packageInfo.baseUrlPath}/api-spec/${versions.OPEN_API_V3})`;90 spec.info.description = `Specification JSONs: ${v2link}, ${v3link}.`;91 if (packageInfo.baseUrlPath !== '') {92 spec.basePath = packageInfo.baseUrlPath;93 spec.info.description += ` Base url: [${packageInfo.baseUrlPath}](${packageInfo.baseUrlPath})`;94 }95 if (packageInfo.description) {96 spec.info.description += `\n\n${packageInfo.description}`;97 }98}99/**100 * @description Builds api spec middleware101 *102 * @returns Middleware103 */104function apiSpecMiddleware(version) {105 return (req, res) => {106 getSpecByVersion(spec, version, (err, openApiSpec) => {107 if (!err) {108 res.setHeader('Content-Type', 'application/json');109 res.send(JSON.stringify(openApiSpec, null, 2));110 }111 });112 };113}114/**115 * @description Builds swagger serve middleware116 * @param version Available open api versions: 'v2' (default if empty) or 'v3'.117 * @returns Middleware118 */119function swaggerServeMiddleware(version) {120 return (req, res) => {121 getSpecByVersion(spec, version, (err, openApiSpec) => {122 if (!err) {123 res.setHeader('Content-Type', 'text/html');124 swaggerUi.setup(openApiSpec, swaggerDocumentOptions)(req, res);125 }126 });127 };128}129/**130 * @description Applies spec middlewares131 * @param version Available open api versions: 'v2' (default if empty) or 'v3'.132 */133function applySpecMiddlewares(version = '') {134 const apiSpecBasePath = packageInfo.baseUrlPath.concat('/api-spec');135 const baseSwaggerServePath = packageInfo.baseUrlPath.concat('/' + swaggerUiServePath);136 app.use(apiSpecBasePath.concat('/' + version), apiSpecMiddleware(version));137 app.use(baseSwaggerServePath.concat('/' + version), swaggerUi.serve, swaggerServeMiddleware(version));138}139/**140 * @description Prepares spec to be served141 *142 * @returns void143 */144function prepareSpec() {145 spec = { swagger: '2.0', paths: {} };146 const endpoints = listEndpoints(app);147 endpoints.forEach(endpoint => {148 const params = [];149 let path = endpoint.path;150 const matches = path.match(/:([^/]+)/g);151 if (matches) {152 matches.forEach(found => {153 const paramName = found.substr(1);154 path = path.replace(found, `{${paramName}}`);155 params.push(paramName);156 });157 }158 if (!spec.paths[path]) {159 spec.paths[path] = {};160 }161 spec.tags = tagsSpecs || [];162 endpoint.methods.forEach(m => {163 spec.paths[path][m.toLowerCase()] = {164 summary: path,165 consumes: ['application/json'],166 parameters: params.map(p => ({167 name: p,168 in: 'path',169 required: true,170 })) || [],171 responses: {},172 tags: matchingTags(tagsSpecs || [], path)173 };174 });175 });176 spec.definitions = mongooseModelsSpecs || {};177 updateSpecFromPackage();178 spec = patchSpec(predefinedSpec);179}180/**181 * @description serve the openAPI docs with swagger at a specified path / url182 *183 * @returns void184 */185function serveApiDocs() {186 prepareSpec();187 applySpecMiddlewares(versions.OPEN_API_V2);188 189 applySpecMiddlewares(versions.OPEN_API_V3);190 // Base path middleware should be applied after specific versions191 applySpecMiddlewares(); 192}193/**194 *195 * @param predefinedSpec196 * @returns {{}}197 */198function patchSpec(predefinedSpec) {199 return !predefinedSpec200 ? spec201 : typeof predefinedSpec === 'object'202 ? utils.sortObject(_merge(spec, predefinedSpec || {}))203 : predefinedSpec(spec);204}205/**206 *207 * @param req208 * @returns {string|undefined|*}209 */210function getPathKey(req) {211 if (!req.url || spec.paths[req.url]) {212 return req.url;213 }214 const url = req.url.split('?')[0];215 const pathKeys = Object.keys(spec.paths);216 for (let i = 0; i < pathKeys.length; i += 1) {217 const pathKey = pathKeys[i];218 if (url.match(`${pathKey.replace(/{([^/]+)}/g, '(?:([^\\\\/]+?))')}/?$`)) {219 return pathKey;220 }221 }222 return undefined;223}224/**225 *226 * @param req227 * @returns {{method: *, pathKey: *}|undefined}228 */229function getMethod(req) {230 if (req.url.startsWith('/api-')) {231 return undefined;232 }233 const m = req.method.toLowerCase();234 if (m === 'options') {235 return undefined;236 }237 const pathKey = getPathKey(req);238 if (!pathKey) {239 return undefined;240 }241 return { method: spec.paths[pathKey][m], pathKey };242}243/**244 *245 * @param req246 */247function updateSchemesAndHost(req) {248 spec.schemes = spec.schemes || [];249 if (spec.schemes.indexOf(req.protocol) === -1) {250 spec.schemes.push(req.protocol);251 }252 if (!spec.host) {253 spec.host = req.get('host');254 }255}256/**257 * @description Generates definitions spec from mongoose models258 */259function updateDefinitionsSpec(mongooseModels) {260 const validMongooseModels = Array.isArray(mongooseModels) && mongooseModels.length > 0;261 262 if (validMongooseModels && !mongooseModelsSpecs) {263 mongooseModelsSpecs = generateMongooseModelsSpec(mongooseModels);264 }265}266/**267 * @description Generates tags spec268 */269function updateTagsSpec(tags) {270 const validTags = tags && Array.isArray(tags) && tags.length > 0;271 if (validTags && !tagsSpecs) {272 tagsSpecs = generateTagsSpec(tags);273 }274}275/**276 * @description Loads specOutputPath initial content to predefinedSpec.277 * Based on SPEC_OUTPUT_FILE_BEHAVIOR.PRESERVE or SPEC_OUTPUT_FILE_BEHAVIOR.RECREATE278 */279function loadSpecOutputPathContent() {280 if (specOutputFileBehavior !== SPEC_OUTPUT_FILE_BEHAVIOR.PRESERVE) {281 return;282 }283 if (!fs.existsSync(specOutputPath)) {284 return;285 }286 const specOutputFileContent = fs.readFileSync(specOutputPath).toString();287 predefinedSpec = JSON.parse(specOutputFileContent);288}289/**290 * @description Persists OpenAPI content to spec output file291 */292function writeSpecToOutputFile() {293 if (!specOutputPath) {294 return;295 }296 fs.writeFileSync(specOutputPath, JSON.stringify(spec, null, 2), 'utf8');297 convertOpenApiVersionToV3(spec, (err, specV3) => {298 if (!err) {299 const parsedSpecOutputPath = path.parse(specOutputPath);300 const {name, ext} = parsedSpecOutputPath;301 parsedSpecOutputPath.base = name.concat('_').concat(versions.OPEN_API_V3).concat(ext);302 303 const v3Path = path.format(parsedSpecOutputPath);304 305 fs.writeFileSync(v3Path, JSON.stringify(specV3, null, 2), 'utf8');306 }307 /** TODO - Log that open api v3 could not be generated */308 });309}310/**311 * @type { typeof import('./index').handleResponses }312*/313function handleResponses(expressApp, 314 options = { 315 swaggerUiServePath: DEFAULT_SWAGGER_UI_SERVE_PATH, 316 specOutputPath: undefined, 317 predefinedSpec: {}, 318 writeIntervalMs: 0, 319 mongooseModels: [], 320 tags: undefined,321 ignoredNodeEnvironments: DEFAULT_IGNORE_NODE_ENVIRONMENTS,322 alwaysServeDocs: undefined,323 specOutputFileBehavior: SPEC_OUTPUT_FILE_BEHAVIOR.RECREATE,324 swaggerDocumentOptions: {}325 }) {326 ignoredNodeEnvironments = options.ignoredNodeEnvironments || DEFAULT_IGNORE_NODE_ENVIRONMENTS;327 const isEnvironmentIgnored = ignoredNodeEnvironments.includes(process.env.NODE_ENV || '');328 serveDocs = options.alwaysServeDocs;329 330 if (serveDocs === undefined) {331 serveDocs = !isEnvironmentIgnored;332 }333 334 if (!process.env.NODE_ENV) {335 logger.warn(UNDEFINED_NODE_ENV_ERROR(ignoredNodeEnvironments));336 }337 338 /**339 * save the `expressApp` to our local `app` variable.340 * Used here, but not in `handleRequests`,341 * because this comes before it.342 */343 app = expressApp;344 swaggerUiServePath = options.swaggerUiServePath || DEFAULT_SWAGGER_UI_SERVE_PATH;345 predefinedSpec = options.predefinedSpec || {};346 specOutputPath = options.specOutputPath;347 specOutputFileBehavior = options.specOutputFileBehavior;348 swaggerDocumentOptions = options.swaggerDocumentOptions;349 350 loadSpecOutputPathContent();351 updateDefinitionsSpec(options.mongooseModels);352 updateTagsSpec(options.tags || options.mongooseModels);353 354 if (isEnvironmentIgnored) {355 return;356 }357 358 responseMiddlewareHasBeenApplied = true;359 /** middleware to handle RESPONSES */360 app.use((req, res, next) => {361 try {362 const methodAndPathKey = getMethod(req);363 if (methodAndPathKey && methodAndPathKey.method) {364 processors.processResponse(res, methodAndPathKey.method, () => {365 writeSpecToOutputFile();366 });367 }368 369 } catch (e) {370 /** TODO - shouldn't we do something here? */371 } finally {372 /** always call the next middleware */373 next();374 }375 });376}377/**378 * @type { typeof import('./index').handleRequests }379 */380function handleRequests() {381 382 const isIgnoredEnvironment = ignoredNodeEnvironments.includes(process.env.NODE_ENV);383 if (serveDocs || !isIgnoredEnvironment) { 384 /** forward options to `serveApiDocs`: */385 serveApiDocs();386 }387 if (isIgnoredEnvironment) {388 return;389 }390 391 /** make sure the middleware placement order (by the user) is correct */392 if (responseMiddlewareHasBeenApplied !== true) {393 throw new Error(WRONG_MIDDLEWARE_ORDER_ERROR);394 }395 /** everything was applied correctly; reset the global variable. */396 responseMiddlewareHasBeenApplied = false;397 if (specOutputPath) {398 ensureDirectoryExistence(specOutputPath);399 }400 401 /** middleware to handle REQUESTS */402 app.use((req, res, next) => {403 try {404 const methodAndPathKey = getMethod(req);405 if (methodAndPathKey && methodAndPathKey.method && methodAndPathKey.pathKey) {406 const method = methodAndPathKey.method;407 updateSchemesAndHost(req);408 processors.processPath(req, method, methodAndPathKey.pathKey);409 processors.processHeaders(req, method, spec);410 processors.processBody(req, method);411 processors.processQuery(req, method);412 writeSpecToOutputFile();413 }414 } catch (e) {415 /** TODO - shouldn't we do something here? */416 } finally {417 next();418 }419 });420}421/**422 * TODO423 *424 * 1. Rename the parameter names425 * (this will require better global variable naming to allow re-assigning properly)426 *427 * 2. the `aPath` is ignored only if it's `undefined`,428 * but if it's set to an empty string `''`, then the tests fail.429 * I think we should be checking for falsy values, not only `undefined` ones.430 *431 * 3. (Breaking) Use object for optional parameters:432 * https://github.com/mpashkovskiy/express-oas-generator/issues/35433 *434 */435/**436 * @type { typeof import('./index').init }437 */438function init(aApp, aPredefinedSpec = {}, aSpecOutputPath = undefined, aWriteInterval = 0, aSwaggerUiServePath = DEFAULT_SWAGGER_UI_SERVE_PATH, aMongooseModels = [], aTags = undefined, aIgnoredNodeEnvironments = DEFAULT_IGNORE_NODE_ENVIRONMENTS, aAlwaysServeDocs = undefined, aSpecOutputFileBehavior = SPEC_OUTPUT_FILE_BEHAVIOR.RECREATE, aSwaggerDocumentOptions = {}) {439 handleResponses(aApp, {440 swaggerUiServePath: aSwaggerUiServePath,441 specOutputPath: aSpecOutputPath,442 predefinedSpec: aPredefinedSpec,443 writeIntervalMs: aWriteInterval,444 mongooseModels: aMongooseModels,445 tags: aTags,446 ignoredNodeEnvironments: aIgnoredNodeEnvironments,447 alwaysServeDocs: aAlwaysServeDocs,448 specOutputFileBehavior: aSpecOutputFileBehavior,449 swaggerDocumentOptions: aSwaggerDocumentOptions450 });451 setTimeout(() => handleRequests(), 1000);452}453/**454 * @type { typeof import('./index').getSpec }455 */456const getSpec = () => {457 return patchSpec(predefinedSpec);458};459/**460 * @type { typeof import('./index').getSpecV3 }461 */462const getSpecV3 = callback => {463 convertOpenApiVersionToV3(getSpec(), callback);464};465/**466 * @type { typeof import('./index').setPackageInfoPath }467 *468 * @param pkgInfoPath path to package.json469 */470const setPackageInfoPath = pkgInfoPath => {471 packageJsonPath = `${process.cwd()}/${pkgInfoPath}/package.json`;472};473module.exports = {474 handleResponses,475 handleRequests,476 init,477 getSpec,478 getSpecV3,479 setPackageInfoPath,480 SPEC_OUTPUT_FILE_BEHAVIOR...
compact_util.js
Source:compact_util.js
1// Copyright 2014 The ChromeOS IME Authors. All Rights Reserved.2// limitations under the License.3// See the License for the specific language governing permissions and4// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.5// distributed under the License is distributed on an "AS-IS" BASIS,6// Unless required by applicable law or agreed to in writing, software7//8// http://www.apache.org/licenses/LICENSE-2.09//10// You may obtain a copy of the License at11// you may not use this file except in compliance with the License.12// Licensed under the Apache License, Version 2.0 (the "License");13//14goog.provide('i18n.input.chrome.inputview.content.compact.util');15goog.provide('i18n.input.chrome.inputview.content.compact.util.CompactKeysetSpec');16goog.require('goog.object');17goog.require('i18n.input.chrome.ElementType');18goog.require('i18n.input.chrome.inputview.Css');19goog.require('i18n.input.chrome.inputview.SpecNodeName');20goog.require('i18n.input.chrome.inputview.content.Constants');21goog.scope(function() {22var util = i18n.input.chrome.inputview.content.compact.util;23var NON_LETTER_KEYS =24 i18n.input.chrome.inputview.content.Constants.NON_LETTER_KEYS;25var Css = i18n.input.chrome.inputview.Css;26var SpecNodeName = i18n.input.chrome.inputview.SpecNodeName;27/**28 * The compact layout keyset type.29 *30 * @enum {string}31 */32util.CompactKeysetSpec = {33 ID: 'id',34 LAYOUT: 'layout',35 DATA: 'data'36};37/**38 * @desc The name of the layout providing numbers from 0-9 and common39 * symbols.40 */41util.MSG_NUMBER_AND_SYMBOL =42 goog.getMsg('number and symbol layout');43/**44 * @desc The name of the layout providing more symbols.45 */46util.MSG_MORE_SYMBOLS =47 goog.getMsg('more symbols layout');48/**49 * @desc The name of the main layout.50 */51util.MSG_MAIN_LAYOUT = goog.getMsg('main layout');52/**53 * @desc The name of the english main layout.54 */55util.MSG_ENG_MAIN_LAYOUT = goog.getMsg('english main layout');56/**57 * @desc The name of the english layout providing numbers from 0-9 and common.58 */59util.MSG_ENG_MORE_SYMBOLS =60 goog.getMsg('english more symbols layout');61/**62 * @desc The name of the english layout providing more symbols.63 */64util.MSG_ENG_NUMBER_AND_SYMBOL =65 goog.getMsg('english number and symbol layout');66/**67 * Creates the compact key data.68 *69 * @param {!Object} keysetSpec The keyset spec.70 * @param {string} viewIdPrefix The prefix of the view.71 * @param {string} keyIdPrefix The prefix of the key.72 * @return {!Object} The key data.73 */74util.createCompactData = function(keysetSpec, viewIdPrefix, keyIdPrefix) {75 var keyList = [];76 var mapping = {};77 var keysetSpecNode = util.CompactKeysetSpec;78 for (var i = 0; i < keysetSpec[keysetSpecNode.DATA].length; i++) {79 var keySpec = keysetSpec[keysetSpecNode.DATA][i];80 if (keySpec == NON_LETTER_KEYS.MENU) {81 keySpec[SpecNodeName.TO_KEYSET] =82 keysetSpec[keysetSpecNode.ID].split('.')[0];83 }84 var id = keySpec[SpecNodeName.ID] ?85 keySpec[SpecNodeName.ID] :86 keyIdPrefix + i;87 var key = util.createCompactKey(id, keySpec);88 keyList.push(key);89 mapping[key['spec'][SpecNodeName.ID]] = viewIdPrefix + i;90 }91 var compactKeyData = {};92 compactKeyData[SpecNodeName.KEY_LIST] = keyList;93 compactKeyData[SpecNodeName.MAPPING] = mapping;94 compactKeyData[SpecNodeName.LAYOUT] = keysetSpec[keysetSpecNode.LAYOUT];95 return compactKeyData;96};97/**98 * Creates a key in the compact keyboard.99 *100 * @param {string} id The id.101 * @param {!Object} keySpec The specification.102 * @return {!Object} The compact key.103 */104util.createCompactKey = function(id, keySpec) {105 var spec = keySpec;106 spec[SpecNodeName.ID] = id;107 if (!spec[SpecNodeName.TYPE]) {108 spec[SpecNodeName.TYPE] =109 i18n.input.chrome.ElementType.COMPACT_KEY;110 }111 var newSpec = {};112 for (var key in spec) {113 newSpec[key] = spec[key];114 }115 return {116 'spec': newSpec117 };118};119/**120 * Customize the switcher keys in key characters.121 *122 * @param {!Array.<!Object>} keyCharacters The key characters.123 * @param {!Array.<!Object>} switcherKeys The customized switcher keys.124 */125util.customizeSwitchers = function(keyCharacters, switcherKeys) {126 var switcherKeyIndex = 0;127 for (var i = 0; i < keyCharacters.length; i++) {128 if (keyCharacters[i] == NON_LETTER_KEYS.SWITCHER) {129 if (switcherKeyIndex >= switcherKeys.length) {130 console.error('The number of switcher key spec is less than' +131 ' the number of switcher keys in the keyset.');132 return;133 }134 // Merge the switcher key and key character specifications.135 var newSpec = {};136 goog.object.extend(newSpec, switcherKeys[switcherKeyIndex]);137 goog.object.extend(newSpec, keyCharacters[i]);138 // Assign the merged specification to the key and139 // move on to the next switcher key.140 keyCharacters[i] = newSpec;141 switcherKeyIndex++;142 }143 }144 if (switcherKeyIndex < switcherKeys.length) {145 console.error('The number of switcher key spec is more than' +146 ' the number of switcher keys in the keyset.');147 }148};149/**150 * Attaches a keyset to the spacebar.151 * This is used to switch to the letter keyset when space is entered152 * after a symbol.153 *154 * @param {!Array.<!Object>} keyCharacters The key characters.155 * @param {string} letterKeysetId The ID of the letter keyset.156 * @private157 */158util.addKeysetToSpacebar_ = function(keyCharacters, letterKeysetId) {159 for (var i = 0; i < keyCharacters.length; i++) {160 if (keyCharacters[i] == NON_LETTER_KEYS.SPACE) {161 keyCharacters[i][SpecNodeName.TO_KEYSET] = letterKeysetId;162 break;163 }164 }165};166/**167 * Generates letter, symbol and more compact keysets, and loads them.168 *169 * @param {!Object} letterKeysetSpec The spec of letter keyset.170 * @param {!Object} symbolKeysetSpec The spec of symbol keyset.171 * @param {!Object} moreKeysetSpec The spec of more keyset.172 * @param {!function(!Object): void} onLoaded The function to call once keyset173 * data is ready.174 */175util.generateCompactKeyboard =176 function(letterKeysetSpec, symbolKeysetSpec, moreKeysetSpec, onLoaded) {177 // Creates the switcher key specifications.178 var keysetSpecNode = util.CompactKeysetSpec;179 var lettersSwitcherKey = {};180 lettersSwitcherKey[SpecNodeName.NAME] = 'abc';181 lettersSwitcherKey[SpecNodeName.TO_KEYSET] =182 letterKeysetSpec[keysetSpecNode.ID];183 lettersSwitcherKey[SpecNodeName.TO_KEYSET_NAME] = util.MSG_MAIN_LAYOUT;184 var symbolsSwitcherKey = {};185 symbolsSwitcherKey[SpecNodeName.NAME] = '?123';186 symbolsSwitcherKey[SpecNodeName.TO_KEYSET] =187 symbolKeysetSpec[keysetSpecNode.ID];188 symbolsSwitcherKey[SpecNodeName.TO_KEYSET_NAME] = util.MSG_NUMBER_AND_SYMBOL;189 var moreSwitcherKey = {};190 moreSwitcherKey[SpecNodeName.NAME] = '~[<';191 moreSwitcherKey[SpecNodeName.TO_KEYSET] = moreKeysetSpec[keysetSpecNode.ID];192 moreSwitcherKey[SpecNodeName.TO_KEYSET_NAME] = util.MSG_MORE_SYMBOLS;193 // Creates compact qwerty keyset.194 util.customizeSwitchers(195 letterKeysetSpec[keysetSpecNode.DATA],196 [symbolsSwitcherKey]);197 var data = util.createCompactData(198 letterKeysetSpec, 'compactkbd-k-', 'compactkbd-k-key-');199 data[SpecNodeName.ID] = letterKeysetSpec[keysetSpecNode.ID];200 data[SpecNodeName.SHOW_MENU_KEY] = true;201 onLoaded(data);202 // Creates compact symbol keyset.203 util.customizeSwitchers(204 symbolKeysetSpec[keysetSpecNode.DATA],205 [moreSwitcherKey, moreSwitcherKey, lettersSwitcherKey]);206 util.addKeysetToSpacebar_(207 symbolKeysetSpec[keysetSpecNode.DATA],208 letterKeysetSpec[keysetSpecNode.ID]);209 data = util.createCompactData(210 symbolKeysetSpec, 'compactkbd-k-', 'compactkbd-k-key-');211 data[SpecNodeName.ID] = symbolKeysetSpec[keysetSpecNode.ID];212 data[SpecNodeName.SHOW_MENU_KEY] = false;213 data[SpecNodeName.NO_SHIFT] = true;214 onLoaded(data);215 // Creates compact more keyset.216 util.customizeSwitchers(217 moreKeysetSpec[keysetSpecNode.DATA],218 [symbolsSwitcherKey, symbolsSwitcherKey, lettersSwitcherKey]);219 data = util.createCompactData(moreKeysetSpec, 'compactkbd-k-',220 'compactkbd-k-key-');221 data[SpecNodeName.ID] = moreKeysetSpec[keysetSpecNode.ID];222 data[SpecNodeName.SHOW_MENU_KEY] = false;223 data[SpecNodeName.NO_SHIFT] = true;224 onLoaded(data);225};226/**227 * Generates letter, symbol and more compact keysets for228 * pinyin's chinese and english mode and load them.229 *230 * @param {!Object} letterKeysetSpec The spec of letter keyset.231 * @param {!Object} engKeysetSpec The english spec of letter keyset232 * @param {!Object} symbolKeysetSpec The spec of symbol keyset.233 * @param {!Object} engSymbolKeysetSpec The spec of engish symbol keyset.234 * @param {!Object} moreKeysetSpec The spec of more keyset.235 * @param {!Object} engMoreKeysetSpec The spec of english more keyset.236 * @param {!function(!Object): void} onLoaded The function to call once a keyset237 * data is ready.238 */239util.generatePinyinCompactKeyboard = function(letterKeysetSpec, engKeysetSpec,240 symbolKeysetSpec, engSymbolKeysetSpec,241 moreKeysetSpec, engMoreKeysetSpec, onLoaded) {242 // Creates the switcher key specifications.243 var keysetSpecNode = util.CompactKeysetSpec;244 var lettersSwitcherKey = {};245 lettersSwitcherKey[SpecNodeName.NAME] = 'abc';246 lettersSwitcherKey[SpecNodeName.TO_KEYSET] =247 letterKeysetSpec[keysetSpecNode.ID];248 lettersSwitcherKey[SpecNodeName.TO_KEYSET_NAME] = util.MSG_MAIN_LAYOUT;249 var symbolsSwitcherKey = {};250 symbolsSwitcherKey[SpecNodeName.NAME] = '?123';251 symbolsSwitcherKey[SpecNodeName.TO_KEYSET] =252 symbolKeysetSpec[keysetSpecNode.ID];253 symbolsSwitcherKey[SpecNodeName.TO_KEYSET_NAME] = util.MSG_NUMBER_AND_SYMBOL;254 var moreSwitcherKey = {};255 moreSwitcherKey[SpecNodeName.NAME] = '~[<';256 moreSwitcherKey[SpecNodeName.TO_KEYSET] = moreKeysetSpec[keysetSpecNode.ID];257 moreSwitcherKey[SpecNodeName.TO_KEYSET_NAME] = util.MSG_MORE_SYMBOLS;258 var engLettersSwitcherKey = {};259 engLettersSwitcherKey[SpecNodeName.NAME] = 'abc';260 engLettersSwitcherKey[SpecNodeName.TO_KEYSET] =261 engKeysetSpec[keysetSpecNode.ID];262 engLettersSwitcherKey[SpecNodeName.TO_KEYSET_NAME] = util.MSG_ENG_MAIN_LAYOUT;263 var engSymbolsSwitcherKey = {};264 engSymbolsSwitcherKey[SpecNodeName.NAME] = '?123';265 engSymbolsSwitcherKey[SpecNodeName.TO_KEYSET] =266 engSymbolKeysetSpec[keysetSpecNode.ID];267 engSymbolsSwitcherKey[SpecNodeName.TO_KEYSET_NAME] =268 util.MSG_ENG_NUMBER_AND_SYMBOL;269 var engMoreSwitcherKey = {};270 engMoreSwitcherKey[SpecNodeName.NAME] = '~[<';271 engMoreSwitcherKey[SpecNodeName.TO_KEYSET] =272 engMoreKeysetSpec[keysetSpecNode.ID];273 engMoreSwitcherKey[SpecNodeName.TO_KEYSET_NAME] = util.MSG_ENG_MORE_SYMBOLS;274 var lettersSwitcherKeyWithIcon = {};275 lettersSwitcherKeyWithIcon[SpecNodeName.TO_KEYSET] =276 letterKeysetSpec[keysetSpecNode.ID];277 lettersSwitcherKeyWithIcon[SpecNodeName.TO_KEYSET_NAME] =278 util.MSG_MAIN_LAYOUT;279 lettersSwitcherKeyWithIcon[SpecNodeName.ICON_CSS_CLASS] =280 Css.SWITCHER_ENGLISH;281 var engSwitcherKey = {};282 engSwitcherKey[SpecNodeName.TO_KEYSET] = engKeysetSpec[keysetSpecNode.ID];283 engSwitcherKey[SpecNodeName.TO_KEYSET_NAME] = util.MSG_ENG_MAIN_LAYOUT;284 engSwitcherKey[SpecNodeName.ICON_CSS_CLASS] = Css.SWITCHER_CHINESE;285 // Creates compact qwerty keyset for pinyin.286 util.customizeSwitchers(287 letterKeysetSpec[keysetSpecNode.DATA],288 [symbolsSwitcherKey, engSwitcherKey]);289 var data = util.createCompactData(290 letterKeysetSpec, 'compactkbd-k-', 'compactkbd-k-key-');291 data[SpecNodeName.ID] = letterKeysetSpec[keysetSpecNode.ID];292 data[SpecNodeName.SHOW_MENU_KEY] = true;293 onLoaded(data);294 // Creates the compact qwerty keyset for pinyin's English mode.295 util.customizeSwitchers(296 engKeysetSpec[keysetSpecNode.DATA],297 [engSymbolsSwitcherKey, lettersSwitcherKeyWithIcon]);298 data = util.createCompactData(299 engKeysetSpec, 'compactkbd-k-', 'compactkbd-k-key-');300 data[SpecNodeName.ID] = engKeysetSpec[keysetSpecNode.ID];301 data[SpecNodeName.SHOW_MENU_KEY] = true;302 onLoaded(data);303 // Creates compact symbol keyset for pinyin.304 util.customizeSwitchers(305 symbolKeysetSpec[keysetSpecNode.DATA],306 [moreSwitcherKey, moreSwitcherKey, lettersSwitcherKey]);307 data = util.createCompactData(308 symbolKeysetSpec, 'compactkbd-k-', 'compactkbd-k-key-');309 data[SpecNodeName.ID] = symbolKeysetSpec[keysetSpecNode.ID];310 data[SpecNodeName.SHOW_MENU_KEY] = false;311 data[SpecNodeName.NO_SHIFT] = true;312 onLoaded(data);313 // Creates compact symbol keyset for English mode.314 util.customizeSwitchers(315 engSymbolKeysetSpec[keysetSpecNode.DATA],316 [engMoreSwitcherKey, engMoreSwitcherKey, engLettersSwitcherKey]);317 data = util.createCompactData(318 engSymbolKeysetSpec, 'compactkbd-k-', 'compactkbd-k-key-');319 data[SpecNodeName.ID] = engSymbolKeysetSpec[keysetSpecNode.ID];320 data[SpecNodeName.SHOW_MENU_KEY] = false;321 data[SpecNodeName.NO_SHIFT] = true;322 onLoaded(data);323 // Creates compact more keyset for pinyin.324 util.customizeSwitchers(325 moreKeysetSpec[keysetSpecNode.DATA],326 [symbolsSwitcherKey, symbolsSwitcherKey, lettersSwitcherKey]);327 data = util.createCompactData(moreKeysetSpec, 'compactkbd-k-',328 'compactkbd-k-key-');329 data[SpecNodeName.ID] = moreKeysetSpec[keysetSpecNode.ID];330 data[SpecNodeName.SHOW_MENU_KEY] = false;331 data[SpecNodeName.NO_SHIFT] = true;332 onLoaded(data);333 // Creates the compact more keyset of english mode.334 util.customizeSwitchers(335 engMoreKeysetSpec[keysetSpecNode.DATA],336 [engSymbolsSwitcherKey, engSymbolsSwitcherKey, engLettersSwitcherKey]);337 data = util.createCompactData(engMoreKeysetSpec, 'compactkbd-k-',338 'compactkbd-k-key-');339 data[SpecNodeName.ID] = engMoreKeysetSpec[keysetSpecNode.ID];340 data[SpecNodeName.SHOW_MENU_KEY] = false;341 data[SpecNodeName.NO_SHIFT] = true;342 onLoaded(data);343};...
Schema.js
Source:Schema.js
1describe("Ext.data.schema.Schema", function() {2 3 var M = Ext.data.Model,4 schema;5 6 beforeEach(function() {7 schema = Ext.data.Model.schema;8 });9 10 afterEach(function() {11 schema = Ext.data.Model.schema;12 schema.clear(true);13 schema = null; 14 });15 16 describe("entity names", function() {17 function makeCls(name) {18 return {19 $className: name20 };21 }22 23 describe("without namespace", function() {24 it("should return null if there is no className", function() {25 expect(schema.getEntityName(makeCls())).toBeNull(); 26 });27 28 it("should return a simple name", function() {29 expect(schema.getEntityName(makeCls('User'))).toBe('User');30 });31 32 it("should return the full classname", function() {33 expect(schema.getEntityName(makeCls('Foo.bar.baz.User'))).toBe('Foo.bar.baz.User');34 });35 });36 37 describe("with namespace", function() { 38 it("should return null if there is no className", function() {39 schema.setNamespace('spec.model');40 expect(schema.getEntityName(makeCls())).toBeNull(); 41 });42 43 it("should return the model name sans the namespace", function() {44 schema.setNamespace('spec.model');45 expect(schema.getEntityName(makeCls('spec.model.User'))).toBe('User'); 46 });47 48 it("should return the other parts of model name sans the namespace", function() {49 schema.setNamespace('spec.model');50 expect(schema.getEntityName(makeCls('spec.model.trading.Bid'))).toBe('trading.Bid'); 51 });52 53 it("should support putting the . at the end of the namespace", function() {54 schema.setNamespace('spec.model.');55 expect(schema.getEntityName(makeCls('spec.model.User'))).toBe('User'); 56 });57 58 it("should not remove an unrelated namespace", function() {59 schema.setNamespace('spec.model.');60 expect(schema.getEntityName(makeCls('spec.wodel.User'))).toBe('spec.wodel.User');61 });62 });63 });64 describe("hasAssociations", function() {65 beforeEach(function() {66 schema.setNamespace('spec');67 });68 describe("one to one", function() {69 afterEach(function() {70 Ext.undefine('spec.User');71 Ext.undefine('spec.Address');72 });73 it("should have associations when the key holder is declared first", function() {74 Ext.define('spec.User', {75 extend: 'Ext.data.Model',76 fields: [{77 name: 'addressId',78 reference: 'Address',79 unique: true80 }]81 });82 Ext.define('spec.Address', {83 extend: 'Ext.data.Model'84 });85 expect(schema.hasAssociations(spec.User)).toBe(true);86 expect(schema.hasAssociations(spec.Address)).toBe(true);87 });88 it("should have associations when the non-key holder is declared first", function() {89 Ext.define('spec.Address', {90 extend: 'Ext.data.Model'91 });92 Ext.define('spec.User', {93 extend: 'Ext.data.Model',94 fields: [{95 name: 'addressId',96 reference: 'Address',97 unique: true98 }]99 });100 expect(schema.hasAssociations(spec.User)).toBe(true);101 expect(schema.hasAssociations(spec.Address)).toBe(true);102 });103 });104 describe("one to many", function() {105 afterEach(function() {106 Ext.undefine('spec.User');107 Ext.undefine('spec.Post');108 });109 it("should have associations when declaring the one first", function() {110 Ext.define('spec.User', {111 extend: 'Ext.data.Model'112 });113 Ext.define('spec.Post', {114 extend: 'Ext.data.Model',115 fields: [{116 name: 'userId',117 reference: 'User'118 }]119 });120 expect(schema.hasAssociations(spec.User)).toBe(true);121 expect(schema.hasAssociations(spec.Post)).toBe(true);122 });123 it("should have associations when declaring the many first", function() {124 Ext.define('spec.Post', {125 extend: 'Ext.data.Model',126 fields: [{127 name: 'userId',128 reference: 'User'129 }]130 });131 Ext.define('spec.User', {132 extend: 'Ext.data.Model'133 });134 expect(schema.hasAssociations(spec.User)).toBe(true);135 expect(schema.hasAssociations(spec.Post)).toBe(true);136 });137 });138 describe("many to many", function() {139 afterEach(function() {140 Ext.undefine('spec.User');141 Ext.undefine('spec.Group');142 });143 describe("association on the left", function() {144 it("should have associations when declaring the right first", function() {145 Ext.define('spec.User', {146 extend: 'Ext.data.Model'147 });148 Ext.define('spec.Group', {149 extend: 'Ext.data.Model',150 manyToMany: 'User'151 });152 expect(schema.hasAssociations(spec.User)).toBe(true);153 expect(schema.hasAssociations(spec.Group)).toBe(true);154 });155 it("should have associations when declaring the left first", function() {156 Ext.define('spec.Group', {157 extend: 'Ext.data.Model',158 manyToMany: 'User'159 });160 Ext.define('spec.User', {161 extend: 'Ext.data.Model'162 });163 expect(schema.hasAssociations(spec.User)).toBe(true);164 expect(schema.hasAssociations(spec.Group)).toBe(true);165 });166 });167 describe("association on the right", function() {168 it("should have associations when declaring the right first", function() {169 Ext.define('spec.User', {170 extend: 'Ext.data.Model',171 manyToMany: 'Group'172 });173 Ext.define('spec.Group', {174 extend: 'Ext.data.Model'175 });176 expect(schema.hasAssociations(spec.User)).toBe(true);177 expect(schema.hasAssociations(spec.Group)).toBe(true);178 });179 it("should have associations when declaring the left first", function() {180 Ext.define('spec.Group', {181 extend: 'Ext.data.Model'182 });183 Ext.define('spec.User', {184 extend: 'Ext.data.Model',185 manyToMany: 'Group'186 });187 expect(schema.hasAssociations(spec.User)).toBe(true);188 expect(schema.hasAssociations(spec.Group)).toBe(true);189 });190 });191 });192 });193 194 describe("legacy associations", function() {195 describe('inherited associations', function () {196 beforeEach(function () {197 schema.setNamespace('spec');198 Ext.define('spec.AssociatedModel', {199 extend: 'Ext.data.Model'200 });201 Ext.define('spec.ParentModel', {202 extend: 'Ext.data.Model',203 hasOne: {204 model: 'spec.AssociatedModel',205 getterName: 'getAssocModel',206 setterName: 'setAssocModel',207 name: 'associatedModel',208 associationKey: 'associatedModel',209 foreignKey: 'id'210 }211 });212 Ext.define('spec.ChildModel', {213 extend: 'spec.ParentModel'214 });215 });216 afterEach(function () {217 Ext.undefine('spec.AssociatedModel');218 Ext.undefine('spec.ParentModel');219 Ext.undefine('spec.ChildModel');220 });221 it('should convert the association', function () {222 var associatedModel = spec.ParentModel.associations.associatedModel;223 expect(!associatedModel).toBe(false);224 // See if getter/setter names are respected:225 expect(typeof spec.ParentModel.prototype.getAssocModel).toBe('function');226 expect(typeof spec.ParentModel.prototype.setAssocModel).toBe('function');227 // See if roles are assigned properly:228 expect(associatedModel.cls.$className).toBe('spec.AssociatedModel');229 expect(associatedModel.inverse.cls.$className).toBe('spec.ParentModel');230 });231 it('should decorate AssociatedModel with ParentModel association', function () {232 var association = spec.AssociatedModel.associations.parentModel;233 expect(!association).toBe(false);234 // See if roles are assigned properly:235 expect(association.cls.$className).toBe('spec.ParentModel');236 expect(association.inverse.cls.$className).toBe('spec.AssociatedModel');237 });238 xit('should inherit the association', function () {239 // See https://sencha.jira.com/browse/EXTJSIV-12979240 var associatedModel = spec.ChildModel.associations.associatedModel;241 expect(!associatedModel).toBe(false);242 // See if roles are assigned properly:243 expect(associatedModel.cls.$className).toBe('spec.AssociatedModel');244 expect(associatedModel.inverse.cls.$className).toBe('spec.ChildModel');245 });246 xit('should decorate AssociatedModel with ChildModel association', function () {247 // See https://sencha.jira.com/browse/EXTJSIV-12979248 var association = spec.AssociatedModel.associations.childModel;249 expect(!association).toBe(false);250 // See if roles are assigned properly:251 expect(association.cls.$className).toBe('spec.ChildModel');252 expect(association.inverse.cls.$className).toBe('spec.AssociatedModel');253 });254 });255 });...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!