netlify-cms-lib-util
Advanced tools
Comparing version
@@ -6,2 +6,10 @@ # Change Log | ||
## [2.12.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.12.2...netlify-cms-lib-util@2.12.3) (2021-02-10) | ||
**Note:** Version bump only for package netlify-cms-lib-util | ||
## [2.12.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.12.1...netlify-cms-lib-util@2.12.2) (2021-02-01) | ||
@@ -8,0 +16,0 @@ |
@@ -6,3 +6,9 @@ "use strict"; | ||
}); | ||
exports.throwOnConflictingBranches = exports.getPreviewStatus = exports.PreviewState = exports.isPreviewContext = exports.readFileMetadata = exports.readFile = exports.requestWithBackoff = void 0; | ||
exports.requestWithBackoff = requestWithBackoff; | ||
exports.readFile = readFile; | ||
exports.readFileMetadata = readFileMetadata; | ||
exports.isPreviewContext = isPreviewContext; | ||
exports.getPreviewStatus = getPreviewStatus; | ||
exports.throwOnConflictingBranches = throwOnConflictingBranches; | ||
exports.PreviewState = void 0; | ||
@@ -61,3 +67,3 @@ var _asyncLock = require("./asyncLock"); | ||
const requestWithBackoff = async (api, req, attempt = 1) => { | ||
async function requestWithBackoff(api, req, attempt = 1) { | ||
if (api.rateLimiter) { | ||
@@ -113,7 +119,5 @@ await api.rateLimiter.acquire(); | ||
} | ||
}; | ||
} | ||
exports.requestWithBackoff = requestWithBackoff; | ||
const readFile = async (id, fetchContent, localForage, isText) => { | ||
async function readFile(id, fetchContent, localForage, isText) { | ||
const key = id ? isText ? `gh.${id}` : `gh.${id}.blob` : null; | ||
@@ -133,9 +137,9 @@ const cached = key ? await localForage.getItem(key) : null; | ||
return content; | ||
}; | ||
} | ||
exports.readFile = readFile; | ||
function getFileMetadataKey(id) { | ||
return `gh.${id}.meta`; | ||
} | ||
const getFileMetadataKey = id => `gh.${id}.meta`; | ||
const readFileMetadata = async (id, fetchMetadata, localForage) => { | ||
async function readFileMetadata(id, fetchMetadata, localForage) { | ||
const key = id ? getFileMetadataKey(id) : null; | ||
@@ -155,3 +159,3 @@ const cached = key && (await localForage.getItem(key)); | ||
return metadata; | ||
}; | ||
} | ||
/** | ||
@@ -162,3 +166,2 @@ * Keywords for inferring a status that will provide a deploy preview URL. | ||
exports.readFileMetadata = readFileMetadata; | ||
const PREVIEW_CONTEXT_KEYWORDS = ['deploy']; | ||
@@ -171,3 +174,3 @@ /** | ||
const isPreviewContext = (context, previewContext) => { | ||
function isPreviewContext(context, previewContext) { | ||
if (previewContext) { | ||
@@ -178,5 +181,4 @@ return context === previewContext; | ||
return PREVIEW_CONTEXT_KEYWORDS.some(keyword => context.includes(keyword)); | ||
}; | ||
} | ||
exports.isPreviewContext = isPreviewContext; | ||
let PreviewState; | ||
@@ -195,3 +197,3 @@ /** | ||
const getPreviewStatus = (statuses, previewContext) => { | ||
function getPreviewStatus(statuses, previewContext) { | ||
return statuses.find(({ | ||
@@ -202,7 +204,5 @@ context | ||
}); | ||
}; | ||
} | ||
exports.getPreviewStatus = getPreviewStatus; | ||
const getConflictingBranches = branchName => { | ||
function getConflictingBranches(branchName) { | ||
// for cms/posts/post-1, conflicting branches are cms/posts, cms | ||
@@ -216,5 +216,5 @@ const parts = branchName.split('/'); | ||
return conflictingBranches; | ||
}; | ||
} | ||
const throwOnConflictingBranches = async (branchName, getBranch, apiName) => { | ||
async function throwOnConflictingBranches(branchName, getBranch, apiName) { | ||
const possibleConflictingBranches = getConflictingBranches(branchName); | ||
@@ -227,4 +227,2 @@ const conflictingBranches = await Promise.all(possibleConflictingBranches.map(b => getBranch(b).then(b => b.name).catch(() => ''))); | ||
} | ||
}; | ||
exports.throwOnConflictingBranches = throwOnConflictingBranches; | ||
} |
@@ -6,3 +6,10 @@ "use strict"; | ||
}); | ||
exports.branchFromContentKey = exports.contentKeyFromBranch = exports.parseContentKey = exports.generateContentKey = exports.statusToLabel = exports.labelToStatus = exports.isCMSLabel = exports.MERGE_COMMIT_MESSAGE = exports.DEFAULT_PR_BODY = exports.CMS_BRANCH_PREFIX = void 0; | ||
exports.isCMSLabel = isCMSLabel; | ||
exports.labelToStatus = labelToStatus; | ||
exports.statusToLabel = statusToLabel; | ||
exports.generateContentKey = generateContentKey; | ||
exports.parseContentKey = parseContentKey; | ||
exports.contentKeyFromBranch = contentKeyFromBranch; | ||
exports.branchFromContentKey = branchFromContentKey; | ||
exports.MERGE_COMMIT_MESSAGE = exports.DEFAULT_PR_BODY = exports.CMS_BRANCH_PREFIX = void 0; | ||
const CMS_BRANCH_PREFIX = 'cms'; | ||
@@ -16,21 +23,23 @@ exports.CMS_BRANCH_PREFIX = CMS_BRANCH_PREFIX; | ||
const getLabelPrefix = labelPrefix => labelPrefix || DEFAULT_NETLIFY_CMS_LABEL_PREFIX; | ||
function getLabelPrefix(labelPrefix) { | ||
return labelPrefix || DEFAULT_NETLIFY_CMS_LABEL_PREFIX; | ||
} | ||
const isCMSLabel = (label, labelPrefix) => label.startsWith(getLabelPrefix(labelPrefix)); | ||
function isCMSLabel(label, labelPrefix) { | ||
return label.startsWith(getLabelPrefix(labelPrefix)); | ||
} | ||
exports.isCMSLabel = isCMSLabel; | ||
function labelToStatus(label, labelPrefix) { | ||
return label.substr(getLabelPrefix(labelPrefix).length); | ||
} | ||
const labelToStatus = (label, labelPrefix) => label.substr(getLabelPrefix(labelPrefix).length); | ||
function statusToLabel(status, labelPrefix) { | ||
return `${getLabelPrefix(labelPrefix)}${status}`; | ||
} | ||
exports.labelToStatus = labelToStatus; | ||
function generateContentKey(collectionName, slug) { | ||
return `${collectionName}/${slug}`; | ||
} | ||
const statusToLabel = (status, labelPrefix) => `${getLabelPrefix(labelPrefix)}${status}`; | ||
exports.statusToLabel = statusToLabel; | ||
const generateContentKey = (collectionName, slug) => `${collectionName}/${slug}`; | ||
exports.generateContentKey = generateContentKey; | ||
const parseContentKey = contentKey => { | ||
function parseContentKey(contentKey) { | ||
const index = contentKey.indexOf('/'); | ||
@@ -41,16 +50,10 @@ return { | ||
}; | ||
}; | ||
} | ||
exports.parseContentKey = parseContentKey; | ||
const contentKeyFromBranch = branch => { | ||
function contentKeyFromBranch(branch) { | ||
return branch.substring(`${CMS_BRANCH_PREFIX}/`.length); | ||
}; | ||
} | ||
exports.contentKeyFromBranch = contentKeyFromBranch; | ||
const branchFromContentKey = contentKey => { | ||
function branchFromContentKey(contentKey) { | ||
return `${CMS_BRANCH_PREFIX}/${contentKey}`; | ||
}; | ||
exports.branchFromContentKey = branchFromContentKey; | ||
} |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.asyncLock = void 0; | ||
exports.asyncLock = asyncLock; | ||
@@ -13,6 +13,6 @@ var _semaphore = _interopRequireDefault(require("semaphore")); | ||
const asyncLock = () => { | ||
function asyncLock() { | ||
let lock = (0, _semaphore.default)(1); | ||
const acquire = (timeout = 15000) => { | ||
function acquire(timeout = 15000) { | ||
const promise = new Promise(resolve => { | ||
@@ -31,5 +31,5 @@ // this makes sure a caller doesn't gets stuck forever awaiting on the lock | ||
return promise; | ||
}; | ||
} | ||
const release = () => { | ||
function release() { | ||
try { | ||
@@ -48,3 +48,3 @@ // suppress too many calls to leave error | ||
} | ||
}; | ||
} | ||
@@ -55,4 +55,2 @@ return { | ||
}; | ||
}; | ||
exports.asyncLock = asyncLock; | ||
} |
@@ -6,3 +6,8 @@ "use strict"; | ||
}); | ||
exports.getPathDepth = exports.getAllResponses = exports.parseLinkHeader = exports.responseParser = exports.parseResponse = exports.filterByExtension = void 0; | ||
exports.filterByExtension = filterByExtension; | ||
exports.parseResponse = parseResponse; | ||
exports.responseParser = responseParser; | ||
exports.parseLinkHeader = parseLinkHeader; | ||
exports.getAllResponses = getAllResponses; | ||
exports.getPathDepth = getPathDepth; | ||
@@ -23,17 +28,17 @@ var _map2 = _interopRequireDefault(require("lodash/fp/map")); | ||
const filterByExtension = (file, extension) => { | ||
function filterByExtension(file, extension) { | ||
const path = (file === null || file === void 0 ? void 0 : file.path) || ''; | ||
return path.endsWith(extension.startsWith('.') ? extension : `.${extension}`); | ||
}; | ||
} | ||
exports.filterByExtension = filterByExtension; | ||
function catchFormatErrors(format, formatter) { | ||
return res => { | ||
try { | ||
return formatter(res); | ||
} catch (err) { | ||
throw new Error(`Response cannot be parsed into the expected format (${format}): ${err.message}`); | ||
} | ||
}; | ||
} | ||
const catchFormatErrors = (format, formatter) => res => { | ||
try { | ||
return formatter(res); | ||
} catch (err) { | ||
throw new Error(`Response cannot be parsed into the expected format (${format}): ${err.message}`); | ||
} | ||
}; | ||
const responseFormatters = (0, _immutable.fromJS)({ | ||
@@ -53,7 +58,7 @@ json: async res => { | ||
const parseResponse = async (res, { | ||
async function parseResponse(res, { | ||
expectingOk = true, | ||
format = 'text', | ||
apiName = '' | ||
}) => { | ||
}) { | ||
let body; | ||
@@ -82,11 +87,9 @@ | ||
return body; | ||
}; | ||
} | ||
exports.parseResponse = parseResponse; | ||
function responseParser(options) { | ||
return res => parseResponse(res, options); | ||
} | ||
const responseParser = options => res => parseResponse(res, options); | ||
exports.responseParser = responseParser; | ||
const parseLinkHeader = header => { | ||
function parseLinkHeader(header) { | ||
if (!header) { | ||
@@ -97,7 +100,5 @@ return {}; | ||
return (0, _flow2.default)([linksString => linksString.split(','), (0, _map2.default)(str => str.trim().split(';')), (0, _map2.default)(([linkStr, keyStr]) => [keyStr.match(/rel="(.*?)"/)[1], linkStr.trim().match(/<(.*?)>/)[1].replace(/\+/g, '%20')]), _fromPairs2.default])(header); | ||
}; | ||
} | ||
exports.parseLinkHeader = parseLinkHeader; | ||
const getAllResponses = async (url, options = {}, linkHeaderRelName, nextUrlProcessor) => { | ||
async function getAllResponses(url, options = {}, linkHeaderRelName, nextUrlProcessor) { | ||
const maxResponses = 30; | ||
@@ -125,11 +126,7 @@ let responseCount = 1; | ||
return pageResponses; | ||
}; | ||
} | ||
exports.getAllResponses = getAllResponses; | ||
const getPathDepth = path => { | ||
function getPathDepth(path) { | ||
const depth = path.split('/').length; | ||
return depth; | ||
}; | ||
exports.getPathDepth = getPathDepth; | ||
} |
@@ -12,3 +12,3 @@ "use strict"; | ||
const jsToMap = obj => { | ||
function jsToMap(obj) { | ||
if (obj === undefined) { | ||
@@ -25,7 +25,9 @@ return (0, _immutable.Map)(); | ||
return immutableObj; | ||
}; | ||
} | ||
const knownMetaKeys = (0, _immutable.Set)(['index', 'page', 'count', 'pageSize', 'pageCount', 'usingOldPaginationAPI', 'extension', 'folder', 'depth']); | ||
const filterUnknownMetaKeys = meta => meta.filter((_v, k) => knownMetaKeys.has(k)); | ||
function filterUnknownMetaKeys(meta) { | ||
return meta.filter((_v, k) => knownMetaKeys.has(k)); | ||
} | ||
/* | ||
@@ -39,3 +41,3 @@ createCursorMap takes one of three signatures: | ||
const createCursorStore = (...args) => { | ||
function createCursorStore(...args) { | ||
const { | ||
@@ -57,7 +59,11 @@ actions, | ||
}); | ||
}; | ||
} | ||
const hasAction = (store, action) => store.hasIn(['actions', action]); | ||
function hasAction(store, action) { | ||
return store.hasIn(['actions', action]); | ||
} | ||
const getActionHandlers = (store, handler) => store.get('actions', (0, _immutable.Set)()).toMap().map(action => handler(action)); // The cursor logic is entirely functional, so this class simply | ||
function getActionHandlers(store, handler) { | ||
return store.get('actions', (0, _immutable.Set)()).toMap().map(action => handler(action)); | ||
} // The cursor logic is entirely functional, so this class simply | ||
// provides a chainable interface | ||
@@ -64,0 +70,0 @@ |
@@ -6,5 +6,6 @@ "use strict"; | ||
}); | ||
exports.createPointerFile = createPointerFile; | ||
exports.getPointerFileForMediaFileObj = getPointerFileForMediaFileObj; | ||
exports.getLargeMediaFilteredMediaFiles = getLargeMediaFilteredMediaFiles; | ||
exports.createPointerFile = exports.getLargeMediaPatternsFromGitAttributesFile = exports.parsePointerFile = void 0; | ||
exports.getLargeMediaPatternsFromGitAttributesFile = exports.parsePointerFile = void 0; | ||
@@ -33,7 +34,13 @@ var _map2 = _interopRequireDefault(require("lodash/fp/map")); | ||
const splitIntoLines = str => str.split('\n'); | ||
function splitIntoLines(str) { | ||
return str.split('\n'); | ||
} | ||
const splitIntoWords = str => str.split(/\s+/g); | ||
function splitIntoWords(str) { | ||
return str.split(/\s+/g); | ||
} | ||
const isNonEmptyString = str => str !== ''; | ||
function isNonEmptyString(str) { | ||
return str !== ''; | ||
} | ||
@@ -57,5 +64,7 @@ const withoutEmptyLines = (0, _flow2.default)([(0, _map2.default)(str => str.trim()), (0, _filter2.default)(isNonEmptyString)]); | ||
const removeGitAttributesCommentsFromLine = line => line.split('#')[0]; | ||
function removeGitAttributesCommentsFromLine(line) { | ||
return line.split('#')[0]; | ||
} | ||
const parseGitPatternAttribute = attributeString => { | ||
function parseGitPatternAttribute(attributeString) { | ||
// There are three kinds of attribute settings: | ||
@@ -75,3 +84,3 @@ // - a key=val pair sets an attribute to a specific value | ||
return [attributeString, true]; | ||
}; | ||
} | ||
@@ -84,6 +93,7 @@ const parseGitPatternAttributes = (0, _flow2.default)([(0, _map2.default)(parseGitPatternAttribute), _fromPairs2.default]); | ||
const createPointerFile = ({ | ||
function createPointerFile({ | ||
size, | ||
sha | ||
}) => `\ | ||
}) { | ||
return `\ | ||
version https://git-lfs.github.com/spec/v1 | ||
@@ -93,5 +103,4 @@ oid sha256:${sha} | ||
`; | ||
} | ||
exports.createPointerFile = createPointerFile; | ||
async function getPointerFileForMediaFileObj(client, fileObj, path) { | ||
@@ -98,0 +107,0 @@ const { |
@@ -6,3 +6,12 @@ "use strict"; | ||
}); | ||
exports.allEntriesByFolder = exports.getLocalTree = exports.persistLocalTree = exports.runWithLock = exports.getMediaDisplayURL = exports.getMediaAsBlob = exports.blobToFileObj = exports.unpublishedEntries = exports.entriesByFiles = exports.entriesByFolder = void 0; | ||
exports.entriesByFolder = entriesByFolder; | ||
exports.entriesByFiles = entriesByFiles; | ||
exports.unpublishedEntries = unpublishedEntries; | ||
exports.blobToFileObj = blobToFileObj; | ||
exports.getMediaAsBlob = getMediaAsBlob; | ||
exports.getMediaDisplayURL = getMediaDisplayURL; | ||
exports.runWithLock = runWithLock; | ||
exports.persistLocalTree = persistLocalTree; | ||
exports.getLocalTree = getLocalTree; | ||
exports.allEntriesByFolder = allEntriesByFolder; | ||
@@ -27,3 +36,3 @@ var _sortBy2 = _interopRequireDefault(require("lodash/sortBy")); | ||
const fetchFiles = async (files, readFile, readFileMetadata, apiName) => { | ||
async function fetchFiles(files, readFile, readFileMetadata, apiName) { | ||
const sem = (0, _semaphore.default)(MAX_CONCURRENT_DOWNLOADS); | ||
@@ -52,18 +61,14 @@ const promises = []; | ||
return Promise.all(promises).then(loadedEntries => loadedEntries.filter(loadedEntry => !loadedEntry.error)); | ||
}; | ||
} | ||
const entriesByFolder = async (listFiles, readFile, readFileMetadata, apiName) => { | ||
async function entriesByFolder(listFiles, readFile, readFileMetadata, apiName) { | ||
const files = await listFiles(); | ||
return fetchFiles(files, readFile, readFileMetadata, apiName); | ||
}; | ||
} | ||
exports.entriesByFolder = entriesByFolder; | ||
const entriesByFiles = async (files, readFile, readFileMetadata, apiName) => { | ||
async function entriesByFiles(files, readFile, readFileMetadata, apiName) { | ||
return fetchFiles(files, readFile, readFileMetadata, apiName); | ||
}; | ||
} | ||
exports.entriesByFiles = entriesByFiles; | ||
const unpublishedEntries = async listEntriesKeys => { | ||
async function unpublishedEntries(listEntriesKeys) { | ||
try { | ||
@@ -79,7 +84,5 @@ const keys = await listEntriesKeys(); | ||
} | ||
}; | ||
} | ||
exports.unpublishedEntries = unpublishedEntries; | ||
const blobToFileObj = (name, blob) => { | ||
function blobToFileObj(name, blob) { | ||
const options = name.match(/.svg$/) ? { | ||
@@ -89,7 +92,5 @@ type: 'image/svg+xml' | ||
return new File([blob], name, options); | ||
}; | ||
} | ||
exports.blobToFileObj = blobToFileObj; | ||
const getMediaAsBlob = async (path, id, readFile) => { | ||
async function getMediaAsBlob(path, id, readFile) { | ||
let blob; | ||
@@ -111,7 +112,5 @@ | ||
return blob; | ||
}; | ||
} | ||
exports.getMediaAsBlob = getMediaAsBlob; | ||
const getMediaDisplayURL = async (displayURL, readFile, semaphore) => { | ||
async function getMediaDisplayURL(displayURL, readFile, semaphore) { | ||
const { | ||
@@ -122,7 +121,5 @@ path, | ||
return new Promise((resolve, reject) => semaphore.take(() => getMediaAsBlob(path, id, readFile).then(blob => URL.createObjectURL(blob)).then(resolve, reject).finally(() => semaphore.leave()))); | ||
}; | ||
} | ||
exports.getMediaDisplayURL = getMediaDisplayURL; | ||
const runWithLock = async (lock, func, message) => { | ||
async function runWithLock(lock, func, message) { | ||
try { | ||
@@ -140,8 +137,7 @@ const acquired = await lock.acquire(); | ||
} | ||
}; | ||
} | ||
exports.runWithLock = runWithLock; | ||
const LOCAL_KEY = 'git.local'; | ||
const getLocalKey = ({ | ||
function getLocalKey({ | ||
branch, | ||
@@ -151,7 +147,7 @@ folder, | ||
depth | ||
}) => { | ||
}) { | ||
return `${LOCAL_KEY}.${branch}.${folder}.${extension}.${depth}`; | ||
}; | ||
} | ||
const persistLocalTree = async ({ | ||
async function persistLocalTree({ | ||
localForage, | ||
@@ -163,3 +159,3 @@ localTree, | ||
depth | ||
}) => { | ||
}) { | ||
await localForage.setItem(getLocalKey({ | ||
@@ -171,7 +167,5 @@ branch, | ||
}), localTree); | ||
}; | ||
} | ||
exports.persistLocalTree = persistLocalTree; | ||
const getLocalTree = async ({ | ||
async function getLocalTree({ | ||
localForage, | ||
@@ -182,3 +176,3 @@ branch, | ||
depth | ||
}) => { | ||
}) { | ||
const localTree = await localForage.getItem(getLocalKey({ | ||
@@ -191,7 +185,5 @@ branch, | ||
return localTree; | ||
}; | ||
} | ||
exports.getLocalTree = getLocalTree; | ||
const getDiffFromLocalTree = async ({ | ||
async function getDiffFromLocalTree({ | ||
branch, | ||
@@ -203,3 +195,3 @@ localTree, | ||
getFileId | ||
}) => { | ||
}) { | ||
const diff = await getDifferences(branch.sha, localTree.head); | ||
@@ -251,5 +243,5 @@ const diffFiles = diff.filter(d => { | ||
return diffFilesWithIds; | ||
}; | ||
} | ||
const allEntriesByFolder = async ({ | ||
async function allEntriesByFolder({ | ||
listAllFiles, | ||
@@ -269,4 +261,4 @@ readFile, | ||
filterFile | ||
}) => { | ||
const listAllFilesAndPersist = async () => { | ||
}) { | ||
async function listAllFilesAndPersist() { | ||
const files = await listAllFiles(folder, extension, depth); | ||
@@ -290,5 +282,5 @@ const branch = await getDefaultBranch(); | ||
return files; | ||
}; | ||
} | ||
const listFiles = async () => { | ||
async function listFiles() { | ||
const localTree = await getLocalTree({ | ||
@@ -335,5 +327,2 @@ localForage, | ||
} else { | ||
// refresh local copy | ||
const identity = file => file.path; | ||
const deleted = diff.reduce((acc, d) => { | ||
@@ -343,3 +332,3 @@ acc[d.path] = d.deleted; | ||
}, {}); | ||
const newCopy = (0, _sortBy2.default)((0, _unionBy2.default)(diff.filter(d => !deleted[d.path]), localTree.files.filter(f => !deleted[f.path]), identity), identity); | ||
const newCopy = (0, _sortBy2.default)((0, _unionBy2.default)(diff.filter(d => !deleted[d.path]), localTree.files.filter(f => !deleted[f.path]), file => file.path), file => file.path); | ||
await persistLocalTree({ | ||
@@ -361,8 +350,6 @@ localForage, | ||
} | ||
}; | ||
} | ||
const files = await listFiles(); | ||
return fetchFiles(files, readFile, readFileMetadata, apiName); | ||
}; | ||
exports.allEntriesByFolder = allEntriesByFolder; | ||
} |
@@ -12,3 +12,5 @@ "use strict"; | ||
const normalizePath = path => path.replace(/[\\/]+/g, '/'); | ||
function normalizePath(path) { | ||
return path.replace(/[\\/]+/g, '/'); | ||
} | ||
@@ -15,0 +17,0 @@ function isAbsolutePath(path) { |
@@ -6,3 +6,5 @@ "use strict"; | ||
}); | ||
exports.flowAsync = exports.onlySuccessfulPromises = exports.then = void 0; | ||
exports.then = then; | ||
exports.onlySuccessfulPromises = onlySuccessfulPromises; | ||
exports.flowAsync = flowAsync; | ||
@@ -13,17 +15,18 @@ var _flow = _interopRequireDefault(require("lodash/flow")); | ||
const then = fn => p => Promise.resolve(p).then(fn); | ||
function then(fn) { | ||
return p => Promise.resolve(p).then(fn); | ||
} | ||
exports.then = then; | ||
const filterPromiseSymbol = Symbol('filterPromiseSymbol'); | ||
const onlySuccessfulPromises = promises => { | ||
function onlySuccessfulPromises(promises) { | ||
return Promise.all(promises.map(p => p.catch(() => filterPromiseSymbol))).then(results => results.filter(result => result !== filterPromiseSymbol)); | ||
}; | ||
} | ||
exports.onlySuccessfulPromises = onlySuccessfulPromises; | ||
function wrapFlowAsync(fn) { | ||
return async arg => fn(await arg); | ||
} | ||
const wrapFlowAsync = fn => async arg => fn(await arg); | ||
const flowAsync = fns => (0, _flow.default)(fns.map(fn => wrapFlowAsync(fn))); | ||
exports.flowAsync = flowAsync; | ||
function flowAsync(fns) { | ||
return (0, _flow.default)(fns.map(fn => wrapFlowAsync(fn))); | ||
} |
@@ -24,3 +24,3 @@ "use strict"; | ||
const isAbortControllerSupported = () => { | ||
function isAbortControllerSupported() { | ||
if (typeof window !== 'undefined') { | ||
@@ -31,7 +31,7 @@ return !!window.AbortController; | ||
return false; | ||
}; | ||
} | ||
const timeout = 60; | ||
const fetchWithTimeout = (input, init) => { | ||
function fetchWithTimeout(input, init) { | ||
if (init && init.signal || !isAbortControllerSupported()) { | ||
@@ -55,7 +55,9 @@ return fetch(input, init); | ||
}); | ||
}; | ||
} | ||
const decodeParams = paramsString => (0, _immutable.List)(paramsString.split('&')).map(s => (0, _immutable.List)(s.split('=')).map(decodeURIComponent)).update(_immutable.Map); | ||
function decodeParams(paramsString) { | ||
return (0, _immutable.List)(paramsString.split('&')).map(s => (0, _immutable.List)(s.split('=')).map(decodeURIComponent)).update(_immutable.Map); | ||
} | ||
const fromURL = wholeURL => { | ||
function fromURL(wholeURL) { | ||
const [url, allParamsString] = wholeURL.split('?'); | ||
@@ -67,15 +69,21 @@ return (0, _immutable.Map)(_objectSpread({ | ||
} : {})); | ||
}; | ||
} | ||
const fromFetchArguments = (wholeURL, options) => { | ||
function fromFetchArguments(wholeURL, options) { | ||
return fromURL(wholeURL).merge((options ? (0, _immutable.fromJS)(options) : (0, _immutable.Map)()).remove('url').remove('params')); | ||
}; | ||
} | ||
const encodeParams = params => params.entrySeq().map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join('&'); | ||
function encodeParams(params) { | ||
return params.entrySeq().map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join('&'); | ||
} | ||
const toURL = req => `${req.get('url')}${req.get('params') ? `?${encodeParams(req.get('params'))}` : ''}`; | ||
function toURL(req) { | ||
return `${req.get('url')}${req.get('params') ? `?${encodeParams(req.get('params'))}` : ''}`; | ||
} | ||
const toFetchArguments = req => [toURL(req), req.remove('url').remove('params').toJS()]; | ||
function toFetchArguments(req) { | ||
return [toURL(req), req.remove('url').remove('params').toJS()]; | ||
} | ||
const maybeRequestArg = req => { | ||
function maybeRequestArg(req) { | ||
if ((0, _isString.default)(req)) { | ||
@@ -90,7 +98,11 @@ return fromURL(req); | ||
return (0, _immutable.Map)(); | ||
}; | ||
} | ||
const ensureRequestArg = func => req => func(maybeRequestArg(req)); | ||
function ensureRequestArg(func) { | ||
return req => func(maybeRequestArg(req)); | ||
} | ||
const ensureRequestArg2 = func => (arg, req) => func(arg, maybeRequestArg(req)); // This actually performs the built request object | ||
function ensureRequestArg2(func) { | ||
return (arg, req) => func(arg, maybeRequestArg(req)); | ||
} // This actually performs the built request object | ||
@@ -106,5 +118,9 @@ | ||
const getPropSetFunction = path => getCurriedRequestProcessor((val, req) => req.setIn(path, val)); | ||
function getPropSetFunction(path) { | ||
return getCurriedRequestProcessor((val, req) => req.setIn(path, val)); | ||
} | ||
const getPropMergeFunction = path => getCurriedRequestProcessor((obj, req) => req.updateIn(path, (p = (0, _immutable.Map)()) => p.merge(obj))); | ||
function getPropMergeFunction(path) { | ||
return getCurriedRequestProcessor((obj, req) => req.updateIn(path, (p = (0, _immutable.Map)()) => p.merge(obj))); | ||
} | ||
@@ -111,0 +127,0 @@ const withMethod = getPropSetFunction(['method']); |
{ | ||
"name": "netlify-cms-lib-util", | ||
"description": "Shared utilities for Netlify CMS.", | ||
"version": "2.12.2", | ||
"version": "2.12.3", | ||
"repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util", | ||
@@ -28,3 +28,3 @@ "bugs": "https://github.com/netlify/netlify-cms/issues", | ||
}, | ||
"gitHead": "d11282ffebfdb4895666fa6cc940b8938226284c" | ||
"gitHead": "9348bd40a8cacdf98252e5363cc4c90e045177db" | ||
} |
@@ -24,7 +24,7 @@ import { parseLinkHeader, getAllResponses, getPathDepth, filterByExtension } from '../backendUtil'; | ||
describe('getAllResponses', () => { | ||
const generatePulls = length => { | ||
function generatePulls(length) { | ||
return Array.from({ length }, (_, id) => { | ||
return { id: id + 1, number: `134${id}`, state: 'open' }; | ||
}); | ||
}; | ||
} | ||
@@ -35,4 +35,7 @@ function createLinkHeaders({ page, pageCount }) { | ||
const url = 'https://api.github.com/pulls'; | ||
const link = linkPage => `<${url}?page=${linkPage}>`; | ||
function link(linkPage) { | ||
return `<${url}?page=${linkPage}>`; | ||
} | ||
const linkHeader = oneLine` | ||
@@ -39,0 +42,0 @@ ${pageNum === 1 ? '' : `${link(1)}; rel="first",`} |
@@ -41,7 +41,7 @@ import { asyncLock, AsyncLock } from './asyncLock'; | ||
export const requestWithBackoff = async ( | ||
export async function requestWithBackoff( | ||
api: API, | ||
req: ApiRequest, | ||
attempt = 1, | ||
): Promise<Response> => { | ||
): Promise<Response> { | ||
if (api.rateLimiter) { | ||
@@ -96,5 +96,5 @@ await api.rateLimiter.acquire(); | ||
} | ||
}; | ||
} | ||
export const readFile = async ( | ||
export async function readFile( | ||
id: string | null | undefined, | ||
@@ -104,3 +104,3 @@ fetchContent: () => Promise<string | Blob>, | ||
isText: boolean, | ||
) => { | ||
) { | ||
const key = id ? (isText ? `gh.${id}` : `gh.${id}.blob`) : null; | ||
@@ -117,3 +117,3 @@ const cached = key ? await localForage.getItem<string | Blob>(key) : null; | ||
return content; | ||
}; | ||
} | ||
@@ -125,9 +125,11 @@ export type FileMetadata = { | ||
const getFileMetadataKey = (id: string) => `gh.${id}.meta`; | ||
function getFileMetadataKey(id: string) { | ||
return `gh.${id}.meta`; | ||
} | ||
export const readFileMetadata = async ( | ||
export async function readFileMetadata( | ||
id: string | null | undefined, | ||
fetchMetadata: () => Promise<FileMetadata>, | ||
localForage: LocalForage, | ||
) => { | ||
) { | ||
const key = id ? getFileMetadataKey(id) : null; | ||
@@ -144,3 +146,3 @@ const cached = key && (await localForage.getItem<FileMetadata>(key)); | ||
return metadata; | ||
}; | ||
} | ||
@@ -157,3 +159,3 @@ /** | ||
*/ | ||
export const isPreviewContext = (context: string, previewContext: string) => { | ||
export function isPreviewContext(context: string, previewContext: string) { | ||
if (previewContext) { | ||
@@ -163,3 +165,3 @@ return context === previewContext; | ||
return PREVIEW_CONTEXT_KEYWORDS.some(keyword => context.includes(keyword)); | ||
}; | ||
} | ||
@@ -175,3 +177,3 @@ export enum PreviewState { | ||
*/ | ||
export const getPreviewStatus = ( | ||
export function getPreviewStatus( | ||
statuses: { | ||
@@ -183,9 +185,9 @@ context: string; | ||
previewContext: string, | ||
) => { | ||
) { | ||
return statuses.find(({ context }) => { | ||
return isPreviewContext(context, previewContext); | ||
}); | ||
}; | ||
} | ||
const getConflictingBranches = (branchName: string) => { | ||
function getConflictingBranches(branchName: string) { | ||
// for cms/posts/post-1, conflicting branches are cms/posts, cms | ||
@@ -201,9 +203,9 @@ const parts = branchName.split('/'); | ||
return conflictingBranches; | ||
}; | ||
} | ||
export const throwOnConflictingBranches = async ( | ||
export async function throwOnConflictingBranches( | ||
branchName: string, | ||
getBranch: (name: string) => Promise<{ name: string }>, | ||
apiName: string, | ||
) => { | ||
) { | ||
const possibleConflictingBranches = getConflictingBranches(branchName); | ||
@@ -227,2 +229,2 @@ | ||
} | ||
}; | ||
} |
@@ -6,25 +6,34 @@ export const CMS_BRANCH_PREFIX = 'cms'; | ||
const DEFAULT_NETLIFY_CMS_LABEL_PREFIX = 'netlify-cms/'; | ||
const getLabelPrefix = (labelPrefix: string) => labelPrefix || DEFAULT_NETLIFY_CMS_LABEL_PREFIX; | ||
export const isCMSLabel = (label: string, labelPrefix: string) => | ||
label.startsWith(getLabelPrefix(labelPrefix)); | ||
export const labelToStatus = (label: string, labelPrefix: string) => | ||
label.substr(getLabelPrefix(labelPrefix).length); | ||
export const statusToLabel = (status: string, labelPrefix: string) => | ||
`${getLabelPrefix(labelPrefix)}${status}`; | ||
function getLabelPrefix(labelPrefix: string) { | ||
return labelPrefix || DEFAULT_NETLIFY_CMS_LABEL_PREFIX; | ||
} | ||
export const generateContentKey = (collectionName: string, slug: string) => | ||
`${collectionName}/${slug}`; | ||
export function isCMSLabel(label: string, labelPrefix: string) { | ||
return label.startsWith(getLabelPrefix(labelPrefix)); | ||
} | ||
export const parseContentKey = (contentKey: string) => { | ||
export function labelToStatus(label: string, labelPrefix: string) { | ||
return label.substr(getLabelPrefix(labelPrefix).length); | ||
} | ||
export function statusToLabel(status: string, labelPrefix: string) { | ||
return `${getLabelPrefix(labelPrefix)}${status}`; | ||
} | ||
export function generateContentKey(collectionName: string, slug: string) { | ||
return `${collectionName}/${slug}`; | ||
} | ||
export function parseContentKey(contentKey: string) { | ||
const index = contentKey.indexOf('/'); | ||
return { collection: contentKey.substr(0, index), slug: contentKey.substr(index + 1) }; | ||
}; | ||
} | ||
export const contentKeyFromBranch = (branch: string) => { | ||
export function contentKeyFromBranch(branch: string) { | ||
return branch.substring(`${CMS_BRANCH_PREFIX}/`.length); | ||
}; | ||
} | ||
export const branchFromContentKey = (contentKey: string) => { | ||
export function branchFromContentKey(contentKey: string) { | ||
return `${CMS_BRANCH_PREFIX}/${contentKey}`; | ||
}; | ||
} |
@@ -5,6 +5,6 @@ import semaphore from 'semaphore'; | ||
export const asyncLock = (): AsyncLock => { | ||
export function asyncLock(): AsyncLock { | ||
let lock = semaphore(1); | ||
const acquire = (timeout = 15000) => { | ||
function acquire(timeout = 15000) { | ||
const promise = new Promise<boolean>(resolve => { | ||
@@ -25,5 +25,5 @@ // this makes sure a caller doesn't gets stuck forever awaiting on the lock | ||
return promise; | ||
}; | ||
} | ||
const release = () => { | ||
function release() { | ||
try { | ||
@@ -42,5 +42,5 @@ // suppress too many calls to leave error | ||
} | ||
}; | ||
} | ||
return { acquire, release }; | ||
}; | ||
} |
@@ -9,16 +9,18 @@ import { flow, fromPairs } from 'lodash'; | ||
export const filterByExtension = (file: { path: string }, extension: string) => { | ||
export function filterByExtension(file: { path: string }, extension: string) { | ||
const path = file?.path || ''; | ||
return path.endsWith(extension.startsWith('.') ? extension : `.${extension}`); | ||
}; | ||
} | ||
const catchFormatErrors = (format: string, formatter: Formatter) => (res: Response) => { | ||
try { | ||
return formatter(res); | ||
} catch (err) { | ||
throw new Error( | ||
`Response cannot be parsed into the expected format (${format}): ${err.message}`, | ||
); | ||
} | ||
}; | ||
function catchFormatErrors(format: string, formatter: Formatter) { | ||
return (res: Response) => { | ||
try { | ||
return formatter(res); | ||
} catch (err) { | ||
throw new Error( | ||
`Response cannot be parsed into the expected format (${format}): ${err.message}`, | ||
); | ||
} | ||
}; | ||
} | ||
@@ -40,6 +42,6 @@ const responseFormatters = fromJS({ | ||
export const parseResponse = async ( | ||
export async function parseResponse( | ||
res: Response, | ||
{ expectingOk = true, format = 'text', apiName = '' }, | ||
) => { | ||
) { | ||
let body; | ||
@@ -61,11 +63,13 @@ try { | ||
return body; | ||
}; | ||
} | ||
export const responseParser = (options: { | ||
export function responseParser(options: { | ||
expectingOk?: boolean; | ||
format: string; | ||
apiName: string; | ||
}) => (res: Response) => parseResponse(res, options); | ||
}) { | ||
return (res: Response) => parseResponse(res, options); | ||
} | ||
export const parseLinkHeader = (header: string | null) => { | ||
export function parseLinkHeader(header: string | null) { | ||
if (!header) { | ||
@@ -86,5 +90,5 @@ return {}; | ||
])(header); | ||
}; | ||
} | ||
export const getAllResponses = async ( | ||
export async function getAllResponses( | ||
url: string, | ||
@@ -94,3 +98,3 @@ options: { headers?: {} } = {}, | ||
nextUrlProcessor: (url: string) => string, | ||
) => { | ||
) { | ||
const maxResponses = 30; | ||
@@ -115,7 +119,7 @@ let responseCount = 1; | ||
return pageResponses; | ||
}; | ||
} | ||
export const getPathDepth = (path: string) => { | ||
export function getPathDepth(path: string) { | ||
const depth = path.split('/').length; | ||
return depth; | ||
}; | ||
} |
@@ -30,3 +30,3 @@ import { fromJS, Map, Set } from 'immutable'; | ||
const jsToMap = (obj: {}) => { | ||
function jsToMap(obj: {}) { | ||
if (obj === undefined) { | ||
@@ -40,3 +40,3 @@ return Map(); | ||
return immutableObj; | ||
}; | ||
} | ||
@@ -54,5 +54,7 @@ const knownMetaKeys = Set([ | ||
]); | ||
const filterUnknownMetaKeys = (meta: Map<string, string>) => | ||
meta.filter((_v, k) => knownMetaKeys.has(k as string)); | ||
function filterUnknownMetaKeys(meta: Map<string, string>) { | ||
return meta.filter((_v, k) => knownMetaKeys.has(k as string)); | ||
} | ||
/* | ||
@@ -64,3 +66,3 @@ createCursorMap takes one of three signatures: | ||
*/ | ||
const createCursorStore = (...args: {}[]) => { | ||
function createCursorStore(...args: {}[]) { | ||
const { actions, data, meta } = | ||
@@ -78,11 +80,14 @@ args.length === 1 | ||
}) as CursorStore; | ||
}; | ||
} | ||
const hasAction = (store: CursorStore, action: string) => store.hasIn(['actions', action]); | ||
function hasAction(store: CursorStore, action: string) { | ||
return store.hasIn(['actions', action]); | ||
} | ||
const getActionHandlers = (store: CursorStore, handler: ActionHandler) => | ||
store | ||
function getActionHandlers(store: CursorStore, handler: ActionHandler) { | ||
return store | ||
.get('actions', Set<string>()) | ||
.toMap() | ||
.map(action => handler(action as string)); | ||
} | ||
@@ -89,0 +94,0 @@ // The cursor logic is entirely functional, so this class simply |
@@ -13,5 +13,14 @@ // | ||
const splitIntoLines = (str: string) => str.split('\n'); | ||
const splitIntoWords = (str: string) => str.split(/\s+/g); | ||
const isNonEmptyString = (str: string) => str !== ''; | ||
function splitIntoLines(str: string) { | ||
return str.split('\n'); | ||
} | ||
function splitIntoWords(str: string) { | ||
return str.split(/\s+/g); | ||
} | ||
function isNonEmptyString(str: string) { | ||
return str !== ''; | ||
} | ||
const withoutEmptyLines = flow([map((str: string) => str.trim()), filter(isNonEmptyString)]); | ||
@@ -33,5 +42,7 @@ export const parsePointerFile: (data: string) => PointerFile = flow([ | ||
const removeGitAttributesCommentsFromLine = (line: string) => line.split('#')[0]; | ||
function removeGitAttributesCommentsFromLine(line: string) { | ||
return line.split('#')[0]; | ||
} | ||
const parseGitPatternAttribute = (attributeString: string) => { | ||
function parseGitPatternAttribute(attributeString: string) { | ||
// There are three kinds of attribute settings: | ||
@@ -49,3 +60,3 @@ // - a key=val pair sets an attribute to a specific value | ||
return [attributeString, true]; | ||
}; | ||
} | ||
@@ -75,3 +86,4 @@ const parseGitPatternAttributes = flow([map(parseGitPatternAttribute), fromPairs]); | ||
export const createPointerFile = ({ size, sha }: PointerFile) => `\ | ||
export function createPointerFile({ size, sha }: PointerFile) { | ||
return `\ | ||
version https://git-lfs.github.com/spec/v1 | ||
@@ -81,2 +93,3 @@ oid sha256:${sha} | ||
`; | ||
} | ||
@@ -83,0 +96,0 @@ export async function getPointerFileForMediaFileObj( |
@@ -203,3 +203,3 @@ import semaphore, { Semaphore } from 'semaphore'; | ||
const fetchFiles = async ( | ||
async function fetchFiles( | ||
files: ImplementationFile[], | ||
@@ -209,3 +209,3 @@ readFile: ReadFile, | ||
apiName: string, | ||
) => { | ||
) { | ||
const sem = semaphore(MAX_CONCURRENT_DOWNLOADS); | ||
@@ -236,5 +236,5 @@ const promises = [] as Promise<ImplementationEntry | { error: boolean }>[]; | ||
) as Promise<ImplementationEntry[]>; | ||
}; | ||
} | ||
export const entriesByFolder = async ( | ||
export async function entriesByFolder( | ||
listFiles: () => Promise<ImplementationFile[]>, | ||
@@ -244,8 +244,8 @@ readFile: ReadFile, | ||
apiName: string, | ||
) => { | ||
) { | ||
const files = await listFiles(); | ||
return fetchFiles(files, readFile, readFileMetadata, apiName); | ||
}; | ||
} | ||
export const entriesByFiles = async ( | ||
export async function entriesByFiles( | ||
files: ImplementationFile[], | ||
@@ -255,7 +255,7 @@ readFile: ReadFile, | ||
apiName: string, | ||
) => { | ||
) { | ||
return fetchFiles(files, readFile, readFileMetadata, apiName); | ||
}; | ||
} | ||
export const unpublishedEntries = async (listEntriesKeys: () => Promise<string[]>) => { | ||
export async function unpublishedEntries(listEntriesKeys: () => Promise<string[]>) { | ||
try { | ||
@@ -270,10 +270,10 @@ const keys = await listEntriesKeys(); | ||
} | ||
}; | ||
} | ||
export const blobToFileObj = (name: string, blob: Blob) => { | ||
export function blobToFileObj(name: string, blob: Blob) { | ||
const options = name.match(/.svg$/) ? { type: 'image/svg+xml' } : {}; | ||
return new File([blob], name, options); | ||
}; | ||
} | ||
export const getMediaAsBlob = async (path: string, id: string | null, readFile: ReadFile) => { | ||
export async function getMediaAsBlob(path: string, id: string | null, readFile: ReadFile) { | ||
let blob: Blob; | ||
@@ -287,9 +287,9 @@ if (path.match(/.svg$/)) { | ||
return blob; | ||
}; | ||
} | ||
export const getMediaDisplayURL = async ( | ||
export async function getMediaDisplayURL( | ||
displayURL: DisplayURL, | ||
readFile: ReadFile, | ||
semaphore: Semaphore, | ||
) => { | ||
) { | ||
const { path, id } = displayURL as DisplayURLObject; | ||
@@ -304,5 +304,5 @@ return new Promise<string>((resolve, reject) => | ||
); | ||
}; | ||
} | ||
export const runWithLock = async (lock: AsyncLock, func: Function, message: string) => { | ||
export async function runWithLock(lock: AsyncLock, func: Function, message: string) { | ||
try { | ||
@@ -319,3 +319,3 @@ const acquired = await lock.acquire(); | ||
} | ||
}; | ||
} | ||
@@ -336,5 +336,5 @@ const LOCAL_KEY = 'git.local'; | ||
const getLocalKey = ({ branch, folder, extension, depth }: GetKeyArgs) => { | ||
function getLocalKey({ branch, folder, extension, depth }: GetKeyArgs) { | ||
return `${LOCAL_KEY}.${branch}.${folder}.${extension}.${depth}`; | ||
}; | ||
} | ||
@@ -350,3 +350,3 @@ type PersistLocalTreeArgs = GetKeyArgs & { | ||
export const persistLocalTree = async ({ | ||
export async function persistLocalTree({ | ||
localForage, | ||
@@ -358,3 +358,3 @@ localTree, | ||
depth, | ||
}: PersistLocalTreeArgs) => { | ||
}: PersistLocalTreeArgs) { | ||
await localForage.setItem<LocalTree>( | ||
@@ -364,5 +364,5 @@ getLocalKey({ branch, folder, extension, depth }), | ||
); | ||
}; | ||
} | ||
export const getLocalTree = async ({ | ||
export async function getLocalTree({ | ||
localForage, | ||
@@ -373,3 +373,3 @@ branch, | ||
depth, | ||
}: GetLocalTreeArgs) => { | ||
}: GetLocalTreeArgs) { | ||
const localTree = await localForage.getItem<LocalTree>( | ||
@@ -379,3 +379,3 @@ getLocalKey({ branch, folder, extension, depth }), | ||
return localTree; | ||
}; | ||
} | ||
@@ -405,3 +405,3 @@ type GetDiffFromLocalTreeMethods = { | ||
const getDiffFromLocalTree = async ({ | ||
async function getDiffFromLocalTree({ | ||
branch, | ||
@@ -413,3 +413,3 @@ localTree, | ||
getFileId, | ||
}: GetDiffFromLocalTreeArgs) => { | ||
}: GetDiffFromLocalTreeArgs) { | ||
const diff = await getDifferences(branch.sha, localTree.head); | ||
@@ -461,3 +461,3 @@ const diffFiles = diff | ||
return diffFilesWithIds; | ||
}; | ||
} | ||
@@ -479,3 +479,3 @@ type AllEntriesByFolderArgs = GetKeyArgs & | ||
export const allEntriesByFolder = async ({ | ||
export async function allEntriesByFolder({ | ||
listAllFiles, | ||
@@ -495,4 +495,4 @@ readFile, | ||
filterFile, | ||
}: AllEntriesByFolderArgs) => { | ||
const listAllFilesAndPersist = async () => { | ||
}: AllEntriesByFolderArgs) { | ||
async function listAllFilesAndPersist() { | ||
const files = await listAllFiles(folder, extension, depth); | ||
@@ -512,5 +512,5 @@ const branch = await getDefaultBranch(); | ||
return files; | ||
}; | ||
} | ||
const listFiles = async () => { | ||
async function listFiles() { | ||
const localTree = await getLocalTree({ localForage, branch, folder, extension, depth }); | ||
@@ -550,4 +550,2 @@ if (localTree) { | ||
} else { | ||
// refresh local copy | ||
const identity = (file: { path: string }) => file.path; | ||
const deleted = diff.reduce((acc, d) => { | ||
@@ -561,5 +559,5 @@ acc[d.path] = d.deleted; | ||
localTree.files.filter(f => !deleted[f.path]), | ||
identity, | ||
file => file.path, | ||
), | ||
identity, | ||
file => file.path, | ||
); | ||
@@ -581,6 +579,6 @@ | ||
} | ||
}; | ||
} | ||
const files = await listFiles(); | ||
return fetchFiles(files, readFile, readFileMetadata, apiName); | ||
}; | ||
} |
const absolutePath = new RegExp('^(?:[a-z]+:)?//', 'i'); | ||
const normalizePath = (path: string) => path.replace(/[\\/]+/g, '/'); | ||
function normalizePath(path: string) { | ||
return path.replace(/[\\/]+/g, '/'); | ||
} | ||
export function isAbsolutePath(path: string) { | ||
@@ -5,0 +8,0 @@ return absolutePath.test(path); |
import flow from 'lodash/flow'; | ||
export const then = <T, V>(fn: (r: T) => V) => (p: Promise<T>) => Promise.resolve(p).then(fn); | ||
export function then<T, V>(fn: (r: T) => V) { | ||
return (p: Promise<T>) => Promise.resolve(p).then(fn); | ||
} | ||
const filterPromiseSymbol = Symbol('filterPromiseSymbol'); | ||
export const onlySuccessfulPromises = (promises: Promise<unknown>[]) => { | ||
export function onlySuccessfulPromises(promises: Promise<unknown>[]) { | ||
return Promise.all(promises.map(p => p.catch(() => filterPromiseSymbol))).then(results => | ||
results.filter(result => result !== filterPromiseSymbol), | ||
); | ||
}; | ||
} | ||
const wrapFlowAsync = (fn: Function) => async (arg: unknown) => fn(await arg); | ||
export const flowAsync = (fns: Function[]) => flow(fns.map(fn => wrapFlowAsync(fn))); | ||
function wrapFlowAsync(fn: Function) { | ||
return async (arg: unknown) => fn(await arg); | ||
} | ||
export function flowAsync(fns: Function[]) { | ||
return flow(fns.map(fn => wrapFlowAsync(fn))); | ||
} |
@@ -6,3 +6,3 @@ import { fromJS, List, Map } from 'immutable'; | ||
const isAbortControllerSupported = () => { | ||
function isAbortControllerSupported() { | ||
if (typeof window !== 'undefined') { | ||
@@ -12,6 +12,7 @@ return !!window.AbortController; | ||
return false; | ||
}; | ||
} | ||
const timeout = 60; | ||
const fetchWithTimeout = (input, init) => { | ||
function fetchWithTimeout(input, init) { | ||
if ((init && init.signal) || !isAbortControllerSupported()) { | ||
@@ -33,38 +34,43 @@ return fetch(input, init); | ||
}); | ||
}; | ||
} | ||
const decodeParams = paramsString => | ||
List(paramsString.split('&')) | ||
function decodeParams(paramsString) { | ||
return List(paramsString.split('&')) | ||
.map(s => List(s.split('=')).map(decodeURIComponent)) | ||
.update(Map); | ||
} | ||
const fromURL = wholeURL => { | ||
function fromURL(wholeURL) { | ||
const [url, allParamsString] = wholeURL.split('?'); | ||
return Map({ url, ...(allParamsString ? { params: decodeParams(allParamsString) } : {}) }); | ||
}; | ||
} | ||
const fromFetchArguments = (wholeURL, options) => { | ||
function fromFetchArguments(wholeURL, options) { | ||
return fromURL(wholeURL).merge( | ||
(options ? fromJS(options) : Map()).remove('url').remove('params'), | ||
); | ||
}; | ||
} | ||
const encodeParams = params => | ||
params | ||
function encodeParams(params) { | ||
return params | ||
.entrySeq() | ||
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`) | ||
.join('&'); | ||
} | ||
const toURL = req => | ||
`${req.get('url')}${req.get('params') ? `?${encodeParams(req.get('params'))}` : ''}`; | ||
function toURL(req) { | ||
return `${req.get('url')}${req.get('params') ? `?${encodeParams(req.get('params'))}` : ''}`; | ||
} | ||
const toFetchArguments = req => [ | ||
toURL(req), | ||
req | ||
.remove('url') | ||
.remove('params') | ||
.toJS(), | ||
]; | ||
function toFetchArguments(req) { | ||
return [ | ||
toURL(req), | ||
req | ||
.remove('url') | ||
.remove('params') | ||
.toJS(), | ||
]; | ||
} | ||
const maybeRequestArg = req => { | ||
function maybeRequestArg(req) { | ||
if (isString(req)) { | ||
@@ -77,6 +83,12 @@ return fromURL(req); | ||
return Map(); | ||
}; | ||
const ensureRequestArg = func => req => func(maybeRequestArg(req)); | ||
const ensureRequestArg2 = func => (arg, req) => func(arg, maybeRequestArg(req)); | ||
} | ||
function ensureRequestArg(func) { | ||
return req => func(maybeRequestArg(req)); | ||
} | ||
function ensureRequestArg2(func) { | ||
return (arg, req) => func(arg, maybeRequestArg(req)); | ||
} | ||
// This actually performs the built request object | ||
@@ -91,6 +103,11 @@ const performRequest = ensureRequestArg(req => { | ||
const getCurriedRequestProcessor = flow([ensureRequestArg2, curry]); | ||
const getPropSetFunction = path => getCurriedRequestProcessor((val, req) => req.setIn(path, val)); | ||
const getPropMergeFunction = path => | ||
getCurriedRequestProcessor((obj, req) => req.updateIn(path, (p = Map()) => p.merge(obj))); | ||
function getPropSetFunction(path) { | ||
return getCurriedRequestProcessor((val, req) => req.setIn(path, val)); | ||
} | ||
function getPropMergeFunction(path) { | ||
return getCurriedRequestProcessor((obj, req) => req.updateIn(path, (p = Map()) => p.merge(obj))); | ||
} | ||
const withMethod = getPropSetFunction(['method']); | ||
@@ -97,0 +114,0 @@ const withBody = getPropSetFunction(['body']); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
862298
0.11%4129
2.41%