Files
medical-mall/server/tools/deploy-cloudfunc-service.js
not-like-juvenile 427010f7db 云服务推送
2026-02-27 16:02:44 +08:00

82 lines
3.5 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const archiver = require('archiver');
const fetch = require('node-fetch');
const FormData = require('form-data');
function packDirToZip(srcDir, outPath) {
return new Promise((resolve, reject) => {
const output = fs.createWriteStream(outPath);
const archive = archiver('zip', { zlib: { level: 9 } });
output.on('close', () => resolve({ bytes: archive.pointer(), path: outPath }));
archive.on('error', err => reject(err));
archive.pipe(output);
archive.directory(srcDir, false);
archive.finalize();
});
}
async function uploadZip(url, token, zipPath, extraFields = {}) {
const form = new FormData();
form.append('file', fs.createReadStream(zipPath));
for (const k of Object.keys(extraFields)) form.append(k, extraFields[k]);
const headers = token ? { Authorization: `Bearer ${token}` } : {};
const resp = await fetch(url, { method: 'POST', headers: Object.assign(headers, form.getHeaders()), body: form });
const text = await resp.text();
let json;
try { json = JSON.parse(text); } catch (e) { json = { statusText: text }; }
return { ok: resp.ok, status: resp.status, body: json };
}
async function triggerDeployApi(deployApi, deployToken, payload = {}) {
const headers = { 'Content-Type': 'application/json' };
if (deployToken) headers.Authorization = `Bearer ${deployToken}`;
const resp = await fetch(deployApi, { method: 'POST', headers, body: JSON.stringify(payload) });
const json = await resp.json().catch(() => null);
return { ok: resp.ok, status: resp.status, body: json };
}
async function invokeFunction(funcUrl, pushToken, testCid, title = 'CI Test', content = 'hello from backend') {
const body = { token: pushToken, push_clientid: testCid, title, content, payload: {} };
const resp = await fetch(funcUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
const json = await resp.json().catch(() => null);
return { ok: resp.ok, status: resp.status, body: json };
}
async function deployCloudFunction(options = {}) {
const funcDir = options.funcDir || path.join(__dirname, '..', '..', 'uniCloud-alipay', 'cloudfunctions', 'testUnipush2');
const outDir = path.join(__dirname, '..', 'dist');
if (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true });
const zipPath = path.join(outDir, path.basename(funcDir) + '.zip');
const result = { packed: null, uploaded: null, deployed: null, invoked: null };
// pack
const packRes = await packDirToZip(funcDir, zipPath);
result.packed = packRes;
// upload
if (!options.uploadUrl) return result;
const extra = {};
if (options.uniAppId) extra.appId = options.uniAppId;
const up = await uploadZip(options.uploadUrl, options.uploadToken, zipPath, extra);
result.uploaded = up;
// trigger deploy API (optional)
if (options.deployApi) {
const payload = Object.assign({}, options.deployPayload || {}, { uploadUrl: options.uploadUrl, uploadResponse: up.body });
const dp = await triggerDeployApi(options.deployApi, options.deployToken, payload);
result.deployed = dp;
}
// invoke function for smoke test (optional)
if (options.funcInvokeUrl && options.pushToken && options.testCid) {
const iv = await invokeFunction(options.funcInvokeUrl, options.pushToken, options.testCid, options.testTitle, options.testContent);
result.invoked = iv;
}
return result;
}
module.exports = { deployCloudFunction, packDirToZip, uploadZip, triggerDeployApi, invokeFunction };