kitten-cloud-function
Version:
用于编程猫源码云功能(云变量、云列表等)的客户端工具
606 lines (605 loc) • 26.9 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CodemaoWorkInfo = void 0;
const promise_any_1 = __importDefault(require("@ungap/promise-any"));
const other_1 = require("../../utils/other");
const codemao_community_api_1 = require("../codemao-community-api");
const codemao_user_1 = require("../user/codemao-user");
const codemao_user_sex_1 = require("../user/codemao-user-sex");
const codemao_work_editor_1 = require("./codemao-work-editor");
const codemao_environment_1 = require("../codemao-environment");
const codemao_user_badge_1 = require("../user/codemao-user-badge");
async function testWorkEditorByKittenCloud(info, editor) {
const KITTEN_WEB_SOCKET_URL_PARAMS = {
[codemao_work_editor_1.CodemaoWorkEditor.NEMO.symbol]: {
authorization_type: 5,
stag: 2,
EIO: 3,
transport: "websocket"
},
[codemao_work_editor_1.CodemaoWorkEditor.KITTEN.symbol]: {
authorization_type: 1,
stag: 1,
EIO: 3,
transport: "websocket"
},
[codemao_work_editor_1.CodemaoWorkEditor.KITTEN_N.symbol]: {
authorization_type: 5,
stag: 3,
token: "",
EIO: 3,
transport: "websocket"
},
};
const url = await (async () => {
const scheme = typeof global == "object" || window.location.protocol != "http:" ? "wss" : "ws";
const host = ["socketcv", "codemao", "cn"].join(".");
const port = 9096;
const path = "/cloudstorage/";
const particularParams = KITTEN_WEB_SOCKET_URL_PARAMS[editor.symbol];
if (particularParams == null) {
throw new Error(`不支持的作品类型: ${editor.name}`);
}
const params = `session_id=${await info.id}&${Object.entries(particularParams)
.map(([key, value]) => `${key}=${value}`)
.join("&")}`;
return `${scheme}://${host}:${port}${path}?${params}`;
})();
const socket = await (0, codemao_environment_1.CodemaoWebSocket)(url);
return new Promise((resolve, reject) => {
socket.onopen = () => {
try {
// @ts-ignore
socket.close();
}
catch (error) {
console.error(error);
}
resolve({ editor });
};
socket.onerror = async () => {
reject(new Error(`通过云功能连接试探作品 ${await info.id} 编辑器类型为 ${editor.name} 失败:WebSocket 出错`));
};
});
}
/**
* ## 编程猫作品信息类
*
* - 用于获取编程猫作品信息。
* - 所有属性均为`Promise`对象,当属性获取失败时访问该属性的值会被拒绝。
*
* 提供的作品信息详见类属性
*
* ### 具有以下特性:
* - 集成多个API接口,以确保在部分API接口信息获取失败时仍能提供尽可能完整的作品信息。
* - 内置懒加载和缓存机制,以减少不必要的请求。
*
* ### 集成API接口
*
* #### 已经集成的API接口
* - {@link getWorkInfo}
* - {@link getWorkDetail}
* - {@link getNemoWorkPublicResource}
* - {@link getKittenWorkPublicResource}
* - {@link getKitten_NWorkPublicResource}
*
* #### 将来可能集成的API接口:
* - {@link searchWorkByName}
*
* #### API优先级:
* - 优先使用 {@link getWorkInfo} 接口获取作品信息,该接口包含了作品的全部信息,但是容易出错。
* - 如果 {@link getWorkInfo} 接口获取失败,则使用 {@link getWorkDetail} 接口获取作品的大部分信息。
* - 如果 {@link getWorkDetail} 接口获取失败,则使用 {@link getNemoWorkPublicResource}、{@link getKittenWorkPublicResource} 和 {@link getKitten_NWorkPublicResource} 接口获取作品的少部分信息。
* - 对于作品编辑器类型而言,如果所有接口都获取失败,还会利用 {@link testWorkEditorByKittenCloud} 试探作品类型。
* - 如果所有接口都获取失败,则抛出异常,对应属性的值会被拒绝。
*/
class CodemaoWorkInfo {
get workInfo() {
return (async () => {
if (this.__workInfo == null) {
Object.defineProperty(this, "__workInfo", {
value: (async () => {
const workInfo = await (0, codemao_community_api_1.getWorkInfo)(await this.id);
return {
id: workInfo.id,
name: workInfo.work_name,
author: new codemao_user_1.CodemaoUser({
id: workInfo.user_info.id,
nickname: workInfo.user_info.nickname,
avatarURL: workInfo.user_info.avatar,
description: workInfo.user_info.description,
badge: codemao_user_badge_1.CodemaoUserBadge.parse(workInfo.user_info.author_level)
}),
editor: codemao_work_editor_1.CodemaoWorkEditor.parse(workInfo.type),
description: workInfo.description,
operationInstruction: workInfo.operation,
publishTime: new Date(workInfo.publish_time * 1000),
playerURL: workInfo.player_url,
shareURL: workInfo.share_url,
coverURL: workInfo.preview,
previewURL: workInfo.screenshot_cover_url,
viewTimes: workInfo.view_times,
likeTimes: workInfo.praise_times,
collectTimes: workInfo.collect_times,
shareTimes: workInfo.share_times,
commentTimes: workInfo.comment_times,
openResource: workInfo.fork_enable
};
})(),
enumerable: false,
configurable: true
});
this.setCache(await this.__workInfo);
}
return await this.__workInfo;
})();
}
get workDetail() {
return (async () => {
if (this.__workDetail == null) {
Object.defineProperty(this, "__workDetail", {
value: (async () => {
const { workInfo, userInfo, qrcodeUrl, allowFork } = await (0, codemao_community_api_1.getWorkDetail)(await this.id);
return {
id: workInfo.id,
name: workInfo.name,
author: new codemao_user_1.CodemaoUser({
id: userInfo.id,
nickname: userInfo.nickname,
avatarURL: userInfo.avatar,
description: userInfo.description,
sex: codemao_user_sex_1.CodemaoUserSex.parse(userInfo.sex)
}),
description: workInfo.description,
publishTime: new Date(workInfo.publish_time * 1000),
shareURL: qrcodeUrl,
previewURL: workInfo.preview,
viewTimes: workInfo.view_times,
likeTimes: workInfo.praise_times,
collectTimes: workInfo.collection_times,
openResource: Boolean(allowFork)
};
})(),
enumerable: false,
configurable: true
});
this.setCache(await this.__workDetail);
}
return await this.__workDetail;
})();
}
get nemoWorkPublicResource() {
return (async () => {
if (this.__nemoPublicResource == null) {
Object.defineProperty(this, "__nemoPublicResource", {
value: (async () => {
const source = await (0, codemao_community_api_1.getNemoWorkPublicResource)(await this.id);
return {
id: source.work_id,
name: source.name,
author: new codemao_user_1.CodemaoUser({
id: source.user.id,
nickname: source.user.nickname,
avatarURL: source.user.avatar_url
}),
editor: codemao_work_editor_1.CodemaoWorkEditor.NEMO,
coverURL: source.preview,
previewURL: source.preview,
viewTimes: source.view_times,
likeTimes: source.n_likes
};
})(),
enumerable: false,
configurable: true
});
this.setCache(await this.__nemoPublicResource);
}
return await this.__nemoPublicResource;
})();
}
get kittenWorkPublicResource() {
return (async () => {
if (this.__kittenPublicResource == null) {
Object.defineProperty(this, "__kittenPublicResource", {
value: (async () => {
const source = await (0, codemao_community_api_1.getKittenWorkPublicResource)(await this.id);
return {
name: source.name,
editor: codemao_work_editor_1.CodemaoWorkEditor.KITTEN,
publishTime: new Date(source.updated_time * 1000)
};
})(),
enumerable: false,
configurable: true
});
this.setCache(await this.__kittenPublicResource);
}
return await this.__kittenPublicResource;
})();
}
get kitten_NWorkPublicResource() {
return (async () => {
if (this.__kittenNPublicResource == null) {
Object.defineProperty(this, "__kittenNPublicResource", {
value: (async () => {
const source = await (0, codemao_community_api_1.getKittenNWorkPublicResource)(await this.id);
return {
name: source.name,
author: new codemao_user_1.CodemaoUser({
id: parseInt(source.author_id)
}),
editor: codemao_work_editor_1.CodemaoWorkEditor.KITTEN_N,
publishTime: new Date(source.update_time * 1000),
previewURL: source.preview_url
};
})(),
enumerable: false,
configurable: true
});
this.setCache(await this.__kittenNPublicResource);
}
return await this.__kittenNPublicResource;
})();
}
/**
* 作品 ID。
*/
get id() {
if (this.__id == null) {
this.__id = Promise.reject(["获取作品ID失败", new Error("没有提供作品ID")]);
}
return this.__id;
}
/**
* 作品名称。
*/
get name() {
if (this.__name == null) {
this.__name = (0, promise_any_1.default)([
Promise.reject(new Error("没有提供作品名称")),
this.workInfo
.catch((getWorkInfoError) => this.workDetail.catch((getWorkDetailError) => Promise.reject([getWorkInfoError, getWorkDetailError]))).catch((error0) => (0, promise_any_1.default)([
this.nemoWorkPublicResource,
this.kittenWorkPublicResource,
this.kitten_NWorkPublicResource
]).catch((error1) => Promise.reject([...error0, ...error1.errors]))).then((info) => info.name)
]).catch(({ errors }) => Promise.reject(["获取作品名称失败", errors[0], ...errors[1]]));
}
return this.__name;
}
/**
* 作品作者。
*/
get author() {
if (this.__author == null) {
this.__author = (0, promise_any_1.default)([
Promise.reject(new Error("没有提供作品作者")),
this.workInfo
.catch((error0) => this.workDetail.catch((error1) => (0, promise_any_1.default)([
this.nemoWorkPublicResource,
this.kitten_NWorkPublicResource
]).catch((error2) => Promise.reject([error0, error1, ...error2.errors])))).then((info) => info.author)
]).catch(({ errors }) => Promise.reject(["获取作品作者失败", errors[0], ...errors[1]]));
}
return this.__author;
}
/**
* 作品使用的编辑器类型,详见 {@link CodemaoWorkEditor}。
*/
get editor() {
if (this.__editor == null) {
this.__editor = (0, promise_any_1.default)([
Promise.reject(new Error("没有提供作品类型")),
this.workInfo
.catch((error0) => (0, promise_any_1.default)([
this.nemoWorkPublicResource,
this.kittenWorkPublicResource,
this.kitten_NWorkPublicResource
]).catch((error1) => (0, promise_any_1.default)([
testWorkEditorByKittenCloud(this, codemao_work_editor_1.CodemaoWorkEditor.NEMO),
testWorkEditorByKittenCloud(this, codemao_work_editor_1.CodemaoWorkEditor.KITTEN),
testWorkEditorByKittenCloud(this, codemao_work_editor_1.CodemaoWorkEditor.KITTENN)
]).catch(error2 => Promise.reject([error0, ...error1.errors, ...error2.errors])))).then((info) => info.editor)
]).catch(({ errors }) => Promise.reject(["获取作品类型失败", errors[0], ...errors[1]]));
}
return this.__editor;
}
/**
* 作品描述。
*/
get description() {
if (this.__description == null) {
this.__description = (0, promise_any_1.default)([
Promise.reject(new Error("没有提供作品描述")),
this.workInfo
.catch((error0) => this.workDetail.catch((error1) => Promise.reject([error0, error1]))).then((info) => info.description)
]).catch(({ errors }) => Promise.reject(["获取作品描述失败", errors[0], ...errors[1]]));
}
return this.__description;
}
/**
* 作品操作说明。
*/
get operationInstruction() {
if (this.__operationInstruction == null) {
this.__operationInstruction = (0, promise_any_1.default)([
Promise.reject(new Error("没有提供作品操作说明")),
this.workInfo.then((info) => info.operationInstruction)
]).catch(({ errors }) => Promise.reject(["获取作品操作说明失败", ...errors]));
}
return this.__operationInstruction;
}
/**
* 作品发布时间。
*/
get publishTime() {
if (this.__publishTime == null) {
this.__publishTime = (0, promise_any_1.default)([
Promise.reject(new Error("没有提供作品发布时间")),
this.workInfo
.catch((error0) => (0, promise_any_1.default)([
this.kittenWorkPublicResource,
this.kitten_NWorkPublicResource
]).catch((error1) => Promise.reject([error0, ...error1.errors]))).then((info) => info.publishTime)
]).catch(({ errors }) => Promise.reject(["获取作品发布时间失败", errors[0], ...errors[1]]));
}
return this.__publishTime;
}
/**
* 作品运行器(即 Player)地址。
*/
get playerURL() {
if (this.__playerURL == null) {
this.__playerURL = (0, promise_any_1.default)([
Promise.reject(new Error("没有提供作品运行器地址")),
this.workInfo.then((info) => info.playerURL)
]).catch(({ errors }) => Promise.reject(["获取作品运行器地址失败", ...errors]));
}
return this.__playerURL;
}
/**
* 作品分享地址。
*/
get shareURL() {
if (this.__shareURL == null) {
this.__shareURL = (0, promise_any_1.default)([
Promise.reject(new Error("没有提供作品分享地址")),
this.workInfo
.catch((error0) => this.workDetail.catch((error1) => Promise.reject([error0, error1]))).then((info) => info.shareURL)
]).catch(({ errors }) => Promise.reject(["获取作品分享地址失败", errors[0], ...errors[1]]));
}
return this.__shareURL;
}
/**
* 作品封面地址。
*/
get coverURL() {
if (this.__coverURL == null) {
this.__coverURL = (0, promise_any_1.default)([
Promise.reject(new Error("没有提供作品封面地址")),
this.workInfo
.catch((error0) => this.nemoWorkPublicResource
.catch((error1) => Promise.reject([error0, error1]))).then((info) => info.coverURL)
]).catch(({ errors }) => Promise.reject(["获取作品封面地址失败", errors[0], ...errors[1]]));
}
return this.__coverURL;
}
/**
* 作品预览地址。
*/
get previewURL() {
if (this.__previewURL == null) {
this.__previewURL = (0, promise_any_1.default)([
Promise.reject(new Error("没有提供作品预览地址")),
this.workInfo
.catch((error0) => this.workDetail.catch((error1) => Promise.reject([error0, error1]))).catch((error0) => (0, promise_any_1.default)([
this.nemoWorkPublicResource,
this.kitten_NWorkPublicResource
]).catch((error1) => Promise.reject([...error0, ...error1.errors]))).then((info) => info.previewURL)
]).catch(({ errors }) => Promise.reject(["获取作品预览地址失败", errors[0], ...errors[1]]));
}
return this.__previewURL;
}
/**
* 作品被浏览的次数。
*/
get viewTimes() {
if (this.__viewTimes == null) {
this.__viewTimes = (0, promise_any_1.default)([
Promise.reject(new Error("没有提供作品浏览次数")),
this.workInfo
.catch((error0) => this.workDetail.catch((error1) => Promise.reject([error0, error1]))).catch((error0) => this.nemoWorkPublicResource
.catch((error1) => Promise.reject([...error0, error1]))).then((info) => info.viewTimes)
]).catch(({ errors }) => Promise.reject(["获取作品浏览次数失败", errors[0], ...errors[1]]));
}
return this.__viewTimes;
}
/**
* 点赞该作品的人数。
*/
get likeTimes() {
if (this.__likeTimes == null) {
this.__likeTimes = (0, promise_any_1.default)([
Promise.reject(new Error("没有提供作品点赞次数")),
this.workInfo
.catch((error0) => this.workDetail.catch((error1) => Promise.reject([error0, error1]))).catch((error0) => this.nemoWorkPublicResource
.catch((error1) => Promise.reject([...error0, error1]))).then((info) => info.likeTimes)
]).catch(({ errors }) => Promise.reject(["获取作品点赞次数失败", errors[0], ...errors[1]]));
}
return this.__likeTimes;
}
/**
* 收藏该作品的人数。
*/
get collectTimes() {
if (this.__collectTimes == null) {
this.__collectTimes = (0, promise_any_1.default)([
Promise.reject(new Error("没有提供作品收藏次数")),
this.workInfo
.catch((error0) => this.workDetail.catch((error1) => Promise.reject([error0, error1]))).then((info) => info.collectTimes)
]).catch(({ errors }) => Promise.reject(["获取作品收藏次数失败", errors[0], ...errors[1]]));
}
return this.__collectTimes;
}
/**
* 作品被分享的次数。
*/
get shareTimes() {
if (this.__shareTimes == null) {
this.__shareTimes = (0, promise_any_1.default)([
Promise.reject(new Error("没有提供作品分享次数")),
this.workInfo.then((info) => info.shareTimes)
]).catch(({ errors }) => Promise.reject(["获取作品分享次数失败", ...errors]));
}
return this.__shareTimes;
}
/**
* 作品的评论区中评论的数量,包括二级评论。
*/
get commentTimes() {
if (this.__commentTimes == null) {
this.__commentTimes = (0, promise_any_1.default)([
Promise.reject(new Error("没有提供作品评论次数")),
this.workInfo.then((info) => info.commentTimes)
]).catch(({ errors }) => Promise.reject(["获取作品分享次数失败", ...errors]));
}
return this.__commentTimes;
}
/**
* 作品是否是否开源。
*/
get openResource() {
if (this.__openResource == null) {
this.__openResource = (0, promise_any_1.default)([
Promise.reject(new Error("没有提供作品开源状态")),
this.workInfo
.catch((error0) => this.workDetail.catch((error1) => Promise.reject([error0, error1]))).then((info) => info.openResource)
]).catch(({ errors }) => Promise.reject(["获取作品分享次数失败", errors[0], ...errors[1]]));
}
return this.__openResource;
}
/**
* @param info 已知的作品信息。
*/
constructor(info) {
for (const key in this) {
if (key.startsWith("__") && this[key] == Node) {
Object.defineProperty(this, key, {
value: undefined,
enumerable: false,
configurable: true
});
}
}
this.setCache(info);
}
async setCache(info) {
for (let key in info) {
let value = info[key];
if (value != null) {
if (value instanceof codemao_user_1.CodemaoUser) {
if (this.__author == null) {
this.__author = Promise.resolve(new codemao_user_1.CodemaoUser());
}
const userInfoObject = {};
for (const key in value.info) {
if (`__${key}` in value.info) {
try {
// @ts-ignore
userInfoObject[key] = await value.info[`__${key}`];
}
catch (error) {
console.error(error);
}
}
}
;
(await this.__author).info.setCache(userInfoObject);
}
else {
Object.defineProperty(this, `__${key}`, {
value: Promise.resolve(value),
enumerable: false,
configurable: true
});
}
}
}
}
}
exports.CodemaoWorkInfo = CodemaoWorkInfo;
__decorate([
(0, other_1.enumerable)(false)
], CodemaoWorkInfo.prototype, "workInfo", null);
__decorate([
(0, other_1.enumerable)(false)
], CodemaoWorkInfo.prototype, "workDetail", null);
__decorate([
(0, other_1.enumerable)(false)
], CodemaoWorkInfo.prototype, "nemoWorkPublicResource", null);
__decorate([
(0, other_1.enumerable)(false)
], CodemaoWorkInfo.prototype, "kittenWorkPublicResource", null);
__decorate([
(0, other_1.enumerable)(false)
], CodemaoWorkInfo.prototype, "kitten_NWorkPublicResource", null);
__decorate([
(0, other_1.enumerable)(true)
], CodemaoWorkInfo.prototype, "id", null);
__decorate([
(0, other_1.enumerable)(true)
], CodemaoWorkInfo.prototype, "name", null);
__decorate([
(0, other_1.enumerable)(true)
], CodemaoWorkInfo.prototype, "author", null);
__decorate([
(0, other_1.enumerable)(true)
], CodemaoWorkInfo.prototype, "editor", null);
__decorate([
(0, other_1.enumerable)(true)
], CodemaoWorkInfo.prototype, "description", null);
__decorate([
(0, other_1.enumerable)(true)
], CodemaoWorkInfo.prototype, "operationInstruction", null);
__decorate([
(0, other_1.enumerable)(true)
], CodemaoWorkInfo.prototype, "publishTime", null);
__decorate([
(0, other_1.enumerable)(true)
], CodemaoWorkInfo.prototype, "playerURL", null);
__decorate([
(0, other_1.enumerable)(true)
], CodemaoWorkInfo.prototype, "shareURL", null);
__decorate([
(0, other_1.enumerable)(true)
], CodemaoWorkInfo.prototype, "coverURL", null);
__decorate([
(0, other_1.enumerable)(true)
], CodemaoWorkInfo.prototype, "previewURL", null);
__decorate([
(0, other_1.enumerable)(true)
], CodemaoWorkInfo.prototype, "viewTimes", null);
__decorate([
(0, other_1.enumerable)(true)
], CodemaoWorkInfo.prototype, "likeTimes", null);
__decorate([
(0, other_1.enumerable)(true)
], CodemaoWorkInfo.prototype, "collectTimes", null);
__decorate([
(0, other_1.enumerable)(true)
], CodemaoWorkInfo.prototype, "shareTimes", null);
__decorate([
(0, other_1.enumerable)(true)
], CodemaoWorkInfo.prototype, "commentTimes", null);
__decorate([
(0, other_1.enumerable)(true)
], CodemaoWorkInfo.prototype, "openResource", null);