From 4a0f8505f8f0025c230ef9bcea78fa07cadf5c85 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Sun, 28 Jan 2018 01:45:45 +0100 Subject: [PATCH] some lbryURI updates from lbry-app master --- build/index.js | 1404 +++++++++++++++-------------- src/index.js | 12 +- src/{lbryuri.js => lbryURI.js} | 68 +- src/redux/actions/claims.js | 6 +- src/redux/actions/search.js | 4 +- src/redux/selectors/claims.js | 6 +- src/redux/selectors/navigation.js | 4 +- 7 files changed, 768 insertions(+), 736 deletions(-) rename src/{lbryuri.js => lbryURI.js} (80%) diff --git a/build/index.js b/build/index.js index 0770204..cf644a0 100644 --- a/build/index.js +++ b/build/index.js @@ -70,7 +70,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 13); +/******/ return __webpack_require__(__webpack_require__.s = 15); /******/ }) /************************************************************************/ /******/ ([ @@ -262,13 +262,9 @@ exports.selectActiveHistoryEntry = exports.selectHistoryStack = exports.selectHi var _reselect = __webpack_require__(2); -var _query_params = __webpack_require__(7); +var _lbryURI = __webpack_require__(3); -var _lbryuri = __webpack_require__(4); - -var _lbryuri2 = _interopRequireDefault(_lbryuri); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _query_params = __webpack_require__(8); var selectState = exports.selectState = function selectState(state) { return state.navigation || {}; @@ -368,7 +364,7 @@ var selectPageTitle = exports.selectPageTitle = (0, _reselect.createSelector)(se return __('Developer'); case 'show': { - var parts = [_lbryuri2.default.normalize(params.uri)]; + var parts = [(0, _lbryURI.normalizeURI)(params.uri)]; // If the params has any keys other than "uri" if (Object.keys(params).length > 1) { parts.push((0, _query_params.toQueryString)(Object.assign({}, params, { uri: null }))); @@ -560,7 +556,440 @@ Object.defineProperty(exports, "__esModule", { value: true }); -var _jsonrpc = __webpack_require__(14); +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +exports.parseURI = parseURI; +exports.buildURI = buildURI; +exports.normalizeURI = normalizeURI; +exports.isURIValid = isURIValid; +exports.isNameValid = isNameValid; +exports.isURIClaimable = isURIClaimable; +var channelNameMinLength = 1; +var claimIdMaxLength = 40; + +var regexInvalidURI = exports.regexInvalidURI = /[^A-Za-z0-9-]/g; +var regexAddress = exports.regexAddress = /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; + +/** + * Parses a LBRY name into its component parts. Throws errors with user-friendly + * messages for invalid names. + * + * N.B. that "name" indicates the value in the name position of the URI. For + * claims for channel content, this will actually be the channel name, and + * the content name is in the path (e.g. lbry://@channel/content) + * + * In most situations, you'll want to use the contentName and channelName keys + * and ignore the name key. + * + * Returns a dictionary with keys: + * - name (string): The value in the "name" position in the URI. Note that this + * could be either content name or channel name; see above. + * - path (string, if persent) + * - claimSequence (int, if present) + * - bidPosition (int, if present) + * - claimId (string, if present) + * - isChannel (boolean) + * - contentName (string): For anon claims, the name; for channel claims, the path + * - channelName (string, if present): Channel name without @ + */ +function parseURI(URI) { + var requireProto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + // Break into components. Empty sub-matches are converted to null + var componentsRegex = new RegExp('^((?:lbry://)?)' + // protocol + '([^:$#/]*)' + // name (stops at the first separator or end) + '([:$#]?)([^/]*)' + // modifier separator, modifier (stops at the first path separator or end) + '(/?)(.*)' // path separator, path + ); + + var _componentsRegex$exec = componentsRegex.exec(URI).slice(1).map(function (match) { + return match || null; + }), + _componentsRegex$exec2 = _slicedToArray(_componentsRegex$exec, 6), + proto = _componentsRegex$exec2[0], + name = _componentsRegex$exec2[1], + modSep = _componentsRegex$exec2[2], + modVal = _componentsRegex$exec2[3], + pathSep = _componentsRegex$exec2[4], + path = _componentsRegex$exec2[5]; + + var contentName = void 0; + + // Validate protocol + if (requireProto && !proto) { + throw new Error(__('LBRY URIs must include a protocol prefix (lbry://).')); + } + + // Validate and process name + if (!name) { + throw new Error(__('URI does not include name.')); + } + + var isChannel = name.startsWith('@'); + var channelName = isChannel ? name.slice(1) : name; + + if (isChannel) { + if (!channelName) { + throw new Error(__('No channel name after @.')); + } + + if (channelName.length < channelNameMinLength) { + throw new Error(__('Channel names must be at least %s characters.', channelNameMinLength)); + } + + contentName = path; + } + + var nameBadChars = (channelName || name).match(regexInvalidURI); + if (nameBadChars) { + throw new Error(__('Invalid character %s in name: %s.', nameBadChars.length === 1 ? '' : 's', nameBadChars.join(', '))); + } + + // Validate and process modifier (claim ID, bid position or claim sequence) + var claimId = void 0; + var claimSequence = void 0; + var bidPosition = void 0; + if (modSep) { + if (!modVal) { + throw new Error(__('No modifier provided after separator %s.', modSep)); + } + + if (modSep === '#') { + claimId = modVal; + } else if (modSep === ':') { + claimSequence = modVal; + } else if (modSep === '$') { + bidPosition = modVal; + } + } + + if (claimId && (claimId.length > claimIdMaxLength || !claimId.match(/^[0-9a-f]+$/)) && !claimId.match(/^pending/) // ought to be dropped when savePendingPublish drops hack + ) { + throw new Error(__('Invalid claim ID %s.', claimId)); + } + + if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { + throw new Error(__('Claim sequence must be a number.')); + } + + if (bidPosition && !bidPosition.match(/^-?[1-9][0-9]*$/)) { + throw new Error(__('Bid position must be a number.')); + } + + // Validate and process path + if (path) { + if (!isChannel) { + throw new Error(__('Only channel URIs may have a path.')); + } + + var pathBadChars = path.match(regexInvalidURI); + if (pathBadChars) { + throw new Error(__('Invalid character in path: %s', pathBadChars.join(', '))); + } + + contentName = path; + } else if (pathSep) { + throw new Error(__('No path provided after /')); + } + + return _extends({ + name: name, + path: path, + isChannel: isChannel + }, contentName ? { contentName: contentName } : {}, channelName ? { channelName: channelName } : {}, claimSequence ? { claimSequence: parseInt(claimSequence, 10) } : {}, bidPosition ? { bidPosition: parseInt(bidPosition, 10) } : {}, claimId ? { claimId: claimId } : {}, path ? { path: path } : {}); +} + +/** + * Takes an object in the same format returned by parse() and builds a URI. + * + * The channelName key will accept names with or without the @ prefix. + */ +function buildURI(URIObj) { + var includeProto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var claimId = URIObj.claimId, + claimSequence = URIObj.claimSequence, + bidPosition = URIObj.bidPosition, + contentName = URIObj.contentName, + channelName = URIObj.channelName; + var name = URIObj.name, + path = URIObj.path; + + + if (channelName) { + var channelNameFormatted = channelName.startsWith('@') ? channelName : '@' + channelName; + if (!name) { + name = channelNameFormatted; + } else if (name !== channelNameFormatted) { + throw new Error(__('Received a channel content URI, but name and channelName do not match. "name" represents the value in the name position of the URI (lbry://name...), which for channel content will be the channel name. In most cases, to construct a channel URI you should just pass channelName and contentName.')); + } + } + + if (contentName) { + if (!name) { + name = contentName; + } else if (!path) { + path = contentName; + } + if (path && path !== contentName) { + throw new Error(__('Path and contentName do not match. Only one is required; most likely you wanted contentName.')); + } + } + + return (includeProto ? 'lbry://' : '') + name + (claimId ? '#' + claimId : '') + (claimSequence ? ':' + claimSequence : '') + (bidPosition ? '' + bidPosition : '') + (path ? '/' + path : ''); +} + +/* Takes a parseable LBRY URI and converts it to standard, canonical format */ +function normalizeURI(URI) { + if (URI.match(/pending_claim/)) return URI; + + var _parseURI = parseURI(URI), + name = _parseURI.name, + path = _parseURI.path, + bidPosition = _parseURI.bidPosition, + claimSequence = _parseURI.claimSequence, + claimId = _parseURI.claimId; + + return buildURI({ name: name, path: path, claimSequence: claimSequence, bidPosition: bidPosition, claimId: claimId }); +} + +function isURIValid(URI) { + var parts = void 0; + try { + parts = parseURI(normalizeURI(URI)); + } catch (error) { + return false; + } + return parts && parts.name; +} + +function isNameValid(name) { + var checkCase = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + + var regexp = new RegExp('^[a-z0-9-]+$', checkCase ? '' : 'i'); + return regexp.test(name); +} + +function isURIClaimable(URI) { + var parts = void 0; + try { + parts = parseURI(normalizeURI(URI)); + } catch (error) { + return false; + } + return parts && parts.name && !parts.claimId && !parts.bidPosition && !parts.claimSequence && !parts.isChannel && !parts.path; +} + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.makeSelectIsUriResolving = exports.selectResolvingUris = exports.selectMyChannelClaims = exports.selectFetchingMyChannels = exports.selectMyClaimsOutpoints = exports.selectAllMyClaimsByOutpoint = exports.selectMyClaimsWithoutChannels = exports.selectMyClaims = exports.selectPendingClaims = exports.selectIsFetchingClaimListMine = exports.makeSelectContentTypeForUri = exports.makeSelectTitleForUri = exports.makeSelectMetadataForUri = exports.makeSelectClaimsInChannelForCurrentPage = exports.makeSelectFetchingChannelClaims = exports.selectAllFetchingChannelClaims = exports.makeSelectClaimIsMine = exports.selectMyActiveClaims = exports.selectAbandoningIds = exports.selectMyClaimsRaw = exports.makeSelectClaimForUri = exports.selectAllClaimsByChannel = exports.selectClaimsByUri = exports.selectClaimsById = undefined; + +var _lbryURI = __webpack_require__(3); + +var _navigation = __webpack_require__(1); + +var _reselect = __webpack_require__(2); + +function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var selectState = function selectState(state) { + return state.claims || {}; +}; + +var selectClaimsById = exports.selectClaimsById = (0, _reselect.createSelector)(selectState, function (state) { + return state.byId || {}; +}); + +var selectClaimsByUri = exports.selectClaimsByUri = (0, _reselect.createSelector)(selectState, selectClaimsById, function (state, byId) { + var byUri = state.claimsByUri || {}; + var claims = {}; + + Object.keys(byUri).forEach(function (uri) { + var claimId = byUri[uri]; + + // NOTE returning a null claim allows us to differentiate between an + // undefined (never fetched claim) and one which just doesn't exist. Not + // the cleanest solution but couldn't think of anything better right now + if (claimId === null) { + claims[uri] = null; + } else { + claims[uri] = byId[claimId]; + } + }); + + return claims; +}); + +var selectAllClaimsByChannel = exports.selectAllClaimsByChannel = (0, _reselect.createSelector)(selectState, function (state) { + return state.claimsByChannel || {}; +}); + +var makeSelectClaimForUri = exports.makeSelectClaimForUri = function makeSelectClaimForUri(uri) { + return (0, _reselect.createSelector)(selectClaimsByUri, function (claims) { + return claims && claims[(0, _lbryURI.normalizeURI)(uri)]; + }); +}; + +var selectMyClaimsRaw = exports.selectMyClaimsRaw = (0, _reselect.createSelector)(selectState, function (state) { + return state.myClaims; +}); + +var selectAbandoningIds = exports.selectAbandoningIds = (0, _reselect.createSelector)(selectState, function (state) { + return Object.keys(state.abandoningById || {}); +}); + +var selectMyActiveClaims = exports.selectMyActiveClaims = (0, _reselect.createSelector)(selectMyClaimsRaw, selectAbandoningIds, function (claims, abandoningIds) { + return new Set(claims && claims.map(function (claim) { + return claim.claim_id; + }).filter(function (claimId) { + return Object.keys(abandoningIds).indexOf(claimId) === -1; + })); +}); + +var makeSelectClaimIsMine = exports.makeSelectClaimIsMine = function makeSelectClaimIsMine(rawUri) { + var uri = (0, _lbryURI.normalizeURI)(rawUri); + return (0, _reselect.createSelector)(selectClaimsByUri, selectMyActiveClaims, function (claims, myClaims) { + return claims && claims[uri] && claims[uri].claim_id && myClaims.has(claims[uri].claim_id); + }); +}; + +var selectAllFetchingChannelClaims = exports.selectAllFetchingChannelClaims = (0, _reselect.createSelector)(selectState, function (state) { + return state.fetchingChannelClaims || {}; +}); + +var makeSelectFetchingChannelClaims = exports.makeSelectFetchingChannelClaims = function makeSelectFetchingChannelClaims(uri) { + return (0, _reselect.createSelector)(selectAllFetchingChannelClaims, function (fetching) { + return fetching && fetching[uri]; + }); +}; + +var makeSelectClaimsInChannelForCurrentPage = exports.makeSelectClaimsInChannelForCurrentPage = function makeSelectClaimsInChannelForCurrentPage(uri) { + var pageSelector = (0, _navigation.makeSelectCurrentParam)('page'); + + return (0, _reselect.createSelector)(selectClaimsById, selectAllClaimsByChannel, pageSelector, function (byId, allClaims, page) { + var byChannel = allClaims[uri] || {}; + var claimIds = byChannel[page || 1]; + + if (!claimIds) return claimIds; + + return claimIds.map(function (claimId) { + return byId[claimId]; + }); + }); +}; + +var makeSelectMetadataForUri = exports.makeSelectMetadataForUri = function makeSelectMetadataForUri(uri) { + return (0, _reselect.createSelector)(makeSelectClaimForUri(uri), function (claim) { + var metadata = claim && claim.value && claim.value.stream && claim.value.stream.metadata; + + return metadata || (claim === undefined ? undefined : null); + }); +}; + +var makeSelectTitleForUri = exports.makeSelectTitleForUri = function makeSelectTitleForUri(uri) { + return (0, _reselect.createSelector)(makeSelectMetadataForUri(uri), function (metadata) { + return metadata && metadata.title; + }); +}; + +var makeSelectContentTypeForUri = exports.makeSelectContentTypeForUri = function makeSelectContentTypeForUri(uri) { + return (0, _reselect.createSelector)(makeSelectClaimForUri(uri), function (claim) { + var source = claim && claim.value && claim.value.stream && claim.value.stream.source; + return source ? source.contentType : undefined; + }); +}; + +var selectIsFetchingClaimListMine = exports.selectIsFetchingClaimListMine = (0, _reselect.createSelector)(selectState, function (state) { + return state.isFetchingClaimListMine; +}); + +var selectPendingClaims = exports.selectPendingClaims = (0, _reselect.createSelector)(selectState, function (state) { + return Object.values(state.pendingById || {}); +}); + +var selectMyClaims = exports.selectMyClaims = (0, _reselect.createSelector)(selectMyActiveClaims, selectClaimsById, selectAbandoningIds, selectPendingClaims, function (myClaimIds, byId, abandoningIds, pendingClaims) { + var claims = []; + + myClaimIds.forEach(function (id) { + var claim = byId[id]; + + if (claim && abandoningIds.indexOf(id) === -1) claims.push(claim); + }); + + return [].concat(claims, _toConsumableArray(pendingClaims)); +}); + +var selectMyClaimsWithoutChannels = exports.selectMyClaimsWithoutChannels = (0, _reselect.createSelector)(selectMyClaims, function (myClaims) { + return myClaims.filter(function (claim) { + return !claim.name.match(/^@/); + }); +}); + +var selectAllMyClaimsByOutpoint = exports.selectAllMyClaimsByOutpoint = (0, _reselect.createSelector)(selectMyClaimsRaw, function (claims) { + return new Set(claims && claims.length ? claims.map(function (claim) { + return claim.txid + ':' + claim.nout; + }) : null); +}); + +var selectMyClaimsOutpoints = exports.selectMyClaimsOutpoints = (0, _reselect.createSelector)(selectMyClaims, function (myClaims) { + var outpoints = []; + + myClaims.forEach(function (claim) { + return outpoints.push(claim.txid + ':' + claim.nout); + }); + + return outpoints; +}); + +var selectFetchingMyChannels = exports.selectFetchingMyChannels = (0, _reselect.createSelector)(selectState, function (state) { + return state.fetchingMyChannels; +}); + +var selectMyChannelClaims = exports.selectMyChannelClaims = (0, _reselect.createSelector)(selectState, selectClaimsById, function (state, byId) { + var ids = state.myChannelClaims || []; + var claims = []; + + ids.forEach(function (id) { + if (byId[id]) { + // I'm not sure why this check is necessary, but it ought to be a quick fix for https://github.com/lbryio/lbry-app/issues/544 + claims.push(byId[id]); + } + }); + + return claims; +}); + +var selectResolvingUris = exports.selectResolvingUris = (0, _reselect.createSelector)(selectState, function (state) { + return state.resolvingUris || []; +}); + +var makeSelectIsUriResolving = exports.makeSelectIsUriResolving = function makeSelectIsUriResolving(uri) { + return (0, _reselect.createSelector)(selectResolvingUris, function (resolvingUris) { + return resolvingUris && resolvingUris.indexOf(uri) !== -1; + }); +}; + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _jsonrpc = __webpack_require__(16); var _jsonrpc2 = _interopRequireDefault(_jsonrpc); @@ -690,6 +1119,7 @@ Lbry.connect = function () { // Check every half second to see if the daemon is accepting connections function checkDaemonStarted() { tryNum += 1; + // eslint-disable-next-line no-use-before-define lbryProxy.status().then(resolve).catch(function () { if (tryNum <= CHECK_DAEMON_STARTED_TRY_NUMBER) { setTimeout(checkDaemonStarted, tryNum < 50 ? 400 : 1000); @@ -728,6 +1158,7 @@ Lbry.publishDeprecated = function (params, fileListedCallback, publishedCallback } }, 2000, { once: true }); + // eslint-disable-next-line no-use-before-define lbryProxy.publish(params).then(function (result) { if (returnPendingTimeout) clearTimeout(returnPendingTimeout); publishedCallback(result); @@ -859,445 +1290,6 @@ var lbryProxy = new Proxy(Lbry, { exports.default = lbryProxy; -/***/ }), -/* 4 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -var CHANNEL_NAME_MIN_LEN = 1; -var CLAIM_ID_MAX_LEN = 40; - -var Lbryuri = {}; - -Lbryuri.REGEXP_INVALID_URI = /[^A-Za-z0-9-]/g; -Lbryuri.REGEXP_ADDRESS = /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; - -/** - * Parses a LBRY name into its component parts. Throws errors with user-friendly - * messages for invalid names. - * - * N.B. that "name" indicates the value in the name position of the URI. For - * claims for channel content, this will actually be the channel name, and - * the content name is in the path (e.g. lbry://@channel/content) - * - * In most situations, you'll want to use the contentName and channelName keys - * and ignore the name key. - * - * Returns a dictionary with keys: - * - name (string): The value in the "name" position in the URI. Note that this - * could be either content name or channel name; see above. - * - path (string, if persent) - * - claimSequence (int, if present) - * - bidPosition (int, if present) - * - claimId (string, if present) - * - isChannel (boolean) - * - contentName (string): For anon claims, the name; for channel claims, the path - * - channelName (string, if present): Channel name without @ - */ -Lbryuri.parse = function (uri) { - var requireProto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - // Break into components. Empty sub-matches are converted to null - var componentsRegex = new RegExp('^((?:lbry://)?)' + // protocol - '([^:$#/]*)' + // name (stops at the first separator or end) - '([:$#]?)([^/]*)' + // modifier separator, modifier (stops at the first path separator or end) - '(/?)(.*)' // path separator, path - ); - - var _componentsRegex$exec = componentsRegex.exec(uri).slice(1).map(function (match) { - return match || null; - }), - _componentsRegex$exec2 = _slicedToArray(_componentsRegex$exec, 6), - proto = _componentsRegex$exec2[0], - name = _componentsRegex$exec2[1], - modSep = _componentsRegex$exec2[2], - modVal = _componentsRegex$exec2[3], - pathSep = _componentsRegex$exec2[4], - path = _componentsRegex$exec2[5]; - - var contentName = void 0; - - // Validate protocol - if (requireProto && !proto) { - throw new Error(__('LBRY URIs must include a protocol prefix (lbry://).')); - } - - // Validate and process name - if (!name) { - throw new Error(__('URI does not include name.')); - } - - var isChannel = name.startsWith('@'); - var channelName = isChannel ? name.slice(1) : name; - - if (isChannel) { - if (!channelName) { - throw new Error(__('No channel name after @.')); - } - - if (channelName.length < CHANNEL_NAME_MIN_LEN) { - throw new Error(__('Channel names must be at least %s characters.', CHANNEL_NAME_MIN_LEN)); - } - - contentName = path; - } - - var nameBadChars = (channelName || name).match(Lbryuri.REGEXP_INVALID_URI); - if (nameBadChars) { - throw new Error(__('Invalid character %s in name: %s.', nameBadChars.length === 1 ? '' : 's', nameBadChars.join(', '))); - } - - // Validate and process modifier (claim ID, bid position or claim sequence) - var claimId = void 0; - var claimSequence = void 0; - var bidPosition = void 0; - if (modSep) { - if (!modVal) { - throw new Error(__('No modifier provided after separator %s.', modSep)); - } - - if (modSep === '#') { - claimId = modVal; - } else if (modSep === ':') { - claimSequence = modVal; - } else if (modSep === '$') { - bidPosition = modVal; - } - } - - if (claimId && (claimId.length > CLAIM_ID_MAX_LEN || !claimId.match(/^[0-9a-f]+$/)) && !claimId.match(/^pending/) // ought to be dropped when savePendingPublish drops hack - ) { - throw new Error(__('Invalid claim ID %s.', claimId)); - } - - if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__('Claim sequence must be a number.')); - } - - if (bidPosition && !bidPosition.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__('Bid position must be a number.')); - } - - // Validate and process path - if (path) { - if (!isChannel) { - throw new Error(__('Only channel URIs may have a path.')); - } - - var pathBadChars = path.match(Lbryuri.REGEXP_INVALID_URI); - if (pathBadChars) { - throw new Error(__('Invalid character in path: %s', pathBadChars.join(', '))); - } - - contentName = path; - } else if (pathSep) { - throw new Error(__('No path provided after /')); - } - - return _extends({ - name: name, - path: path, - isChannel: isChannel - }, contentName ? { contentName: contentName } : {}, channelName ? { channelName: channelName } : {}, claimSequence ? { claimSequence: parseInt(claimSequence, 10) } : {}, bidPosition ? { bidPosition: parseInt(bidPosition, 10) } : {}, claimId ? { claimId: claimId } : {}, path ? { path: path } : {}); -}; - -/** - * Takes an object in the same format returned by lbryuri.parse() and builds a URI. - * - * The channelName key will accept names with or without the @ prefix. - */ -Lbryuri.build = function (uriObj) { - var includeProto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - var claimId = uriObj.claimId, - claimSequence = uriObj.claimSequence, - bidPosition = uriObj.bidPosition, - contentName = uriObj.contentName, - channelName = uriObj.channelName; - var name = uriObj.name, - path = uriObj.path; - - - if (channelName) { - var channelNameFormatted = channelName.startsWith('@') ? channelName : '@' + channelName; - if (!name) { - name = channelNameFormatted; - } else if (name !== channelNameFormatted) { - throw new Error(__('Received a channel content URI, but name and channelName do not match. "name" represents the value in the name position of the URI (lbry://name...), which for channel content will be the channel name. In most cases, to construct a channel URI you should just pass channelName and contentName.')); - } - } - - if (contentName) { - if (!name) { - name = contentName; - } else if (!path) { - path = contentName; - } - if (path && path !== contentName) { - throw new Error(__('Path and contentName do not match. Only one is required; most likely you wanted contentName.')); - } - } - - return (includeProto ? 'lbry://' : '') + name + (claimId ? '#' + claimId : '') + (claimSequence ? ':' + claimSequence : '') + (bidPosition ? '' + bidPosition : '') + (path ? '/' + path : ''); -}; - -/* Takes a parseable LBRY URI and converts it to standard, canonical format (currently this just - * consists of adding the lbry:// prefix if needed) */ -Lbryuri.normalize = function (uri) { - if (uri.match(/pending_claim/)) return uri; - - var _Lbryuri$parse = Lbryuri.parse(uri), - name = _Lbryuri$parse.name, - path = _Lbryuri$parse.path, - bidPosition = _Lbryuri$parse.bidPosition, - claimSequence = _Lbryuri$parse.claimSequence, - claimId = _Lbryuri$parse.claimId; - - return Lbryuri.build({ name: name, path: path, claimSequence: claimSequence, bidPosition: bidPosition, claimId: claimId }); -}; - -Lbryuri.isValid = function (uri) { - var parts = void 0; - try { - parts = Lbryuri.parse(Lbryuri.normalize(uri)); - } catch (error) { - return false; - } - return parts && parts.name; -}; - -Lbryuri.isValidName = function (name) { - var checkCase = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - - var regexp = new RegExp('^[a-z0-9-]+$', checkCase ? '' : 'i'); - return regexp.test(name); -}; - -Lbryuri.isClaimable = function (uri) { - var parts = void 0; - try { - parts = Lbryuri.parse(Lbryuri.normalize(uri)); - } catch (error) { - return false; - } - return parts && parts.name && !parts.claimId && !parts.bidPosition && !parts.claimSequence && !parts.isChannel && !parts.path; -}; - -if (window) { - window.lbryuri = Lbryuri; -} -exports.default = Lbryuri; - -/***/ }), -/* 5 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.makeSelectIsUriResolving = exports.selectResolvingUris = exports.selectMyChannelClaims = exports.selectFetchingMyChannels = exports.selectMyClaimsOutpoints = exports.selectAllMyClaimsByOutpoint = exports.selectMyClaimsWithoutChannels = exports.selectMyClaims = exports.selectPendingClaims = exports.selectIsFetchingClaimListMine = exports.makeSelectContentTypeForUri = exports.makeSelectTitleForUri = exports.makeSelectMetadataForUri = exports.makeSelectClaimsInChannelForCurrentPage = exports.makeSelectFetchingChannelClaims = exports.selectAllFetchingChannelClaims = exports.makeSelectClaimIsMine = exports.selectMyActiveClaims = exports.selectAbandoningIds = exports.selectMyClaimsRaw = exports.makeSelectClaimForUri = exports.selectAllClaimsByChannel = exports.selectClaimsByUri = exports.selectClaimsById = undefined; - -var _lbryuri = __webpack_require__(4); - -var _lbryuri2 = _interopRequireDefault(_lbryuri); - -var _navigation = __webpack_require__(1); - -var _reselect = __webpack_require__(2); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } - -var selectState = function selectState(state) { - return state.claims || {}; -}; - -var selectClaimsById = exports.selectClaimsById = (0, _reselect.createSelector)(selectState, function (state) { - return state.byId || {}; -}); - -var selectClaimsByUri = exports.selectClaimsByUri = (0, _reselect.createSelector)(selectState, selectClaimsById, function (state, byId) { - var byUri = state.claimsByUri || {}; - var claims = {}; - - Object.keys(byUri).forEach(function (uri) { - var claimId = byUri[uri]; - - // NOTE returning a null claim allows us to differentiate between an - // undefined (never fetched claim) and one which just doesn't exist. Not - // the cleanest solution but couldn't think of anything better right now - if (claimId === null) { - claims[uri] = null; - } else { - claims[uri] = byId[claimId]; - } - }); - - return claims; -}); - -var selectAllClaimsByChannel = exports.selectAllClaimsByChannel = (0, _reselect.createSelector)(selectState, function (state) { - return state.claimsByChannel || {}; -}); - -var makeSelectClaimForUri = exports.makeSelectClaimForUri = function makeSelectClaimForUri(uri) { - return (0, _reselect.createSelector)(selectClaimsByUri, function (claims) { - return claims && claims[_lbryuri2.default.normalize(uri)]; - }); -}; - -var selectMyClaimsRaw = exports.selectMyClaimsRaw = (0, _reselect.createSelector)(selectState, function (state) { - return state.myClaims; -}); - -var selectAbandoningIds = exports.selectAbandoningIds = (0, _reselect.createSelector)(selectState, function (state) { - return Object.keys(state.abandoningById || {}); -}); - -var selectMyActiveClaims = exports.selectMyActiveClaims = (0, _reselect.createSelector)(selectMyClaimsRaw, selectAbandoningIds, function (claims, abandoningIds) { - return new Set(claims && claims.map(function (claim) { - return claim.claim_id; - }).filter(function (claimId) { - return Object.keys(abandoningIds).indexOf(claimId) === -1; - })); -}); - -var makeSelectClaimIsMine = exports.makeSelectClaimIsMine = function makeSelectClaimIsMine(rawUri) { - var uri = _lbryuri2.default.normalize(rawUri); - return (0, _reselect.createSelector)(selectClaimsByUri, selectMyActiveClaims, function (claims, myClaims) { - return claims && claims[uri] && claims[uri].claim_id && myClaims.has(claims[uri].claim_id); - }); -}; - -var selectAllFetchingChannelClaims = exports.selectAllFetchingChannelClaims = (0, _reselect.createSelector)(selectState, function (state) { - return state.fetchingChannelClaims || {}; -}); - -var makeSelectFetchingChannelClaims = exports.makeSelectFetchingChannelClaims = function makeSelectFetchingChannelClaims(uri) { - return (0, _reselect.createSelector)(selectAllFetchingChannelClaims, function (fetching) { - return fetching && fetching[uri]; - }); -}; - -var makeSelectClaimsInChannelForCurrentPage = exports.makeSelectClaimsInChannelForCurrentPage = function makeSelectClaimsInChannelForCurrentPage(uri) { - var pageSelector = (0, _navigation.makeSelectCurrentParam)('page'); - - return (0, _reselect.createSelector)(selectClaimsById, selectAllClaimsByChannel, pageSelector, function (byId, allClaims, page) { - var byChannel = allClaims[uri] || {}; - var claimIds = byChannel[page || 1]; - - if (!claimIds) return claimIds; - - return claimIds.map(function (claimId) { - return byId[claimId]; - }); - }); -}; - -var makeSelectMetadataForUri = exports.makeSelectMetadataForUri = function makeSelectMetadataForUri(uri) { - return (0, _reselect.createSelector)(makeSelectClaimForUri(uri), function (claim) { - var metadata = claim && claim.value && claim.value.stream && claim.value.stream.metadata; - - return metadata || (claim === undefined ? undefined : null); - }); -}; - -var makeSelectTitleForUri = exports.makeSelectTitleForUri = function makeSelectTitleForUri(uri) { - return (0, _reselect.createSelector)(makeSelectMetadataForUri(uri), function (metadata) { - return metadata && metadata.title; - }); -}; - -var makeSelectContentTypeForUri = exports.makeSelectContentTypeForUri = function makeSelectContentTypeForUri(uri) { - return (0, _reselect.createSelector)(makeSelectClaimForUri(uri), function (claim) { - var source = claim && claim.value && claim.value.stream && claim.value.stream.source; - return source ? source.contentType : undefined; - }); -}; - -var selectIsFetchingClaimListMine = exports.selectIsFetchingClaimListMine = (0, _reselect.createSelector)(selectState, function (state) { - return state.isFetchingClaimListMine; -}); - -var selectPendingClaims = exports.selectPendingClaims = (0, _reselect.createSelector)(selectState, function (state) { - return Object.values(state.pendingById || {}); -}); - -var selectMyClaims = exports.selectMyClaims = (0, _reselect.createSelector)(selectMyActiveClaims, selectClaimsById, selectAbandoningIds, selectPendingClaims, function (myClaimIds, byId, abandoningIds, pendingClaims) { - var claims = []; - - myClaimIds.forEach(function (id) { - var claim = byId[id]; - - if (claim && abandoningIds.indexOf(id) === -1) claims.push(claim); - }); - - return [].concat(claims, _toConsumableArray(pendingClaims)); -}); - -var selectMyClaimsWithoutChannels = exports.selectMyClaimsWithoutChannels = (0, _reselect.createSelector)(selectMyClaims, function (myClaims) { - return myClaims.filter(function (claim) { - return !claim.name.match(/^@/); - }); -}); - -var selectAllMyClaimsByOutpoint = exports.selectAllMyClaimsByOutpoint = (0, _reselect.createSelector)(selectMyClaimsRaw, function (claims) { - return new Set(claims && claims.length ? claims.map(function (claim) { - return claim.txid + ':' + claim.nout; - }) : null); -}); - -var selectMyClaimsOutpoints = exports.selectMyClaimsOutpoints = (0, _reselect.createSelector)(selectMyClaims, function (myClaims) { - var outpoints = []; - - myClaims.forEach(function (claim) { - return outpoints.push(claim.txid + ':' + claim.nout); - }); - - return outpoints; -}); - -var selectFetchingMyChannels = exports.selectFetchingMyChannels = (0, _reselect.createSelector)(selectState, function (state) { - return state.fetchingMyChannels; -}); - -var selectMyChannelClaims = exports.selectMyChannelClaims = (0, _reselect.createSelector)(selectState, selectClaimsById, function (state, byId) { - var ids = state.myChannelClaims || []; - var claims = []; - - ids.forEach(function (id) { - if (byId[id]) { - // I'm not sure why this check is necessary, but it ought to be a quick fix for https://github.com/lbryio/lbry-app/issues/544 - claims.push(byId[id]); - } - }); - - return claims; -}); - -var selectResolvingUris = exports.selectResolvingUris = (0, _reselect.createSelector)(selectState, function (state) { - return state.resolvingUris || []; -}); - -var makeSelectIsUriResolving = exports.makeSelectIsUriResolving = function makeSelectIsUriResolving(uri) { - return (0, _reselect.createSelector)(selectResolvingUris, function (resolvingUris) { - return resolvingUris && resolvingUris.indexOf(uri) !== -1; - }); -}; - /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { @@ -1305,6 +1297,51 @@ var makeSelectIsUriResolving = exports.makeSelectIsUriResolving = function makeS "use strict"; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.doOpenModal = doOpenModal; +exports.doCloseModal = doCloseModal; +exports.doShowSnackBar = doShowSnackBar; + +var _action_types = __webpack_require__(0); + +var ACTIONS = _interopRequireWildcard(_action_types); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function doOpenModal(modal) { + var modalProps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + return { + type: ACTIONS.OPEN_MODAL, + data: { + modal: modal, + modalProps: modalProps + } + }; +} + +function doCloseModal() { + return { + type: ACTIONS.CLOSE_MODAL + }; +} + +function doShowSnackBar(data) { + return { + type: ACTIONS.SHOW_SNACKBAR, + data: data + }; +} + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + Object.defineProperty(exports, "__esModule", { value: true }); @@ -1320,15 +1357,19 @@ var _action_types = __webpack_require__(0); var ACTIONS = _interopRequireWildcard(_action_types); -var _lbry = __webpack_require__(3); +var _modal_types = __webpack_require__(10); + +var MODALS = _interopRequireWildcard(_modal_types); + +var _lbry = __webpack_require__(5); var _lbry2 = _interopRequireDefault(_lbry); -var _lbryuri = __webpack_require__(4); +var _lbryURI = __webpack_require__(3); -var _lbryuri2 = _interopRequireDefault(_lbryuri); +var _app = __webpack_require__(6); -var _claims = __webpack_require__(5); +var _claims = __webpack_require__(4); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -1336,7 +1377,7 @@ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; function doResolveUris(uris) { return function (dispatch, getState) { - var normalizedUris = uris.map(_lbryuri2.default.normalize); + var normalizedUris = uris.map(_lbryURI.normalizeURI); var state = getState(); // Filter out URIs that are already resolving @@ -1407,7 +1448,7 @@ function doFetchClaimListMine() { function doAbandonClaim(txid, nout) { return function (dispatch, getState) { var state = getState(); - var myClaims = selectMyClaimsRaw(state); + var myClaims = (0, _claims.selectMyClaimsRaw)(state); var _myClaims$find = myClaims.find(function (claim) { return claim.txid === txid && claim.nout === nout; @@ -1423,7 +1464,7 @@ function doAbandonClaim(txid, nout) { }); var errorCallback = function errorCallback() { - dispatch(doOpenModal(MODALS.TRANSACTION_FAILED)); + dispatch((0, _app.doOpenModal)(MODALS.TRANSACTION_FAILED)); }; var successCallback = function successCallback(results) { @@ -1434,10 +1475,10 @@ function doAbandonClaim(txid, nout) { claimId: claimId } }); - dispatch(doResolveUri(_lbryuri2.default.build({ name: name, claimId: claimId }))); + dispatch(doResolveUri((0, _lbryURI.buildURI)({ name: name, claimId: claimId }))); dispatch(doFetchClaimListMine()); } else { - dispatch(doOpenModal(MODALS.TRANSACTION_FAILED)); + dispatch((0, _app.doOpenModal)(MODALS.TRANSACTION_FAILED)); } }; @@ -1449,7 +1490,7 @@ function doAbandonClaim(txid, nout) { } /***/ }), -/* 7 */ +/* 8 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -1494,7 +1535,7 @@ function toQueryString(params) { } /***/ }), -/* 8 */ +/* 9 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -1516,7 +1557,7 @@ var ACTIONS = _interopRequireWildcard(_action_types); var _navigation = __webpack_require__(1); -var _query_params = __webpack_require__(7); +var _query_params = __webpack_require__(8); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } @@ -1593,7 +1634,7 @@ function doRecordScroll(scroll) { } /***/ }), -/* 9 */ +/* 10 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -1602,43 +1643,130 @@ function doRecordScroll(scroll) { Object.defineProperty(exports, "__esModule", { value: true }); -exports.doOpenModal = doOpenModal; -exports.doCloseModal = doCloseModal; -exports.doShowSnackBar = doShowSnackBar; - -var _action_types = __webpack_require__(0); - -var ACTIONS = _interopRequireWildcard(_action_types); - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } - -function doOpenModal(modal) { - var modalProps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - return { - type: ACTIONS.OPEN_MODAL, - data: { - modal: modal, - modalProps: modalProps - } - }; -} - -function doCloseModal() { - return { - type: ACTIONS.CLOSE_MODAL - }; -} - -function doShowSnackBar(data) { - return { - type: ACTIONS.SHOW_SNACKBAR, - data: data - }; -} +var CONFIRM_FILE_REMOVE = exports.CONFIRM_FILE_REMOVE = 'confirmFileRemove'; +var INCOMPATIBLE_DAEMON = exports.INCOMPATIBLE_DAEMON = 'incompatibleDaemon'; +var FILE_TIMEOUT = exports.FILE_TIMEOUT = 'file_timeout'; +var DOWNLOADING = exports.DOWNLOADING = 'downloading'; +var ERROR = exports.ERROR = 'error'; +var INSUFFICIENT_CREDITS = exports.INSUFFICIENT_CREDITS = 'insufficient_credits'; +var UPGRADE = exports.UPGRADE = 'upgrade'; +var WELCOME = exports.WELCOME = 'welcome'; +var EMAIL_COLLECTION = exports.EMAIL_COLLECTION = 'email_collection'; +var FIRST_REWARD = exports.FIRST_REWARD = 'first_reward'; +var AUTHENTICATION_FAILURE = exports.AUTHENTICATION_FAILURE = 'auth_failure'; +var TRANSACTION_FAILED = exports.TRANSACTION_FAILED = 'transaction_failed'; +var REWARD_APPROVAL_REQUIRED = exports.REWARD_APPROVAL_REQUIRED = 'reward_approval_required'; +var AFFIRM_PURCHASE = exports.AFFIRM_PURCHASE = 'affirm_purchase'; +var CONFIRM_CLAIM_REVOKE = exports.CONFIRM_CLAIM_REVOKE = 'confirmClaimRevoke'; /***/ }), -/* 10 */ +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(process) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +var _querystring = __webpack_require__(19); + +var _querystring2 = _interopRequireDefault(_querystring); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var Lbryapi = { + enabled: true, + exchangePromise: null, + exchangeLastFetched: null +}; + +var CONNECTION_STRING = process.env.LBRY_APP_API_URL ? process.env.LBRY_APP_API_URL.replace(/\/*$/, '/') // exactly one slash at the end +: 'https://api.lbry.io/'; + +var EXCHANGE_RATE_TIMEOUT = 20 * 60 * 1000; + +Lbryapi.getExchangeRates = function () { + if (!Lbryapi.exchangeLastFetched || Date.now() - Lbryapi.exchangeLastFetched > EXCHANGE_RATE_TIMEOUT) { + Lbryapi.exchangePromise = new Promise(function (resolve, reject) { + Lbryapi.call('lbc', 'exchange_rate', {}, 'get', true).then(function (_ref) { + var LBC_USD = _ref.lbc_usd, + LBC_BTC = _ref.lbc_btc, + BTC_USD = _ref.btc_usd; + + var rates = { LBC_USD: LBC_USD, LBC_BTC: LBC_BTC, BTC_USD: BTC_USD }; + resolve(rates); + }).catch(reject); + }); + Lbryapi.exchangeLastFetched = Date.now(); + } + return Lbryapi.exchangePromise; +}; + +Lbryapi.call = function (resource, action) { + var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var method = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'get'; + + if (!Lbryapi.enabled) { + return Promise.reject(new Error(__('LBRY internal API is disabled'))); + } + + if (!(method === 'get' || method === 'post')) { + return Promise.reject(new Error(__('Invalid method'))); + } + + function checkAndParse(response) { + if (response.status >= 200 && response.status < 300) { + return response.json(); + } + return response.json().then(function (json) { + var error = void 0; + if (json.error) { + error = new Error(json.error); + } else { + error = new Error('Unknown API error signature'); + } + error.response = response; // This is primarily a hack used in actions/user.js + return Promise.reject(error); + }); + } + + function makeRequest(url, options) { + return fetch(url, options).then(checkAndParse); + } + + var fullParams = _extends({}, params); + var qs = _querystring2.default.stringify(fullParams); + var url = '' + CONNECTION_STRING + resource + '/' + action + '?' + qs; + + var options = { + method: 'GET' + }; + + if (method === 'post') { + options = { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + }, + body: qs + }; + url = '' + CONNECTION_STRING + resource + '/' + action; + } + + return makeRequest(url, options).then(function (response) { + return response.data; + }); +}; + +exports.default = Lbryapi; +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(18))) + +/***/ }), +/* 12 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -1649,7 +1777,7 @@ Object.defineProperty(exports, "__esModule", { }); exports.selectTotalDownloadProgress = exports.selectDownloadingFileInfos = exports.selectFileInfosDownloaded = exports.makeSelectLoadingForUri = exports.selectUrisLoading = exports.makeSelectDownloadingForUri = exports.selectDownloadingByOutpoint = exports.makeSelectFileInfoForUri = exports.selectIsFetchingFileListDownloadedOrPublished = exports.selectIsFetchingFileList = exports.selectFileInfosByOutpoint = exports.selectState = undefined; -var _claims = __webpack_require__(5); +var _claims = __webpack_require__(4); var _reselect = __webpack_require__(2); @@ -1747,7 +1875,7 @@ var selectTotalDownloadProgress = exports.selectTotalDownloadProgress = (0, _res }); /***/ }), -/* 11 */ +/* 13 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -1770,7 +1898,7 @@ function batchActions() { } /***/ }), -/* 12 */ +/* 14 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -1906,7 +2034,7 @@ var makeSelectBlockDate = exports.makeSelectBlockDate = function makeSelectBlock }; /***/ }), -/* 13 */ +/* 15 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -1915,10 +2043,55 @@ var makeSelectBlockDate = exports.makeSelectBlockDate = function makeSelectBlock Object.defineProperty(exports, "__esModule", { value: true }); -exports.selectBlocks = exports.selectDraftTransactionError = exports.selectDraftTransactionAddress = exports.selectDraftTransactionAmount = exports.selectDraftTransaction = exports.selectGettingNewAddress = exports.selectReceiveAddress = exports.selectIsSendingSupport = exports.selectIsFetchingTransactions = exports.selectHasTransactions = exports.selectRecentTransactions = exports.selectTransactionItems = undefined; -exports.selectTransactionsById = exports.selectBalance = exports.makeSelectBlockDate = exports.selectWunderBarIcon = exports.selectWunderBarAddress = exports.selectSearchUrisByQuery = exports.selectIsSearching = exports.selectSearchQuery = exports.makeSelectSearchUris = exports.selectActiveHistoryEntry = exports.selectHistoryStack = exports.selectHistoryIndex = exports.selectIsForwardDisabled = exports.selectIsBackDisabled = exports.selectPathAfterAuth = exports.selectPageTitle = exports.selectHeaderLinks = exports.selectCurrentParams = exports.selectCurrentPage = exports.selectCurrentPath = exports.makeSelectCurrentParam = exports.computePageFromPath = exports.selectTotalDownloadProgress = exports.selectDownloadingFileInfos = exports.selectFileInfosDownloaded = exports.selectUrisLoading = exports.selectDownloadingByOutpoint = exports.selectIsFetchingFileListDownloadedOrPublished = exports.selectIsFetchingFileList = exports.selectFileInfosByOutpoint = exports.makeSelectLoadingForUri = exports.makeSelectDownloadingForUri = exports.makeSelectFileInfoForUri = exports.selectFetchingCostInfo = exports.selectCostForCurrentPageUri = exports.selectAllCostInfoByUri = exports.makeSelectCostInfoForUri = exports.makeSelectFetchingCostInfoForUri = exports.selectResolvingUris = exports.selectMyChannelClaims = exports.selectFetchingMyChannels = exports.selectMyClaimsOutpoints = exports.selectAllMyClaimsByOutpoint = exports.selectMyClaimsWithoutChannels = exports.selectMyClaims = exports.selectPendingClaims = exports.selectIsFetchingClaimListMine = exports.selectAllFetchingChannelClaims = exports.selectMyActiveClaims = exports.selectAbandoningIds = exports.selectMyClaimsRaw = exports.selectAllClaimsByChannel = exports.selectClaimsByUri = exports.selectClaimsById = exports.makeSelectIsUriResolving = exports.makeSelectContentTypeForUri = exports.makeSelectTitleForUri = exports.makeSelectMetadataForUri = exports.makeSelectClaimsInChannelForCurrentPage = exports.makeSelectFetchingChannelClaims = exports.makeSelectClaimIsMine = exports.makeSelectClaimForUri = exports.walletReducer = exports.searchReducer = exports.fileInfoReducer = exports.costInfoReducer = exports.claimsReducer = exports.toQueryString = exports.parseQueryParams = exports.batchActions = exports.doSendSupport = exports.doSetDraftTransactionAddress = exports.doSetDraftTransactionAmount = exports.doSendDraftTransaction = exports.doCheckAddressIsMine = exports.doGetNewAddress = exports.doFetchBlock = exports.doFetchTransactions = exports.doBalanceSubscribe = exports.doUpdateBalance = exports.doSearch = exports.doRecordScroll = exports.doHistoryForward = exports.doHistoryBack = exports.doHistoryTraverse = exports.doAuthNavigate = exports.doNavigate = exports.doFetchFileInfosAndPublishedClaims = exports.doFileList = exports.doFetchFileInfo = exports.doFetchCostInfoForUri = exports.doResolveUri = exports.doResolveUris = exports.doAbandonClaim = exports.doFetchClaimListMine = exports.doShowSnackBar = exports.doCloseModal = exports.doOpenModal = exports.Lbryuri = exports.Lbry = undefined; +exports.selectBlocks = exports.selectDraftTransactionError = exports.selectDraftTransactionAddress = exports.selectDraftTransactionAmount = exports.selectDraftTransaction = exports.selectGettingNewAddress = exports.selectReceiveAddress = exports.selectIsSendingSupport = exports.selectIsFetchingTransactions = exports.selectHasTransactions = exports.selectRecentTransactions = exports.selectTransactionItems = exports.selectTransactionsById = exports.selectBalance = exports.makeSelectBlockDate = exports.selectWunderBarIcon = exports.selectWunderBarAddress = exports.selectSearchUrisByQuery = exports.selectIsSearching = undefined; +exports.selectSearchQuery = exports.makeSelectSearchUris = exports.selectActiveHistoryEntry = exports.selectHistoryStack = exports.selectHistoryIndex = exports.selectIsForwardDisabled = exports.selectIsBackDisabled = exports.selectPathAfterAuth = exports.selectPageTitle = exports.selectHeaderLinks = exports.selectCurrentParams = exports.selectCurrentPage = exports.selectCurrentPath = exports.makeSelectCurrentParam = exports.computePageFromPath = exports.selectTotalDownloadProgress = exports.selectDownloadingFileInfos = exports.selectFileInfosDownloaded = exports.selectUrisLoading = exports.selectDownloadingByOutpoint = exports.selectIsFetchingFileListDownloadedOrPublished = exports.selectIsFetchingFileList = exports.selectFileInfosByOutpoint = exports.makeSelectLoadingForUri = exports.makeSelectDownloadingForUri = exports.makeSelectFileInfoForUri = exports.selectFetchingCostInfo = exports.selectCostForCurrentPageUri = exports.selectAllCostInfoByUri = exports.makeSelectCostInfoForUri = exports.makeSelectFetchingCostInfoForUri = exports.selectResolvingUris = exports.selectMyChannelClaims = exports.selectFetchingMyChannels = exports.selectMyClaimsOutpoints = exports.selectAllMyClaimsByOutpoint = exports.selectMyClaimsWithoutChannels = exports.selectMyClaims = exports.selectPendingClaims = exports.selectIsFetchingClaimListMine = exports.selectAllFetchingChannelClaims = exports.selectMyActiveClaims = exports.selectAbandoningIds = exports.selectMyClaimsRaw = exports.selectAllClaimsByChannel = exports.selectClaimsByUri = exports.selectClaimsById = exports.makeSelectIsUriResolving = exports.makeSelectContentTypeForUri = exports.makeSelectTitleForUri = exports.makeSelectMetadataForUri = exports.makeSelectClaimsInChannelForCurrentPage = exports.makeSelectFetchingChannelClaims = exports.makeSelectClaimIsMine = exports.makeSelectClaimForUri = exports.walletReducer = exports.searchReducer = exports.fileInfoReducer = exports.costInfoReducer = exports.claimsReducer = exports.toQueryString = exports.parseQueryParams = exports.batchActions = exports.doSendSupport = exports.doSetDraftTransactionAddress = exports.doSetDraftTransactionAmount = exports.doSendDraftTransaction = exports.doCheckAddressIsMine = exports.doGetNewAddress = exports.doFetchBlock = exports.doFetchTransactions = exports.doBalanceSubscribe = exports.doUpdateBalance = exports.doSearch = exports.doRecordScroll = exports.doHistoryForward = exports.doHistoryBack = exports.doHistoryTraverse = exports.doAuthNavigate = exports.doNavigate = exports.doFetchFileInfosAndPublishedClaims = exports.doFileList = exports.doFetchFileInfo = exports.doFetchCostInfoForUri = exports.doResolveUri = exports.doResolveUris = exports.doAbandonClaim = exports.doFetchClaimListMine = exports.doShowSnackBar = exports.doCloseModal = exports.doOpenModal = exports.isURIClaimable = exports.isURIValid = exports.normalizeURI = exports.buildURI = exports.parseURI = exports.regexAddress = exports.regexInvalidURI = exports.Lbryapi = exports.Lbry = undefined; -var _app = __webpack_require__(9); +var _lbryURI = __webpack_require__(3); + +Object.defineProperty(exports, 'regexInvalidURI', { + enumerable: true, + get: function get() { + return _lbryURI.regexInvalidURI; + } +}); +Object.defineProperty(exports, 'regexAddress', { + enumerable: true, + get: function get() { + return _lbryURI.regexAddress; + } +}); +Object.defineProperty(exports, 'parseURI', { + enumerable: true, + get: function get() { + return _lbryURI.parseURI; + } +}); +Object.defineProperty(exports, 'buildURI', { + enumerable: true, + get: function get() { + return _lbryURI.buildURI; + } +}); +Object.defineProperty(exports, 'normalizeURI', { + enumerable: true, + get: function get() { + return _lbryURI.normalizeURI; + } +}); +Object.defineProperty(exports, 'isURIValid', { + enumerable: true, + get: function get() { + return _lbryURI.isURIValid; + } +}); +Object.defineProperty(exports, 'isURIClaimable', { + enumerable: true, + get: function get() { + return _lbryURI.isURIClaimable; + } +}); + +var _app = __webpack_require__(6); Object.defineProperty(exports, 'doOpenModal', { enumerable: true, @@ -1939,7 +2112,7 @@ Object.defineProperty(exports, 'doShowSnackBar', { } }); -var _claims = __webpack_require__(6); +var _claims = __webpack_require__(7); Object.defineProperty(exports, 'doFetchClaimListMine', { enumerable: true, @@ -1966,7 +2139,7 @@ Object.defineProperty(exports, 'doResolveUri', { } }); -var _cost_info = __webpack_require__(15); +var _cost_info = __webpack_require__(17); Object.defineProperty(exports, 'doFetchCostInfoForUri', { enumerable: true, @@ -1975,7 +2148,7 @@ Object.defineProperty(exports, 'doFetchCostInfoForUri', { } }); -var _file_info = __webpack_require__(21); +var _file_info = __webpack_require__(22); Object.defineProperty(exports, 'doFetchFileInfo', { enumerable: true, @@ -1996,7 +2169,7 @@ Object.defineProperty(exports, 'doFetchFileInfosAndPublishedClaims', { } }); -var _navigation = __webpack_require__(8); +var _navigation = __webpack_require__(9); Object.defineProperty(exports, 'doNavigate', { enumerable: true, @@ -2035,7 +2208,7 @@ Object.defineProperty(exports, 'doRecordScroll', { } }); -var _search = __webpack_require__(22); +var _search = __webpack_require__(23); Object.defineProperty(exports, 'doSearch', { enumerable: true, @@ -2044,7 +2217,7 @@ Object.defineProperty(exports, 'doSearch', { } }); -var _wallet = __webpack_require__(23); +var _wallet = __webpack_require__(24); Object.defineProperty(exports, 'doUpdateBalance', { enumerable: true, @@ -2107,7 +2280,7 @@ Object.defineProperty(exports, 'doSendSupport', { } }); -var _batchActions = __webpack_require__(11); +var _batchActions = __webpack_require__(13); Object.defineProperty(exports, 'batchActions', { enumerable: true, @@ -2116,7 +2289,7 @@ Object.defineProperty(exports, 'batchActions', { } }); -var _query_params = __webpack_require__(7); +var _query_params = __webpack_require__(8); Object.defineProperty(exports, 'parseQueryParams', { enumerable: true, @@ -2176,7 +2349,7 @@ Object.defineProperty(exports, 'walletReducer', { } }); -var _claims3 = __webpack_require__(5); +var _claims3 = __webpack_require__(4); Object.defineProperty(exports, 'makeSelectClaimForUri', { enumerable: true, @@ -2356,7 +2529,7 @@ Object.defineProperty(exports, 'selectFetchingCostInfo', { } }); -var _file_info3 = __webpack_require__(10); +var _file_info3 = __webpack_require__(12); Object.defineProperty(exports, 'makeSelectFileInfoForUri', { enumerable: true, @@ -2545,7 +2718,7 @@ Object.defineProperty(exports, 'selectWunderBarIcon', { } }); -var _wallet3 = __webpack_require__(12); +var _wallet3 = __webpack_require__(14); Object.defineProperty(exports, 'makeSelectBlockDate', { enumerable: true, @@ -2638,24 +2811,22 @@ Object.defineProperty(exports, 'selectBlocks', { } }); -var _lbry = __webpack_require__(3); +var _lbry = __webpack_require__(5); var _lbry2 = _interopRequireDefault(_lbry); -var _lbryuri = __webpack_require__(4); +var _lbryapi = __webpack_require__(11); -var _lbryuri2 = _interopRequireDefault(_lbryuri); +var _lbryapi2 = _interopRequireDefault(_lbryapi); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // common exports.Lbry = _lbry2.default; -exports.Lbryuri = _lbryuri2.default; - -// actions +exports.Lbryapi = _lbryapi2.default; /***/ }), -/* 14 */ +/* 16 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -2742,7 +2913,7 @@ jsonrpc.call = function (connectionString, method, params, callback, errorCallba exports.default = jsonrpc; /***/ }), -/* 15 */ +/* 17 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -2757,11 +2928,11 @@ var _action_types = __webpack_require__(0); var ACTIONS = _interopRequireWildcard(_action_types); -var _lbryapi = __webpack_require__(16); +var _lbryapi = __webpack_require__(11); var _lbryapi2 = _interopRequireDefault(_lbryapi); -var _claims = __webpack_require__(5); +var _claims = __webpack_require__(4); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -2802,118 +2973,7 @@ function doFetchCostInfoForUri(uri) { } /***/ }), -/* 16 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -var _lbry = __webpack_require__(3); - -var _lbry2 = _interopRequireDefault(_lbry); - -var _querystring = __webpack_require__(18); - -var _querystring2 = _interopRequireDefault(_querystring); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var LbryApi = { - enabled: true, - exchangePromise: null, - exchangeLastFetched: null -}; - -var CONNECTION_STRING = process.env.LBRY_APP_API_URL ? process.env.LBRY_APP_API_URL.replace(/\/*$/, '/') // exactly one slash at the end -: 'https://api.lbry.io/'; - -var EXCHANGE_RATE_TIMEOUT = 20 * 60 * 1000; - -LbryApi.getExchangeRates = function () { - if (!LbryApi.exchangeLastFetched || Date.now() - LbryApi.exchangeLastFetched > EXCHANGE_RATE_TIMEOUT) { - LbryApi.exchangePromise = new Promise(function (resolve, reject) { - LbryApi.call('lbc', 'exchange_rate', {}, 'get', true).then(function (_ref) { - var LBC_USD = _ref.lbc_usd, - LBC_BTC = _ref.lbc_btc, - BTC_USD = _ref.btc_usd; - - var rates = { LBC_USD: LBC_USD, LBC_BTC: LBC_BTC, BTC_USD: BTC_USD }; - resolve(rates); - }).catch(reject); - }); - LbryApi.exchangeLastFetched = Date.now(); - } - return LbryApi.exchangePromise; -}; - -LbryApi.call = function (resource, action) { - var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - var method = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'get'; - - if (!LbryApi.enabled) { - console.log(__('Internal API disabled')); - return Promise.reject(new Error(__('LBRY internal API is disabled'))); - } - - if (!(method === 'get' || method === 'post')) { - return Promise.reject(new Error(__('Invalid method'))); - } - - function checkAndParse(response) { - if (response.status >= 200 && response.status < 300) { - return response.json(); - } - return response.json().then(function (json) { - var error = void 0; - if (json.error) { - error = new Error(json.error); - } else { - error = new Error('Unknown API error signature'); - } - error.response = response; // This is primarily a hack used in actions/user.js - return Promise.reject(error); - }); - } - - function makeRequest(url, options) { - return fetch(url, options).then(checkAndParse); - } - - var fullParams = _extends({}, params); - var qs = _querystring2.default.stringify(fullParams); - var url = '' + CONNECTION_STRING + resource + '/' + action + '?' + qs; - - var options = { - method: 'GET' - }; - - if (method === 'post') { - options = { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded' - }, - body: qs - }; - url = '' + CONNECTION_STRING + resource + '/' + action; - } - - return makeRequest(url, options).then(function (response) { - return response.data; - }); -}; - -exports.default = LbryApi; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(17))) - -/***/ }), -/* 17 */ +/* 18 */ /***/ (function(module, exports) { // shim for using process in browser @@ -3103,18 +3163,18 @@ process.umask = function() { return 0; }; /***/ }), -/* 18 */ +/* 19 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -exports.decode = exports.parse = __webpack_require__(19); -exports.encode = exports.stringify = __webpack_require__(20); +exports.decode = exports.parse = __webpack_require__(20); +exports.encode = exports.stringify = __webpack_require__(21); /***/ }), -/* 19 */ +/* 20 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3205,7 +3265,7 @@ var isArray = Array.isArray || function (xs) { /***/ }), -/* 20 */ +/* 21 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3297,7 +3357,7 @@ var objectKeys = Object.keys || function (obj) { /***/ }), -/* 21 */ +/* 22 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3314,15 +3374,15 @@ var _action_types = __webpack_require__(0); var ACTIONS = _interopRequireWildcard(_action_types); -var _lbry = __webpack_require__(3); +var _lbry = __webpack_require__(5); var _lbry2 = _interopRequireDefault(_lbry); -var _claims = __webpack_require__(6); +var _claims = __webpack_require__(7); -var _claims2 = __webpack_require__(5); +var _claims2 = __webpack_require__(4); -var _file_info = __webpack_require__(10); +var _file_info = __webpack_require__(12); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -3390,7 +3450,7 @@ function doFetchFileInfosAndPublishedClaims() { } /***/ }), -/* 22 */ +/* 23 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3405,17 +3465,15 @@ var _action_types = __webpack_require__(0); var ACTIONS = _interopRequireWildcard(_action_types); -var _lbryuri = __webpack_require__(4); +var _lbryURI = __webpack_require__(3); -var _lbryuri2 = _interopRequireDefault(_lbryuri); +var _claims = __webpack_require__(7); -var _claims = __webpack_require__(6); - -var _navigation = __webpack_require__(8); +var _navigation = __webpack_require__(9); var _navigation2 = __webpack_require__(1); -var _batchActions = __webpack_require__(11); +var _batchActions = __webpack_require__(13); var _batchActions2 = _interopRequireDefault(_batchActions); @@ -3453,7 +3511,7 @@ function doSearch(rawQuery) { var actions = []; data.forEach(function (result) { - var uri = _lbryuri2.default.build({ + var uri = (0, _lbryURI.buildURI)({ name: result.name, claimId: result.claimId }); @@ -3479,7 +3537,7 @@ function doSearch(rawQuery) { } /***/ }), -/* 23 */ +/* 24 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3503,19 +3561,19 @@ var _action_types = __webpack_require__(0); var ACTIONS = _interopRequireWildcard(_action_types); -var _modal_types = __webpack_require__(24); +var _modal_types = __webpack_require__(10); var MODALS = _interopRequireWildcard(_modal_types); -var _lbry = __webpack_require__(3); +var _lbry = __webpack_require__(5); var _lbry2 = _interopRequireDefault(_lbry); -var _app = __webpack_require__(9); +var _app = __webpack_require__(6); -var _navigation = __webpack_require__(8); +var _navigation = __webpack_require__(9); -var _wallet = __webpack_require__(12); +var _wallet = __webpack_require__(14); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -3716,32 +3774,6 @@ function doSendSupport(amount, claimId, uri) { }; } -/***/ }), -/* 24 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var CONFIRM_FILE_REMOVE = exports.CONFIRM_FILE_REMOVE = 'confirmFileRemove'; -var INCOMPATIBLE_DAEMON = exports.INCOMPATIBLE_DAEMON = 'incompatibleDaemon'; -var FILE_TIMEOUT = exports.FILE_TIMEOUT = 'file_timeout'; -var DOWNLOADING = exports.DOWNLOADING = 'downloading'; -var ERROR = exports.ERROR = 'error'; -var INSUFFICIENT_CREDITS = exports.INSUFFICIENT_CREDITS = 'insufficient_credits'; -var UPGRADE = exports.UPGRADE = 'upgrade'; -var WELCOME = exports.WELCOME = 'welcome'; -var EMAIL_COLLECTION = exports.EMAIL_COLLECTION = 'email_collection'; -var FIRST_REWARD = exports.FIRST_REWARD = 'first_reward'; -var AUTHENTICATION_FAILURE = exports.AUTHENTICATION_FAILURE = 'auth_failure'; -var TRANSACTION_FAILED = exports.TRANSACTION_FAILED = 'transaction_failed'; -var REWARD_APPROVAL_REQUIRED = exports.REWARD_APPROVAL_REQUIRED = 'reward_approval_required'; -var AFFIRM_PURCHASE = exports.AFFIRM_PURCHASE = 'affirm_purchase'; -var CONFIRM_CLAIM_REVOKE = exports.CONFIRM_CLAIM_REVOKE = 'confirmClaimRevoke'; - /***/ }), /* 25 */ /***/ (function(module, exports, __webpack_require__) { diff --git a/src/index.js b/src/index.js index 85e1ed0..5ada795 100644 --- a/src/index.js +++ b/src/index.js @@ -1,9 +1,17 @@ // common import Lbry from 'lbry'; import Lbryapi from 'lbryapi'; -import Lbryuri from 'lbryuri'; -export { Lbry, Lbryapi, Lbryuri }; +export { Lbry, Lbryapi }; +export { + regexInvalidURI, + regexAddress, + parseURI, + buildURI, + normalizeURI, + isURIValid, + isURIClaimable, +} from 'lbryURI'; // actions export { doOpenModal, doCloseModal, doShowSnackBar } from 'redux/actions/app'; diff --git a/src/lbryuri.js b/src/lbryURI.js similarity index 80% rename from src/lbryuri.js rename to src/lbryURI.js index f7c1a31..e069196 100644 --- a/src/lbryuri.js +++ b/src/lbryURI.js @@ -1,10 +1,8 @@ -const CHANNEL_NAME_MIN_LEN = 1; -const CLAIM_ID_MAX_LEN = 40; +const channelNameMinLength = 1; +const claimIdMaxLength = 40; -const Lbryuri = {}; - -Lbryuri.REGEXP_INVALID_URI = /[^A-Za-z0-9-]/g; -Lbryuri.REGEXP_ADDRESS = /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; +export const regexInvalidURI = /[^A-Za-z0-9-]/g; +export const regexAddress = /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; /** * Parses a LBRY name into its component parts. Throws errors with user-friendly @@ -28,7 +26,7 @@ Lbryuri.REGEXP_ADDRESS = /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; * - contentName (string): For anon claims, the name; for channel claims, the path * - channelName (string, if present): Channel name without @ */ -Lbryuri.parse = (uri, requireProto = false) => { +export function parseURI(URI, requireProto = false) { // Break into components. Empty sub-matches are converted to null const componentsRegex = new RegExp( '^((?:lbry://)?)' + // protocol @@ -37,7 +35,7 @@ Lbryuri.parse = (uri, requireProto = false) => { '(/?)(.*)' // path separator, path ); const [proto, name, modSep, modVal, pathSep, path] = componentsRegex - .exec(uri) + .exec(URI) .slice(1) .map(match => match || null); @@ -61,14 +59,14 @@ Lbryuri.parse = (uri, requireProto = false) => { throw new Error(__('No channel name after @.')); } - if (channelName.length < CHANNEL_NAME_MIN_LEN) { - throw new Error(__(`Channel names must be at least %s characters.`, CHANNEL_NAME_MIN_LEN)); + if (channelName.length < channelNameMinLength) { + throw new Error(__(`Channel names must be at least %s characters.`, channelNameMinLength)); } contentName = path; } - const nameBadChars = (channelName || name).match(Lbryuri.REGEXP_INVALID_URI); + const nameBadChars = (channelName || name).match(regexInvalidURI); if (nameBadChars) { throw new Error( __( @@ -99,7 +97,7 @@ Lbryuri.parse = (uri, requireProto = false) => { if ( claimId && - (claimId.length > CLAIM_ID_MAX_LEN || !claimId.match(/^[0-9a-f]+$/)) && + (claimId.length > claimIdMaxLength || !claimId.match(/^[0-9a-f]+$/)) && !claimId.match(/^pending/) // ought to be dropped when savePendingPublish drops hack ) { throw new Error(__(`Invalid claim ID %s.`, claimId)); @@ -119,7 +117,7 @@ Lbryuri.parse = (uri, requireProto = false) => { throw new Error(__('Only channel URIs may have a path.')); } - const pathBadChars = path.match(Lbryuri.REGEXP_INVALID_URI); + const pathBadChars = path.match(regexInvalidURI); if (pathBadChars) { throw new Error(__(`Invalid character in path: %s`, pathBadChars.join(', '))); } @@ -140,17 +138,17 @@ Lbryuri.parse = (uri, requireProto = false) => { ...(claimId ? { claimId } : {}), ...(path ? { path } : {}), }; -}; +} /** - * Takes an object in the same format returned by lbryuri.parse() and builds a URI. + * Takes an object in the same format returned by parse() and builds a URI. * * The channelName key will accept names with or without the @ prefix. */ -Lbryuri.build = (uriObj, includeProto = true) => { - const { claimId, claimSequence, bidPosition, contentName, channelName } = uriObj; +export function buildURI(URIObj, includeProto = true) { + const { claimId, claimSequence, bidPosition, contentName, channelName } = URIObj; - let { name, path } = uriObj; + let { name, path } = URIObj; if (channelName) { const channelNameFormatted = channelName.startsWith('@') ? channelName : `@${channelName}`; @@ -188,36 +186,35 @@ Lbryuri.build = (uriObj, includeProto = true) => { (bidPosition ? `${bidPosition}` : '') + (path ? `/${path}` : '') ); -}; +} -/* Takes a parseable LBRY URI and converts it to standard, canonical format (currently this just - * consists of adding the lbry:// prefix if needed) */ -Lbryuri.normalize = uri => { - if (uri.match(/pending_claim/)) return uri; +/* Takes a parseable LBRY URI and converts it to standard, canonical format */ +export function normalizeURI(URI) { + if (URI.match(/pending_claim/)) return URI; - const { name, path, bidPosition, claimSequence, claimId } = Lbryuri.parse(uri); - return Lbryuri.build({ name, path, claimSequence, bidPosition, claimId }); -}; + const { name, path, bidPosition, claimSequence, claimId } = parseURI(URI); + return buildURI({ name, path, claimSequence, bidPosition, claimId }); +} -Lbryuri.isValid = uri => { +export function isURIValid(URI) { let parts; try { - parts = Lbryuri.parse(Lbryuri.normalize(uri)); + parts = parseURI(normalizeURI(URI)); } catch (error) { return false; } return parts && parts.name; -}; +} -Lbryuri.isValidName = (name, checkCase = true) => { +export function isNameValid(name, checkCase = true) { const regexp = new RegExp('^[a-z0-9-]+$', checkCase ? '' : 'i'); return regexp.test(name); -}; +} -Lbryuri.isClaimable = uri => { +export function isURIClaimable(URI) { let parts; try { - parts = Lbryuri.parse(Lbryuri.normalize(uri)); + parts = parseURI(normalizeURI(URI)); } catch (error) { return false; } @@ -230,9 +227,4 @@ Lbryuri.isClaimable = uri => { !parts.isChannel && !parts.path ); -}; - -if (window) { - window.lbryuri = Lbryuri; } -export default Lbryuri; diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 188783b..c582e8c 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -1,13 +1,13 @@ import * as ACTIONS from 'constants/action_types'; import * as MODALS from 'constants/modal_types'; import Lbry from 'lbry'; -import Lbryuri from 'lbryuri'; +import { buildURI, normalizeURI } from 'lbryURI'; import { doOpenModal } from 'redux/actions/app'; import { selectMyClaimsRaw, selectResolvingUris } from 'redux/selectors/claims'; export function doResolveUris(uris) { return (dispatch, getState) => { - const normalizedUris = uris.map(Lbryuri.normalize); + const normalizedUris = uris.map(normalizeURI); const state = getState(); // Filter out URIs that are already resolving @@ -94,7 +94,7 @@ export function doAbandonClaim(txid, nout) { claimId, }, }); - dispatch(doResolveUri(Lbryuri.build({ name, claimId }))); + dispatch(doResolveUri(buildURI({ name, claimId }))); dispatch(doFetchClaimListMine()); } else { dispatch(doOpenModal(MODALS.TRANSACTION_FAILED)); diff --git a/src/redux/actions/search.js b/src/redux/actions/search.js index a98d7c7..8ada6e4 100644 --- a/src/redux/actions/search.js +++ b/src/redux/actions/search.js @@ -1,5 +1,5 @@ import * as ACTIONS from 'constants/action_types'; -import Lbryuri from 'lbryuri'; +import { buildURI } from 'lbryURI'; import { doResolveUri } from 'redux/actions/claims'; import { doNavigate } from 'redux/actions/navigation'; import { selectCurrentPage } from 'redux/selectors/navigation'; @@ -40,7 +40,7 @@ export function doSearch(rawQuery) { const actions = []; data.forEach(result => { - const uri = Lbryuri.build({ + const uri = buildURI({ name: result.name, claimId: result.claimId, }); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 7b778f6..0ea6b4c 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -1,4 +1,4 @@ -import Lbryuri from 'lbryuri'; +import { normalizeURI } from 'lbryURI'; import { makeSelectCurrentParam } from 'redux/selectors/navigation'; import { createSelector } from 'reselect'; @@ -32,7 +32,7 @@ export const selectAllClaimsByChannel = createSelector( ); export const makeSelectClaimForUri = uri => - createSelector(selectClaimsByUri, claims => claims && claims[Lbryuri.normalize(uri)]); + createSelector(selectClaimsByUri, claims => claims && claims[normalizeURI(uri)]); export const selectMyClaimsRaw = createSelector(selectState, state => state.myClaims); @@ -53,7 +53,7 @@ export const selectMyActiveClaims = createSelector( ); export const makeSelectClaimIsMine = rawUri => { - const uri = Lbryuri.normalize(rawUri); + const uri = normalizeURI(rawUri); return createSelector( selectClaimsByUri, selectMyActiveClaims, diff --git a/src/redux/selectors/navigation.js b/src/redux/selectors/navigation.js index dc0b507..fa9fa3b 100644 --- a/src/redux/selectors/navigation.js +++ b/src/redux/selectors/navigation.js @@ -1,6 +1,6 @@ import { createSelector } from 'reselect'; +import { normalizeURI } from 'lbryURI'; import { parseQueryParams, toQueryString } from 'util/query_params'; -import Lbryuri from 'lbryuri'; export const selectState = state => state.navigation || {}; @@ -93,7 +93,7 @@ export const selectPageTitle = createSelector( case 'developer': return __('Developer'); case 'show': { - const parts = [Lbryuri.normalize(params.uri)]; + const parts = [normalizeURI(params.uri)]; // If the params has any keys other than "uri" if (Object.keys(params).length > 1) { parts.push(toQueryString(Object.assign({}, params, { uri: null })));