| # To get started with Dependabot version updates, you'll need to specify which | ||
| # package ecosystems to update and where the package manifests are located. | ||
| # Please see the documentation for all configuration options: | ||
| # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates | ||
| version: 2 | ||
| updates: | ||
| - package-ecosystem: "" # See documentation for possible values | ||
| directory: "/" # Location of package manifests | ||
| schedule: | ||
| interval: "weekly" | ||
+21
| # Security Policy | ||
| ## Supported Versions | ||
| Use this section to tell people about which versions of your project are | ||
| currently being supported with security updates. | ||
| | Version | Supported | | ||
| | ------- | ------------------ | | ||
| | 5.1.x | :white_check_mark: | | ||
| | 5.0.x | :x: | | ||
| | 4.0.x | :white_check_mark: | | ||
| | < 4.0 | :x: | | ||
| ## Reporting a Vulnerability | ||
| Use this section to tell people how to report a vulnerability. | ||
| Tell them where to go, how often they can expect to get an update on a | ||
| reported vulnerability, what to expect if the vulnerability is accepted or | ||
| declined, etc. |
+8
-9
| #!/usr/bin/env node | ||
| const path = require('path') | ||
| const commander = require('commander') | ||
| const { program } = require('commander'); | ||
| const hexoPost = require('../lib') | ||
| commander | ||
| program | ||
| .version('1.0.0', '-V, --version') | ||
@@ -15,13 +15,12 @@ .option('-c --config [config]', 'path to config file', String) | ||
| // console.log(commander) | ||
| const options = program.opts() | ||
| if (commander.config && commander.output) { | ||
| hexoPost.g(path.resolve(commander.config), path.resolve(process.cwd(), commander.output), {verbose: commander.verbose}) | ||
| if (options.config && options.output) { | ||
| hexoPost.g(path.resolve(options.config), path.resolve(process.cwd(), options.output), {verbose: options.verbose}) | ||
| } | ||
| else if (commander.output) { | ||
| hexoPost.g(path.resolve(process.cwd()), path.resolve(process.cwd(), commander.output), {verbose: commander.verbose}) | ||
| else if (options.output) { | ||
| hexoPost.g(path.resolve(process.cwd()), path.resolve(process.cwd(), options.output), {verbose: options.verbose}) | ||
| } | ||
| else { | ||
| commander.help() | ||
| process.exit() | ||
| program.help() | ||
| } |
+73
-21
@@ -24,3 +24,3 @@ | ||
| const configs = yaml.safeLoadAll(configFileContents) | ||
| const configs = yaml.loadAll(configFileContents) | ||
@@ -40,2 +40,4 @@ const srcArticleFileSet = new Set() | ||
| const hexoPostDir = path.join(hexoRepoPath, 'source/_posts') | ||
| const hexoImageDir = path.join(hexoRepoPath, 'source/images') | ||
| const copiedImageDestinationPathSet = new Set() | ||
| const dstArticleFiles = [] | ||
@@ -57,24 +59,55 @@ configs.forEach((config) => { | ||
| // 替换图片地址 | ||
| let imageRegexpExecResult | ||
| const imageRegexp = /!\[(.*)\]\((.*)\)/gim | ||
| while ((imageRegexpExecResult = imageRegexp.exec(content))) { | ||
| const imagePath = imageRegexpExecResult[2] | ||
| if (imagePath && !isHttpLink(imagePath)) { | ||
| if (!post.imageBaseUrl) { | ||
| post.imageBaseUrl = config.repository | ||
| // 拷贝图片到 Hexo 目录并更新引用 | ||
| const normalizedPostPath = normalizeToPosixPath(post.path) | ||
| const postDirectory = path.posix.dirname(normalizedPostPath) | ||
| const baseImagePathSegments = postDirectory === '.' ? [] : postDirectory.split('/') | ||
| const imageRegexp = /!\[(.*?)\]\((.*?)\)/gim | ||
| content = content.replace(imageRegexp, (matchedMarkdown, altText, rawImagePath) => { | ||
| const trimmedImagePath = rawImagePath.trim() | ||
| if (!trimmedImagePath || isHttpLink(trimmedImagePath) || trimmedImagePath.startsWith('/')) { | ||
| return matchedMarkdown | ||
| } | ||
| const sourceImageAbsolutePath = path.resolve(path.dirname(src), trimmedImagePath) | ||
| if (!fs.existsSync(sourceImageAbsolutePath) || fs.statSync(sourceImageAbsolutePath).isDirectory()) { | ||
| log('\tSkip Image Copy (missing file):', trimmedImagePath) | ||
| return matchedMarkdown | ||
| } | ||
| const normalizedImagePath = normalizeToPosixPath(trimmedImagePath) | ||
| const imageDirectoryWithinPost = path.posix.dirname(normalizedImagePath) | ||
| const destinationPathSegments = baseImagePathSegments.slice() | ||
| if (imageDirectoryWithinPost !== '.' && imageDirectoryWithinPost !== '/') { | ||
| destinationPathSegments.push(...imageDirectoryWithinPost.split('/').filter(Boolean)) | ||
| } | ||
| const imageFileName = path.posix.basename(normalizedImagePath) | ||
| destinationPathSegments.push(imageFileName) | ||
| const destinationImageAbsolutePath = path.join(hexoImageDir, ...destinationPathSegments) | ||
| if (!copiedImageDestinationPathSet.has(destinationImageAbsolutePath)) { | ||
| try { | ||
| const fileUpdated = copyFileEnsuringDirectory(sourceImageAbsolutePath, destinationImageAbsolutePath) | ||
| if (fileUpdated) { | ||
| log('\tCopy Image:', sourceImageAbsolutePath, '->', destinationImageAbsolutePath) | ||
| } | ||
| else { | ||
| log('\tReuse Existing Image:', destinationImageAbsolutePath) | ||
| } | ||
| copiedImageDestinationPathSet.add(destinationImageAbsolutePath) | ||
| } | ||
| if (!post.imageBaseUrl.endsWith('/')) { | ||
| post.imageBaseUrl += '/' | ||
| catch (error) { | ||
| log('\tCopy Image Failed:', sourceImageAbsolutePath, '->', destinationImageAbsolutePath, error.message) | ||
| return matchedMarkdown | ||
| } | ||
| post.imageBaseUrl = post.imageBaseUrl.replace('github.com', 'raw.githubusercontent.com') | ||
| const newImagePath = `${post.imageBaseUrl}master/${path.dirname(post.path)}/${imagePath}` | ||
| const from = imageRegexpExecResult[0] | ||
| const to = `![${imageRegexpExecResult[1]}](${newImagePath})` | ||
| log('\tReplace Image Url:', from, '->', to) | ||
| content = content.replace(from, to) | ||
| } | ||
| } | ||
| // 替换连接地址 | ||
| const relativePathToImage = normalizeToPosixPath(path.relative(path.dirname(dst), destinationImageAbsolutePath)) | ||
| const markdownImagePath = relativePathToImage.startsWith('.') ? relativePathToImage : `./${relativePathToImage}` | ||
| const updatedMarkdown = `` | ||
| log('\tUpdate Image Path:', matchedMarkdown, '->', updatedMarkdown) | ||
| return updatedMarkdown | ||
| }) | ||
| // 替换链接地址 | ||
| let linkRegexpExecResult | ||
@@ -113,3 +146,3 @@ const linkRegexp = /[^!]\[(.*)\]\((.*)\)/gim | ||
| } | ||
| const tags = Array.isArray(post.tags) ? post.tags : (post.tags || '').split(' ') | ||
@@ -135,3 +168,3 @@ const categories = Array.isArray(post.categories) ? post.categories : (post.categories || '未分类').split(' ') | ||
| + '\n' | ||
| mkdirp.sync(path.dirname(dst)) | ||
@@ -149,2 +182,21 @@ fs.writeFileSync(dst, content, {encoding: 'utf8'}) | ||
| function normalizeToPosixPath(filePath) { | ||
| return filePath.replace(/\\/g, '/') | ||
| } | ||
| function copyFileEnsuringDirectory(sourcePath, destinationPath) { | ||
| mkdirp.sync(path.dirname(destinationPath)) | ||
| if (fs.existsSync(destinationPath)) { | ||
| const existingFileBuffer = fs.readFileSync(destinationPath) | ||
| const nextFileBuffer = fs.readFileSync(sourcePath) | ||
| if (existingFileBuffer.equals(nextFileBuffer)) { | ||
| return false | ||
| } | ||
| } | ||
| fs.copyFileSync(sourcePath, destinationPath) | ||
| return true | ||
| } | ||
| function isHttpLink(href) { | ||
@@ -151,0 +203,0 @@ return (href.startsWith('http://') || href.startsWith('https://')) |
+8
-10
| { | ||
| "name": "hexo-post", | ||
| "version": "1.4.0", | ||
| "version": "1.5.0", | ||
| "description": "", | ||
@@ -15,12 +15,10 @@ "main": "lib/index.js", | ||
| "dependencies": { | ||
| "@types/commander": "^2.12.2", | ||
| "@types/js-yaml": "^3.11.1", | ||
| "@types/markdown-it": "0.0.4", | ||
| "@types/mkdirp": "^0.5.2", | ||
| "commander": "^2.15.1", | ||
| "js-yaml": "^3.11.0", | ||
| "markdown-it": "^8.4.1", | ||
| "markdown-toc": "^1.2.0", | ||
| "mkdirp": "^0.5.1" | ||
| "@types/commander": "^2.12.5", | ||
| "@types/js-yaml": "^4.0.9", | ||
| "@types/markdown-it": "^14.1.2", | ||
| "@types/mkdirp": "^2.0.0", | ||
| "commander": "^14.0.2", | ||
| "js-yaml": "^4.1.1", | ||
| "mkdirp": "^3.0.1" | ||
| } | ||
| } |
+55
-23
@@ -5,33 +5,65 @@ # README | ||
| ### Example | ||
| ## Example | ||
| hexo.yaml | ||
| example [hexo.yaml](https://github.com/c-cc-cc/knowledge/blob/master/hexo.yaml) | ||
| ```yaml | ||
| repository: https://github.com/c-cc-cc/knowledge | ||
| posts: | ||
| - title: JavaScript基础 | ||
| date: 2018-04-11 22:05:14 | ||
| path: langs/ecmascript/javascript-base.md | ||
| imageBaseUrl: https://raw.githubusercontent.com/liuyanjie/knowledge/master/langs/ecmascript/ | ||
| categories: | ||
| - Syntax | ||
| - JavaScript | ||
| tags: | ||
| - JavaScript | ||
| - JavaScript基础 | ||
| - title: libuv源码分析(一)全局概览(Overview) | ||
| date: 2019-04-23 23:00:01+0800 | ||
| path: node.js/libuv/1-libuv-overview.md | ||
| categories: [源码分析] | ||
| tags: [libuv, node.js, eventloop] | ||
| - title: libuv源码分析(二)事件循环(Eventloop) | ||
| date: 2019-04-23 23:00:02+0800 | ||
| path: node.js/libuv/2-libuv-event-loop.md | ||
| categories: [源码分析] | ||
| tags: [libuv, node.js, eventloop] | ||
| - title: libuv源码分析(三)资源抽象:Handle 和 Request | ||
| date: 2019-04-23 23:00:03+0800 | ||
| path: node.js/libuv/3-libuv-handle-and-request.md | ||
| categories: [源码分析] | ||
| tags: [libuv, node.js, eventloop] | ||
| - title: libuv源码分析(四)定时器(Timer) | ||
| date: 2019-04-23 23:00:04+0800 | ||
| path: node.js/libuv/4-libuv-timer.md | ||
| categories: [源码分析] | ||
| tags: [libuv, node.js, eventloop] | ||
| - title: libuv源码分析(五)IO观察者(io_watcher) | ||
| date: 2019-04-23 23:00:05+0800 | ||
| path: node.js/libuv/5-libuv-io-watcher.md | ||
| categories: [源码分析] | ||
| tags: [libuv, node.js, eventloop] | ||
| - title: libuv源码分析(六)流(Stream) | ||
| date: 2019-04-23 23:00:06+0800 | ||
| path: node.js/libuv/6-libuv-stream.md | ||
| categories: [源码分析] | ||
| tags: [libuv, node.js, eventloop] | ||
| - title: libuv源码分析(七)异步唤醒(Async) | ||
| date: 2019-04-23 23:00:07+0800 | ||
| path: node.js/libuv/7-libuv-async.md | ||
| categories: [源码分析] | ||
| tags: [libuv, node.js, eventloop] | ||
| - title: libuv源码分析(八)线程池(Threadpool) | ||
| date: 2019-04-23 23:00:08+0800 | ||
| path: node.js/libuv/8-libuv-threadpool.md | ||
| categories: [源码分析] | ||
| tags: [libuv, node.js, eventloop] | ||
| - title: JavaScript深度 | ||
| date: 2018-05-02 | ||
| path: langs/ecmascript/javascript-deep.md | ||
| imageBaseUrl: https://raw.githubusercontent.com/liuyanjie/knowledge/master/langs/ecmascript/ | ||
| categories: | ||
| - Syntax | ||
| - JavaScript | ||
| tags: | ||
| - JavaScript | ||
| - JavaScript执行上下文、变量对象、活动对象、词法作用域、闭包、执行过程 | ||
| - title: Git对象模型:一步一步分析Git底层对象模型 | ||
| date: 2019-06-24 19:00:00+0800 | ||
| path: vcs/git/git-object-model.md | ||
| categories: [git] | ||
| tags: [vcs, git] | ||
| - title: Git命令工作机制 | ||
| date: 2019-06-24 20:00:00+0800 | ||
| path: vcs/git/git-working-mechanism.md | ||
| categories: [git] | ||
| tags: [vcs, git] | ||
| ``` | ||
| ```sh | ||
| hexo-post -f path/to/hexo.yaml | ||
| hexo-post -v -c path/to/config-dir -o . | ||
| ``` |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
38529
14.74%7
-22.22%8
33.33%205
25.77%69
86.49%2
-33.33%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated
Updated
Updated
Updated