npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

apass-opensdk-hugong

v1.0.17

Published

飞书Apass低代码平台-飞书开放平台-相关的接口整合和常用的方法整合

Readme

apass-opensdk-hugong

面向飞书低代码平台(APASS)开发者的 Node.js SDK,也兼容传统 Node.js。


目录


安装

飞书低代码平台(云函数):

依赖管理 → 右侧 → 搜索:apass-opensdk-hugong
⚠️ 记得升级到最新版本


快速开始

const Hugong = require('apass-opensdk-hugong');

// APASS 云函数:传入平台 logger
const hg = new Hugong(logger);

// 传统 Node.js:可省略 logger,默认使用 console
// const hg = new Hugong();

// 正式环境关闭调试日志(log / log4 / log8);error / warn 仍会输出
hg.setLogEnabled(false);
// 或:new Hugong(logger, { enableLog: false })

HG 核心

挂在实例 hg 上的通用能力。

// 重试
const result = await hg.retry(async () => {
  return await hg.utils.file.downloadFileToUpload(url, 'a.xlsx');
}, { retryCount: 3, retryDelay: 2000 });

// 计时
hg.newTime();
// ... do something
hg.printTime();
// 或:await hg.timeRun(async () => { /* ... */ });

// 睡眠(毫秒)
await hg.sleep(2000);

// 安全深层取值
hg.toValue({ a: { b: { c: 'value' } } }, 'a.b.c', 'default');

// 多语言:开放平台格式 → APASS Multilingual
hg.toMultilingualByOpenPlatform([
  { lang: 'en-US', value: 'Regular' },
  { lang: 'zh-CN', value: '正式' },
]);
hg.toMultilingualByOpenPlatform(zh, en);

// 多语言数组取中文文案
hg.toTextByMultilingual([{ language_code: '2052', text: '正式' }]);

对象操作 hg.object

// 查询列表(可流式回调;大数据推荐传 callback)
const list = await hg.object.findList('object_api', ['_id', '_name'], { /* where */ });
await hg.object.findList('object_api', ['_id'], null, async (records) => {
  // 每批处理
});

// 系统权限版本
await hg.object.findListUseSystemAuth('object_api', ['_id'], where);

// 单条
await hg.object.findOne('object_api', ['_id', '_name'], where);
await hg.object.findOneById('object_api', id, ['_id', '_name']);

// OQL
await hg.object.oql('SELECT _id FROM object_api WHERE ...', { /* nameArgs */ });
await hg.object.oqlUseSystemAuth('SELECT _id FROM object_api');
await hg.object.oqlPaging('SELECT _id FROM object_api', null, async (records) => {
  // 每页 200 条
});

// 增删改
await hg.object.create('object_api', data);
await hg.object.batchCreate('object_api', list);
await hg.object.update('object_api', data);
await hg.object.batchUpdate('object_api', list);
await hg.object.deleteOne('object_api', _id);
await hg.object.deleteBatchByIds('object_api', [_id1, _id2]);

// 元数据 / 其他
await hg.object.getFields('object_api');
await hg.object.clearData('object_api', where); // 慎用

多数写接口最后一个参数为 useSystemAuth(默认 false)。


字符串 hg.utils.str

// 模板
hg.utils.str.format('去{}买{}', '市场', '鱼');
hg.utils.str.formatByMap('{a} and {b}', { a: 'x', b: 'y' });
hg.utils.str.formatByMap('{0}-{1}', ['甲', '乙']);
hg.utils.str.formatByMap('你好 {user.name}', { user: { name: '张三' } });
hg.utils.str.formatByMap('价格 \\{amount\\}={amount}', { amount: 9 }); // => 价格 {amount}=9
hg.utils.str.formatByMap('a={a}', { a: null }, true); // ignoreNull:保留 {a}

// 空值 / 裁剪
hg.utils.str.isBlank('  ');
hg.utils.str.defaultIfBlank('', '默认');
hg.utils.str.trimAll(' a  b\nc '); // => 'abc'

// 大小写 / 命名
hg.utils.str.toUpper('abc');
hg.utils.str.capitalize('hELLO');       // => 'Hello'
hg.utils.str.camelCase('user_name');    // => 'userName'
hg.utils.str.snakeCase('userName');     // => 'user_name'
hg.utils.str.kebabCase('userName');     // => 'user-name'

// 截断 / 填充 / 脱敏 / 拼接
hg.utils.str.truncate('一二三四五六', 5); // => '一二...'(含省略号)
hg.utils.str.padStart('7', 3, '0');
hg.utils.str.hideMobile('13800138000');
hg.utils.str.hideIdCard('11010519491231002X');
hg.utils.str.hideBankCard('6222021234567890');
hg.utils.str.join(['张三', '', null, '李四'], ',');
hg.utils.str.removePrefix('api_user', 'api_');
hg.utils.str.removeSuffix('demo.js', '.js');

正则验证 hg.utils.validate

hg.utils.validate.isMobile('13800138000');
hg.utils.validate.isEmail('[email protected]');
hg.utils.validate.isIdCard('11010519491231002X');   // 含校验位
hg.utils.validate.isCreditCode('...');             // 统一社会信用代码,含校验位
hg.utils.validate.isUrl('https://example.com');
hg.utils.validate.isDate('2024-02-29');
hg.utils.validate.isDateTime('2024-01-01 12:00:00');
hg.utils.validate.isNumber('-12.3');
hg.utils.validate.isInteger('12');
hg.utils.validate.isBankCard('6222021234567890');   // Luhn
hg.utils.validate.isPostalCode('100000');
hg.utils.validate.isIPv4('192.168.1.1');

