UNPKG

@theia/core

Version:

Theia is a cloud & desktop IDE framework implemented in TypeScript.

230 lines • 9.8 kB
"use strict"; // ***************************************************************************** // Copyright (C) 2018 TypeFox and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at // http://www.eclipse.org/legal/epl-2.0. // // This Source Code may also be made available under the following Secondary // Licenses when the conditions for such availability set forth in the Eclipse // Public License v. 2.0 are satisfied: GNU General Public License, version 2 // with the GNU Classpath Exception which is available at // https://www.gnu.org/software/classpath/license.html. // // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 // ***************************************************************************** Object.defineProperty(exports, "__esModule", { value: true }); exports.createPreferenceProxy = exports.PreferenceProxyOptions = void 0; /* eslint-disable @typescript-eslint/no-explicit-any */ const common_1 = require("../../common"); const preference_contribution_1 = require("./preference-contribution"); const preference_scope_1 = require("./preference-scope"); const preference_language_override_service_1 = require("./preference-language-override-service"); exports.PreferenceProxyOptions = Symbol('PreferenceProxyOptions'); /** * Creates a preference proxy for typesafe preference handling. * * @param preferences the underlying preference service to use for preference handling. * @param promisedSchema the JSON Schema which describes which preferences are available including types and descriptions. Can be a promise. * @param options configuration options. * * @returns the created preference proxy. * * ### Usage * * 1. Create JSON Schema specifying your preferences * 2. Create Configuration type based on the JSON Schema * 3. Bind the return value of `createPreferenceProxy` to make your preferences available wherever needed. * * See {@link CorePreferences} for an example. * * Note that if `schema` is a Promise, most actions will be no-ops until the promise is resolved. * * @deprecated @since 1.23.0 use `PreferenceProxyFactory` instead. */ function createPreferenceProxy(preferences, promisedSchema, options) { const opts = options || {}; const prefix = opts.prefix || ''; const style = opts.style || 'flat'; const isDeep = style === 'deep' || style === 'both'; const isFlat = style === 'both' || style === 'flat'; let schema; if (preference_contribution_1.PreferenceSchema.is(promisedSchema)) { schema = promisedSchema; } else { promisedSchema.then(s => schema = s); } const onPreferenceChanged = (listener, thisArgs, disposables) => preferences.onPreferencesChanged(changes => { if (schema) { for (const key of Object.keys(changes)) { const e = changes[key]; const overridden = preferences.overriddenPreferenceName(e.preferenceName); const preferenceName = overridden ? overridden.preferenceName : e.preferenceName; if (preferenceName.startsWith(prefix) && (!opts.overrideIdentifier || (overridden === null || overridden === void 0 ? void 0 : overridden.overrideIdentifier) === opts.overrideIdentifier)) { if (schema.properties[preferenceName]) { const { newValue, oldValue } = e; listener({ newValue, oldValue, preferenceName, affects: (resourceUri, overrideIdentifier) => { if (overrideIdentifier !== (overridden === null || overridden === void 0 ? void 0 : overridden.overrideIdentifier)) { return false; } return e.affects(resourceUri); } }); } } } } }, thisArgs, disposables); const unsupportedOperation = (_, __) => { throw new Error('Unsupported operation'); }; const getValue = (arg, defaultValue, resourceUri) => { const preferenceName = preference_language_override_service_1.OverridePreferenceName.is(arg) ? preferences.overridePreferenceName(arg) : arg; return preferences.get(preferenceName, defaultValue, resourceUri || opts.resourceUri); }; const ownKeys = () => { const properties = []; if (schema) { for (const p of Object.keys(schema.properties)) { if (p.startsWith(prefix)) { const idx = p.indexOf('.', prefix.length); if (idx !== -1 && isDeep) { const pre = p.substr(prefix.length, idx - prefix.length); if (properties.indexOf(pre) === -1) { properties.push(pre); } } const prop = p.substr(prefix.length); if (isFlat || prop.indexOf('.') === -1) { properties.push(prop); } } } } return properties; }; const set = (_, property, value) => { if (typeof property !== 'string') { throw new Error(`unexpected property: ${String(property)}`); } if (style === 'deep' && property.indexOf('.') !== -1) { return false; } if (schema) { const fullProperty = prefix ? prefix + property : property; if (schema.properties[fullProperty]) { preferences.set(fullProperty, value, preference_scope_1.PreferenceScope.Default); return true; } const newPrefix = fullProperty + '.'; for (const p of Object.keys(schema.properties)) { if (p.startsWith(newPrefix)) { const subProxy = createPreferenceProxy(preferences, schema, { prefix: newPrefix, resourceUri: opts.resourceUri, overrideIdentifier: opts.overrideIdentifier, style }); for (const k of Object.keys(value)) { subProxy[k] = value[k]; } } } } return false; }; const get = (_, property) => { if (typeof property !== 'string') { throw new Error(`unexpected property: ${String(property)}`); } const fullProperty = prefix ? prefix + property : property; if (schema) { if (isFlat || property.indexOf('.') === -1) { if (schema.properties[fullProperty]) { let value; if (opts.overrideIdentifier) { value = preferences.get(preferences.overridePreferenceName({ overrideIdentifier: opts.overrideIdentifier, preferenceName: fullProperty }), undefined, opts.resourceUri); } if (value === undefined) { value = preferences.get(fullProperty, undefined, opts.resourceUri); } return value; } } } if (property === 'onPreferenceChanged') { return onPreferenceChanged; } if (property === 'dispose') { return () => { }; } if (property === 'ready') { return preferences.ready; } if (property === 'get') { return getValue; } if (property === 'toJSON') { return toJSON(); } if (schema && isDeep) { const newPrefix = fullProperty + '.'; for (const p of Object.keys(schema.properties)) { if (p.startsWith(newPrefix)) { return createPreferenceProxy(preferences, schema, { prefix: newPrefix, resourceUri: opts.resourceUri, overrideIdentifier: opts.overrideIdentifier, style }); } } let value; let parentSegment = fullProperty; const segments = []; do { const index = parentSegment.lastIndexOf('.'); segments.push(parentSegment.substring(index + 1)); parentSegment = parentSegment.substring(0, index); if (parentSegment in schema.properties) { value = get(_, parentSegment); } } while (parentSegment && value === undefined); let segment; while ((0, common_1.isObject)(value) && (segment = segments.pop())) { value = value[segment]; } return segments.length ? undefined : value; } return undefined; }; const toJSON = () => { const result = {}; for (const k of ownKeys()) { result[k] = get(undefined, k); } return result; }; return new Proxy({}, { get, ownKeys, getOwnPropertyDescriptor: (_, property) => { if (ownKeys().indexOf(property) !== -1) { return { enumerable: true, configurable: true }; } return {}; }, set, deleteProperty: unsupportedOperation, defineProperty: unsupportedOperation }); } exports.createPreferenceProxy = createPreferenceProxy; //# sourceMappingURL=preference-proxy.js.map