Security News
PyPI’s New Archival Feature Closes a Major Security Gap
PyPI now allows maintainers to archive projects, improving security and helping users make informed decisions about their dependencies.
@esydoc/doclet-parser
Advanced tools
Take the doclet root to parse be a whole AST.
What is the doclet?
可以理解它为一个对注释的一个抽象
,通常 babel 解析 JS AST 的时候,是不会处理 comment 节点(它只是个字符串),
而jsdoc
则利用 babel 提供的 hooks, 拿到 comment 再进行二次解析,转成 doclet 对象。
Doclet vs AST
Doclet
与 AST
最大区别在于,Doclet
节点都是属于离散的节点,它只保留子树的 key,而不是子树,这就意味着它并不是一颗完整的 AST,
而我们渲染数据的时候却需要, 这时候需要 doclet-parser
为我们处理这一难题。
举例子:
/**
* 小程序入口控制参数
* @edata
* @typedef {Object} EntranceReq
* @property {string} extType
* @property {boolean} visible 入口是否显示
* @property {Object} [param] 自定义参数
*/
/**
* 小程序入口控制
* @eapi
* @param {EntranceReq} params 输入参数
* @returns {Promise<any>}
*/
localControlEntrance(params) {
return extsdk.core.callEvent(MODULE_NAME, 'localControlEntrance', params);
},
转换后的 api doclet 是这样的:
// 伪代码 doclet对象
const apiDoclet = {
name: 'localControlEntrance',
params: [
{
type: {
names: ['EntranceReq'] // 这里这是一个key, 标记引用的节点,而不是实际的AST
},
name: 'params'
}
],
....
}
const EntranceReqDoclect = {
name: EntranceReq,
type: {
names: ['Object']
}
properties: [
{
name: 'extType',
types: {
{
names: ['string']
}
}
},
...
]
}
经过 doclet-parser 处理之后:
// params 转抽象为一个 root 节点
const root = {
name: 'root',
type: 'Array',
properties: [
{
name: 'params',
type: 'Object',
properties: [
{
name: 'extType',
type: 'string'
},
...
]
}
]
}
看到转换后的节点我们发现离散的 doclet 节点都被适当地抽象融合到了一个颗 root 树上,这样我们就可以使用 root 树去渲染各种数据啦~。
import DocletParser from '@esydoc/doclet-parser'
export type DataMap = Map<string, RawDataTreeNode> // RawDataTreeNode 其实就是 doclet
export type FileDataMap = Map<string | symbol, DataMap> // key 代表的是文件路径,用来收集沿路`@edata`标记的数据节点
const fileDataMap = new Map() // 存有 doclet 信息的 map
const parser = new DocletParser(fileDataMap)
parser.parse(apiDoclet, reflectConfig): ParsedResult
- 将 apiDoclet 节点转换为一颗完整 AST,其中 apiDoclet 是通过@eapi标签
标记的注释节点,而reflectConfig 配置是一个格式化 Doclet 字段的一个映射配置。reflectConfig
介绍
export const ApiReflectConfig = Object.freeze({
args: {
key: 'args',
reflectKey: 'params',
format: (data: any) => {
return [data] // args是一个二维数组
},
nodeType: 'Array'
},
ret: {
key: 'ret',
reflectKey: 'returns',
format: (data: any) => {
return data // expect是一个一维数组
},
nodeType: 'Array'
}
})
如何获取上述默认配置?
import {
ApiReflectConfig,
} from '@esydoc/doclet-parser'
ParsedResult数据结构:
export type TransformedDataTreeNode = {
name: string
properties?: TransformedDataTreeNode[]
parent: TransformedDataTreeNode | null
description?: string
optional?: boolean
type: string
id: string
rawType?: string
}
type ParsedResult = {
[key: string]: TransformedDataTreeNode;
} | null
节点相关操作
function traverseNode(
node: TransformedDataTreeNode, // root
onPush: (node: TransformedDataTreeNode) => void, // 访问节点回调
onPop: (node: TransformedDataTreeNode) => void // 访问节点回调
): void
虽然用递归的方式计算深度比较简单,但因为栈的原因,不能提前结束,所以采用循环比较合理
const widthFirstTraverseNode = (
node: DataTreeNode, // root
visit: (node: DataTreeNode, depth: number) => boolean | void // 访问节点回调
): void
function transofrmDataTreeNode2Value(node: DataTreeNode): any
以上文提到的 root 为例子:
const root = {
name: 'root',
type: 'Array',
properties: [
{
name: 'params',
type: 'Object',
properties: [
{
name: 'extType',
type: 'string'
},
...
]
}
]
}
const val = transofrmDataTreeNode2Value(root)
// 以下val是root实际生成的值
val = [
{
extType: ''
}
]
isDateTreeNode(node: DataTreeNode): boolean - 是否是 DataTreeNode
getFirstChild(node: DataTreeNode): DataTreeNode | null - 获取第一个子节点
isMutiValueNode(node: DataTreeNode): boolean - 该节点是否是一个多分支节点,例如:enum节点,polytype节点 (a|b|c)
unwrap(node: DataTreeNode): DataTreeNode - 提取 doclet root 实际有效的节点
doclet root 有两种形态:args, ret
/**
* @eapi
* @param {EntranceReq} params -> args
* @returns {Promise<any>} -> ret
*/
localControlEntrance(params) {
return extsdk.core.callEvent(MODULE_NAME, 'localControlEntrance', params);
}
从上述代码我们可以看出,@param
和 @returns
分别 转换为 doclet root 的 args 和 ret 两种形态。
此时,我们使用unwarp进行解包可以速度拿到关键数据:
const unwarpedArgs = unwrap(argsDocletRoot) // => got 'param(EntranceReq)' node
const unwarpedRet = unwrap(retDocletRoot) // => got 'any' node directly without promise & parent root
type CleanRuleObj = {
key: keyof TransformedDataTreeNode,
assert: string | ((val: any) => boolean) // - true,删除该字段,反之亦然
}
type CleanRule = keyof TransformedDataTreeNode | CleanRuleObj
// 默认配置
const cleanDefaultRules: CleanRule[] = [
'description', // 直接传字符串,则直接删除
'parent',
'id',
{
key: 'properties',
assert: 'undefined' // assert 既可以是字符串,此时会默认通过
// typeof val === assert 判断字段是否删除,
// 也可以传一个((val: any) => boolean)回调,自己控制字段是否删除
},
{
key: 'optional',
assert: 'undefined'
},
{
key: 'rawType',
assert: 'undefined'
}
]
// declare
function clean(tree: TransformedDataTreeNode, rules: CleanRule[] = cleanDefaultRules): TransformedDataTreeNode
通用相关操作
引用方式
import {
genUniId,
clean,
unwrap,
getFirstChild,
isDateTreeNode,
transofrmDataTreeNode2Value,
widthFirstTraverseNode,
traverseNode
} from '@esydoc/doclet-parser'
FAQs
The parser for doclet that it resolved by jsdoc
The npm package @esydoc/doclet-parser receives a total of 35 weekly downloads. As such, @esydoc/doclet-parser popularity was classified as not popular.
We found that @esydoc/doclet-parser demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now allows maintainers to archive projects, improving security and helping users make informed decisions about their dependencies.
Research
Security News
Malicious npm package postcss-optimizer delivers BeaverTail malware, targeting developer systems; similarities to past campaigns suggest a North Korean connection.
Security News
CISA's KEV data is now on GitHub, offering easier access, API integration, commit history tracking, and automated updates for security teams and researchers.