日期 hg.utils.date

hg.utils.date.format(Date.now());                    // 默认 YYYY-MM-DD HH:mm:ss
hg.utils.date.nowFormat('YYYY-MM-DD');
hg.utils.date.dateStringToTimestamp('2024-01-01');
hg.utils.date.splitDateRange('2024-01-01', '2024-12-31', 3);
// => [{ begin, end, len, days }, ...]

数组工具

hg.utils.range(5, 50, 3);
// => [5, 8, 11, ...]

hg.utils.chunkAll([1, 2, 3, 4, 5], 2);
// => [[1, 2], [3, 4], [5]]

// 分块:无回调返回二维数组;有回调则逐批处理(大数据推荐)
await hg.utils.splitArray(list, 10);
await hg.utils.splitArray(list, 10, async (items) => { /* ... */ });

hg.utils.unique([1, 2, 3, 1, 2, 3]); // => [1, 2, 3]
hg.utils.toMD5('hello');
hg.utils.formatCurrency(1234.5, 'zh-CN', 'CNY');

文件 hg.utils.file

路径与本地文件

hg.utils.file.extname('a.XLSX');              // => '.xlsx'
hg.utils.file.extname('a.XLSX', false);       // => 'xlsx'
hg.utils.file.basename('/tmp/a/b.xlsx');      // => 'b.xlsx'
hg.utils.file.filename('/tmp/a/b.xlsx');      // => 'b'
hg.utils.file.dirname('/tmp/a/b.xlsx');       // => '/tmp/a'
hg.utils.file.join('/tmp', 'a', 'b.xlsx');
hg.utils.file.tmpPath('导入.xlsx');           // => '/tmp/导入.xlsx'
hg.utils.file.getCurrentTimeFileName('xlsx');

hg.utils.file.exists('/tmp/a.xlsx');
hg.utils.file.size('/tmp/a.xlsx');            // 不存在返回 -1
hg.utils.file.ensureDir('/tmp/exports');
hg.utils.file.remove('/tmp/a.xlsx');

上传 / 下载

// 网络文件 → 上传到租户空间
await hg.utils.file.downloadFileToUpload(url, '文件名.xlsx');
await hg.utils.file.downloadFileToUpload(url, '文件名.xlsx', { Authorization: '...' });

// 租户空间 → 本地 /tmp
await hg.utils.file.downloadFileToTmp({ id, mime_type }, '/tmp/xxx.xlsx');
await hg.utils.file.downloadFileByToeknToTmp({ token, mime_type }, '/tmp/xxx.xlsx');

// 调试:把数据追加写入本地文件
hg.utils.file.saveDataToEnv(data, '/tmp/debug.json');

CSV / Excel

本地路径一般先用下载方法落到 /tmp/...。

CSV

const list = await hg.utils.file.csvRead(file_path);           // 小文件
await hg.utils.file.csvRead(file_path, async (row) => { /* */ }); // 大文件推荐

Excel 读取(小文件,建议 < 10M)

const list = hg.utils.file.xlsxReaderAll(file_path);

Excel 导入为 APASS 对象数据(流式分块,适合大表)

  • Excel 列名需与对象字段中文名一致,会自动映射到字段 apiName
  • 支持普通值 / 公式计算结果 / 富文本 / 超链接;日期支持序列号与文本
  • 0、false 会保留;空单元格或公式无缓存结果会跳过该字段
  • enableParseLog: true 可输出解析过程(跳过原因等);仍受全局 setLogEnabled 约束,全局关闭时不会打印
const config = {
  fieldCustomization: null, // 可选,见下方
  returnRowNumber: false,
  chunkSize: 200,
  skipRows: 2,
  maxSheet: 1,
  sheetNames: null,         // 传了则忽略 maxSheet,如 ['Sheet1', 1]
  enableParseLog: false,    // 调试时设 true;正式请保持 false,且全局可 setLogEnabled(false)
};

const fieldCustomization = {
  process_outsourcing: {
    lookupObjectKey: 'affiliation_month', // lookup 查询键,默认 _name
    render: async (value, field, item) => value, // 必须是 async
  },
};

await hg.utils.file.xlsxConvertsObjectDataChunks(
  'objectApiName',
  file_path,
  config,
  async (records, rawRecords) => {
    // records:已转换;rawRecords:原始列值
  }
);

Excel 导出

await hg.utils.file.exportExcelFile(records, fields, '导出文件.xlsx');

fields 列配置:

| 参数 | 类型 | 必填 | 说明 | | :--- | :--- | :---: | :--- | | key | string | ✅ | 数据字段键 | | header | string | ✅ | 表头 | | render | Function | - | (value, record) => value | | enums | Array | - | [{ name: [{ language_code, text }], api_alias }] | | type | string | - | 'Date' | 'Float' | 'Region' |

[
  { key: 'name', header: '姓名', render: async (value) => value?.name },
  { key: 'createTime', header: '创建时间', type: 'Date' },
]

交流学习

从事飞书低代码平台(APASS)开发 3 年,欢迎交流学习

微信: IAMRuiyu