-
- {
- Array.isArray(this.state.loadedWidgets) && this.state.loadedWidgets.map((manifest) => {
- return
- {
- app.cores.widgets.uninstall(manifest._id)
- }}
- onInstall={() => {
- app.cores.widgets.install(manifest._id)
- }}
- onUpdate={() => {
- app.cores.widgets.install(manifest._id, {
- update: true,
- })
- }}
- onChangeVisible={(visible) => {
- app.cores.widgets.toggleVisibility(manifest._id, visible)
- }}
- />
-
- })
- }
+ React.useEffect(() => {
+ if (app.layout.tools_bar) {
+ app.layout.tools_bar.toggleVisibility(true)
+ }
+ }, [])
-
+
Widgets
+
+
+ {
+ Array.isArray(loadedWidgets) && loadedWidgets.map((manifest) => {
+ return
+ {
+ app.cores.widgets.uninstall(manifest._id)
+ }}
+ onInstall={() => {
+ app.cores.widgets.install(manifest._id)
+ }}
+ onUpdate={() => {
+ app.cores.widgets.install(manifest._id, {
+ update: true,
+ })
+ }}
+ onChangeVisible={(visible) => {
+ app.cores.widgets.toggleVisibility(manifest._id, visible)
+ }}
+ />
+
+ })
+ }
+
+
+
}
+ onClick={() => { }}
>
-
}
- onClick={openWidgetsBrowserModal}
- >
- Install more
-
-
+ Install more
+
- }
-}
\ No newline at end of file
+
+}
+
+export default WidgetsManager
\ No newline at end of file
diff --git a/packages/app/src/settings/widgets/index.jsx b/packages/app/src/settings/widgets/index.jsx
index 88d1e25a..b04bf07e 100755
--- a/packages/app/src/settings/widgets/index.jsx
+++ b/packages/app/src/settings/widgets/index.jsx
@@ -1,5 +1,3 @@
-import React from "react"
-
import WidgetsManager from "../components/widgetsManager"
export default {
@@ -7,17 +5,5 @@ export default {
icon: "FiList",
label: "Widgets",
group: "app",
- render: () => {
- React.useEffect(() => {
- if (app.layout.tools_bar) {
- app.layout.tools_bar.toggleVisibility(true)
- }
- }, [])
-
- return
-
Widgets
-
-
-
- },
+ render: WidgetsManager
}
\ No newline at end of file
diff --git a/packages/app/src/styles/fixments.less b/packages/app/src/styles/fixments.less
index c8524e52..bd946a93 100755
--- a/packages/app/src/styles/fixments.less
+++ b/packages/app/src/styles/fixments.less
@@ -577,7 +577,8 @@
}
// fix input
-.ant-input {
+.ant-input,
+.ant-mentions {
background-color: var(--background-color-accent);
color: var(--text-color);
@@ -588,11 +589,37 @@
}
}
-.ant-input-affix-wrapper {
- background-color: var(--background-color-accent);
+.ant-mentions-outlined {
+ background: transparent;
+ &:hover {
+ background: transparent;
+ background-color: var(--background-color-accent) !important;
+ }
+
+ &:focus {
+ background: transparent;
+ background-color: var(--background-color-accent) !important;
+ }
+
+ &:focus-within {
+ background: transparent;
+ background-color: var(--background-color-accent) !important;
+ }
+}
+
+.ant-input-affix-wrapper,
+.ant-mentions-affix-wrapper {
+ background: transparent;
+ background-color: var(--background-color-accent);
color: var(--text-color);
+ border: 0 !important;
+
+ :hover {
+ border: 0 !important;
+ }
+
::placeholder {
color: var(--text-color);
opacity: 0.5;
diff --git a/packages/app/src/styles/index.less b/packages/app/src/styles/index.less
index febf227e..9d526676 100755
--- a/packages/app/src/styles/index.less
+++ b/packages/app/src/styles/index.less
@@ -83,6 +83,8 @@ a {
transition: all 150ms ease-in-out;
+ overflow-x: hidden;
+
&.electron {
.ant-layout-sider {
padding-top: 0px;
@@ -167,6 +169,13 @@ html {
// }
// }
+ &.compact-mode {
+ .content_layout {
+ padding: 0 !important;
+ margin: 0 !important;
+ }
+ }
+
&.centered-content {
.content_layout {
margin: 0 auto;
diff --git a/packages/server/db_models/extension/index.js b/packages/server/db_models/extension/index.js
index afb63f68..1b5cbb81 100644
--- a/packages/server/db_models/extension/index.js
+++ b/packages/server/db_models/extension/index.js
@@ -2,13 +2,33 @@ export default {
name: "Extension",
collection: "extensions",
schema: {
+ user_id: {
+ type: String,
+ required: true
+ },
+ assetsUrl: {
+ type: String,
+ required: true
+ },
+ srcUrl: {
+ type: String,
+ required: true
+ },
+ registryId: {
+ type: String,
+ required: true
+ },
+ packageUrl: {
+ type: String,
+ required: true
+ },
version: {
type: String,
required: true
},
- title: {
+ name: {
type: String,
- default: "Untitled"
+ default: "untitled"
},
description: {
type: String,
@@ -22,9 +42,5 @@ export default {
type: Date,
required: true,
},
- experimental: {
- type: Boolean,
- default: false
- },
}
}
\ No newline at end of file
diff --git a/packages/server/gateway/proxy.js b/packages/server/gateway/proxy.js
index b23546c3..a5ab5033 100644
--- a/packages/server/gateway/proxy.js
+++ b/packages/server/gateway/proxy.js
@@ -172,12 +172,14 @@ export default class Proxy {
if (!route) {
res.statusCode = 404
- res.end(`
- {
- "error": "404 Not found"
- }
- `)
- return
+
+ res.end(JSON.stringify({
+ error: "Gateway route not found",
+ details: "The gateway route you are trying to access does not exist, maybe the service is down...",
+ namespace: namespace,
+ }))
+
+ return null
}
if (route.pathRewrite) {
diff --git a/packages/server/services/ems/ipcEvents/accountActivation.js b/packages/server/services/ems/ipcEvents/accountActivation.js
index 1c6bf946..1614b93a 100644
--- a/packages/server/services/ems/ipcEvents/accountActivation.js
+++ b/packages/server/services/ems/ipcEvents/accountActivation.js
@@ -1,8 +1,6 @@
import templates from "../templates"
export default async (ctx, data) => {
- console.log(`EMS Send account activation `, data)
-
const { user, activation_code } = data
const result = await ctx.mailTransporter.sendMail({
diff --git a/packages/server/services/marketplace/classes/extension/index.js b/packages/server/services/marketplace/classes/extension/index.js
new file mode 100644
index 00000000..9a58d3a1
--- /dev/null
+++ b/packages/server/services/marketplace/classes/extension/index.js
@@ -0,0 +1,3 @@
+export default class Extension {
+ static resolve = require("./methods/resolve").default
+}
\ No newline at end of file
diff --git a/packages/server/services/marketplace/classes/extension/methods/resolve.js b/packages/server/services/marketplace/classes/extension/methods/resolve.js
new file mode 100644
index 00000000..cc61dcc5
--- /dev/null
+++ b/packages/server/services/marketplace/classes/extension/methods/resolve.js
@@ -0,0 +1,24 @@
+import { Extension } from "@db_models"
+
+export default async function resolve(payload) {
+ let { user_id, pkg } = payload
+
+ const [pkgName, pkgVersion] = pkg.split("@")
+
+ if (!pkgVersion) {
+ pkgVersion = "latest"
+ }
+
+ if (pkgVersion === "latest") {
+ return await Extension.findOne({
+ user_id,
+ name: pkgName,
+ }).sort({ version: -1 }).limit(1).exec()
+ }
+
+ return await Extension.findOne({
+ user_id,
+ name: pkgName,
+ version: pkgVersion,
+ })
+}
\ No newline at end of file
diff --git a/packages/server/services/marketplace/marketplace.service.js b/packages/server/services/marketplace/marketplace.service.js
index d73414b6..a01cd9da 100755
--- a/packages/server/services/marketplace/marketplace.service.js
+++ b/packages/server/services/marketplace/marketplace.service.js
@@ -1,6 +1,8 @@
import { Server } from "linebridge"
+import B2 from "backblaze-b2"
import DbManager from "@shared-classes/DbManager"
+import CacheService from "@shared-classes/CacheService"
import SharedMiddlewares from "@shared-middlewares"
@@ -16,10 +18,21 @@ class API extends Server {
contexts = {
db: new DbManager(),
+ b2: new B2({
+ applicationKeyId: process.env.B2_KEY_ID,
+ applicationKey: process.env.B2_APP_KEY,
+ }),
+ cache: new CacheService({
+ fsram: false
+ }),
}
async onInitialize() {
await this.contexts.db.initialize()
+ await this.contexts.b2.authorize()
+
+ global.cache = this.contexts.cache
+ global.b2 = this.contexts.b2
}
handleWsAuth = require("@shared-lib/handleWsAuth").default
diff --git a/packages/server/services/marketplace/package.json b/packages/server/services/marketplace/package.json
index 4aaff239..fe9965a2 100755
--- a/packages/server/services/marketplace/package.json
+++ b/packages/server/services/marketplace/package.json
@@ -2,9 +2,10 @@
"name": "marketplace",
"version": "0.60.2",
"dependencies": {
- "7zip-min": "^1.4.4",
"@octokit/rest": "^19.0.7",
+ "7zip-min": "^1.4.4",
+ "backblaze-b2": "^1.7.0",
"sucrase": "^3.32.0",
"uglify-js": "^3.17.4"
}
-}
\ No newline at end of file
+}
diff --git a/packages/server/services/marketplace/routes/extensions/[user_id]/[pkg]/get.js b/packages/server/services/marketplace/routes/extensions/[user_id]/[pkg]/get.js
new file mode 100644
index 00000000..a24347b4
--- /dev/null
+++ b/packages/server/services/marketplace/routes/extensions/[user_id]/[pkg]/get.js
@@ -0,0 +1,10 @@
+import ExtensionClass from "@classes/extension"
+
+export default async (req) => {
+ const { user_id, pkg } = req.params
+
+ return await ExtensionClass.resolveManifest({
+ user_id,
+ pkg,
+ })
+}
\ No newline at end of file
diff --git a/packages/server/services/marketplace/routes/extensions/[user_id]/[pkg]/main/get.js b/packages/server/services/marketplace/routes/extensions/[user_id]/[pkg]/main/get.js
new file mode 100644
index 00000000..70a190ba
--- /dev/null
+++ b/packages/server/services/marketplace/routes/extensions/[user_id]/[pkg]/main/get.js
@@ -0,0 +1,12 @@
+import ExtensionClass from "@classes/extension"
+
+export default async (req, res) => {
+ const { user_id, pkg } = req.params
+
+ const manifest = await ExtensionClass.resolve({
+ user_id,
+ pkg,
+ })
+
+ return manifest
+}
\ No newline at end of file
diff --git a/packages/server/services/marketplace/routes/extensions/publish/put.js b/packages/server/services/marketplace/routes/extensions/publish/put.js
new file mode 100644
index 00000000..89d24acf
--- /dev/null
+++ b/packages/server/services/marketplace/routes/extensions/publish/put.js
@@ -0,0 +1,133 @@
+import { Extension } from "@db_models"
+
+import fs from "node:fs"
+import path from "node:path"
+import sevenzip from "7zip-min"
+
+async function uploadFolderToB2(bucketId, folderPath, b2Directory) {
+ try {
+ const uploadFiles = async (dir) => {
+ const files = fs.readdirSync(dir)
+
+ for (const file of files) {
+ const fullPath = path.join(dir, file)
+ const stats = fs.statSync(fullPath)
+
+ if (stats.isDirectory()) {
+ await uploadFiles(fullPath)
+ } else {
+ const fileData = fs.readFileSync(fullPath)
+ const b2FileName = path.join(b2Directory, path.relative(folderPath, fullPath)).replace(/\\/g, '/')
+
+ console.log(`Uploading ${b2FileName}...`)
+
+ const uploadUrl = await b2.getUploadUrl({
+ bucketId: bucketId,
+ })
+
+ await b2.uploadFile({
+ uploadUrl: uploadUrl.data.uploadUrl,
+ uploadAuthToken: uploadUrl.data.authorizationToken,
+ fileName: b2FileName,
+ data: fileData,
+ })
+
+ console.log(`Uploaded ${b2FileName}`)
+ }
+ }
+ }
+
+ await uploadFiles(folderPath)
+ console.log('All files uploaded successfully.')
+ } catch (error) {
+ console.error('Error uploading folder:', error)
+ }
+}
+
+export default {
+ middlewares: ["withAuthentication"],
+ fn: async (req, res) => {
+ let { pkg } = req.headers
+
+ if (!pkg) {
+ throw new OperationError(400, "Missing package")
+ }
+
+ if (!req.auth) {
+ throw new OperationError(401, "Unauthorized")
+ }
+
+ pkg = JSON.parse(pkg)
+
+ const { user_id } = req.auth.session
+ const registryId = `${user_id}/${pkg.name}@${pkg.version}`
+ const s3Path = `${process.env.B2_BUCKET_ID}/extensions/${pkg.name}/${pkg.version}`
+ const assetsUrl = `https://${process.env.B2_CDN_ENDPOINT}/${process.env.B2_BUCKET}/${s3Path}`
+
+ const workPath = path.resolve(global.cache.constructor.cachePath, String(Date.now()), registryId)
+ const pkgPath = path.resolve(workPath, "pkg")
+ const bundlePath = path.resolve(workPath, "bundle.7z")
+
+ // console.log({
+ // user_id,
+ // pkg,
+ // registryId,
+ // s3Path,
+ // workPath,
+ // bundlePath
+ // })
+
+ let extensionRegistry = await Extension.findOne({
+ user_id: user_id,
+ registryId: registryId,
+ version: pkg.version
+ })
+
+ if (extensionRegistry) {
+ throw new OperationError(400, "Extension already exists")
+ }
+
+ try {
+ if (!fs.existsSync(workPath)) {
+ await fs.promises.mkdir(workPath, { recursive: true })
+ }
+
+ // read multipart form
+ await req.multipart(async (field) => {
+ await field.write(bundlePath)
+ })
+
+ await new Promise((resolve, reject) => {
+ sevenzip.unpack(bundlePath, pkgPath, (error) => {
+ if (error) {
+ fs.promises.rm(workPath, { recursive: true, force: true })
+ reject(error)
+ } else {
+ resolve()
+ }
+ })
+ })
+
+ await uploadFolderToB2(process.env.B2_BUCKET_ID, pkgPath, s3Path)
+
+ fs.promises.rm(workPath, { recursive: true, force: true })
+
+
+ extensionRegistry = await Extension.create({
+ user_id: user_id,
+ name: pkg.name,
+ version: pkg.version,
+ registryId: registryId,
+ assetsUrl: assetsUrl,
+ srcUrl: `${assetsUrl}/src`,
+ packageUrl: `${assetsUrl}/package.json`,
+ created_at: Date.now(),
+ })
+
+ return extensionRegistry
+ } catch (error) {
+ fs.promises.rm(workPath, { recursive: true, force: true })
+ throw error
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/server/services/marketplace/routes/publish/post.js b/packages/server/services/marketplace/routes/publish/post.js
deleted file mode 100644
index b4704500..00000000
--- a/packages/server/services/marketplace/routes/publish/post.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import { Extension } from "@db_models"
-
-export default {
- middlewares: ["withAuthentication"],
- fn: async (req, res) => {
-
- }
-}
\ No newline at end of file
diff --git a/packages/server/services/music/routes/music/lyrics/[track_id]/put.js b/packages/server/services/music/routes/music/lyrics/[track_id]/put.js
index 58298384..8c8f3481 100644
--- a/packages/server/services/music/routes/music/lyrics/[track_id]/put.js
+++ b/packages/server/services/music/routes/music/lyrics/[track_id]/put.js
@@ -18,6 +18,13 @@ export default {
throw new OperationError(403, "Unauthorized")
}
+ console.log(`Setting lyrics for track ${track_id} >`, {
+ track_id: track_id,
+ video_source: video_source,
+ lrc: lrc,
+ track: track,
+ })
+
let trackLyric = await TrackLyric.findOne({
track_id: track_id
}).lean()
@@ -35,10 +42,9 @@ export default {
trackLyric.sync_audio_at = sync_audio_at
}
- trackLyric = await TrackLyric.findOneAndUpdate(
- {
- _id: trackLyric._id
- },
+ trackLyric = await TrackLyric.findOneAndUpdate({
+ track_id: track_id
+ },
trackLyric
)
} else {
diff --git a/packages/server/services/posts/routes/posts/trending/[trending]/get.js b/packages/server/services/posts/routes/posts/trending/[trending]/get.js
new file mode 100644
index 00000000..1a022c49
--- /dev/null
+++ b/packages/server/services/posts/routes/posts/trending/[trending]/get.js
@@ -0,0 +1,25 @@
+import { Post } from "@db_models"
+import fullfill from "@classes/posts/methods/fullfill"
+
+export default {
+ middlewares: ["withOptionalAuthentication"],
+ fn: async (req) => {
+ const { limit, trim } = req.query
+
+ let result = await Post.find({
+ message: {
+ $regex: new RegExp(`#${req.params.trending}`, "gi")
+ }
+ })
+ .sort({ created_at: -1 })
+ .skip(trim ?? 0)
+ .limit(limit ?? 20)
+
+ result = await fullfill({
+ posts: result,
+ for_user_id: req.auth.session.user_id,
+ })
+
+ return result
+ }
+}
\ No newline at end of file
diff --git a/packages/server/services/posts/routes/posts/trendings/get.js b/packages/server/services/posts/routes/posts/trendings/get.js
index 6f099fc8..1301f38b 100644
--- a/packages/server/services/posts/routes/posts/trendings/get.js
+++ b/packages/server/services/posts/routes/posts/trendings/get.js
@@ -2,56 +2,44 @@ import { Post } from "@db_models"
import { DateTime } from "luxon"
const maxDaysOld = 30
+const maxHashtags = 5
export default async (req) => {
// fetch all posts that contain in message an #, with a maximun of 5 diferent hashtags
- let posts = await Post.find({
- message: {
- $regex: /#/gi
- },
- created_at: {
- $gte: DateTime.local().minus({ days: maxDaysOld }).toISO()
- }
- })
- .lean()
+ const startDate = DateTime.local().minus({ days: maxDaysOld }).toISO()
- // get the hastag content
- posts = posts.map((post) => {
- post.hashtags = post.message.match(/#[a-zA-Z0-9_]+/gi)
-
- post.hashtags = post.hashtags.map((hashtag) => {
- return hashtag.substring(1)
- })
-
- return post
- })
-
- // build trendings
- let trendings = posts.reduce((acc, post) => {
- post.hashtags.forEach((hashtag) => {
- if (acc.find((trending) => trending.hashtag === hashtag)) {
- acc = acc.map((trending) => {
- if (trending.hashtag === hashtag) {
- trending.count++
- }
-
- return trending
- })
- } else {
- acc.push({
- hashtag,
- count: 1
- })
+ const trendings = await Post.aggregate([
+ {
+ $match: {
+ message: { $regex: /#/gi },
+ created_at: { $gte: startDate }
}
- })
+ },
+ {
+ $project: {
+ hashtags: {
+ $regexFindAll: {
+ input: "$message",
+ regex: /#[a-zA-Z0-9_]+/g
+ }
+ }
+ }
+ },
+ { $unwind: "$hashtags" },
+ {
+ $project: {
+ hashtag: { $substr: ["$hashtags.match", 1, -1] }
+ }
+ },
+ {
+ $group: {
+ _id: "$hashtag",
+ count: { $sum: 1 }
+ }
+ },
+ { $sort: { count: -1 } },
+ { $limit: maxHashtags }
+ ])
- return acc
- }, [])
-
- // sort by count
- trendings = trendings.sort((a, b) => {
- return b.count - a.count
- })
-
- return trendings
+ return trendings.map(({ _id, count }) => ({ hashtag: _id, count }));
}
\ No newline at end of file
diff --git a/packages/server/services/users/routes/users/search/get.js b/packages/server/services/users/routes/users/search/get.js
new file mode 100644
index 00000000..2faf1a3b
--- /dev/null
+++ b/packages/server/services/users/routes/users/search/get.js
@@ -0,0 +1,44 @@
+import { User } from "@db_models"
+
+const ALLOWED_FIELDS = [
+ "username",
+ "publicName",
+ "id",
+]
+
+export default {
+ middlewares: ["withOptionalAuthentication"],
+ fn: async (req, res) => {
+ const { keywords, limit = 50 } = req.query
+
+ let filters = {}
+
+ if (keywords) {
+ keywords.split(";").forEach((pair) => {
+ const [field, value] = pair.split(":")
+
+ if (value === "" || value === " ") {
+ return
+ }
+
+ // Verifica que el campo estΓ© en los permitidos y que tenga un valor
+ if (ALLOWED_FIELDS.includes(field) && value) {
+ // Si el campo es "id", se busca coincidencia exacta
+ if (field === "id") {
+ filters[field] = value
+ } else {
+ // Para otros campos, usa $regex para coincidencias parciales
+ filters[field] = { $regex: `\\b${value}`, $options: "i" }
+ }
+ }
+ })
+ }
+
+ console.log(filters)
+
+ let users = await User.find(filters)
+ .limit(limit)
+
+ return users
+ }
+}
\ No newline at end of file
diff --git a/scripts/publishWidget.js b/scripts/publishWidget.js
index 07779e88..2ba8af6f 100755
--- a/scripts/publishWidget.js
+++ b/scripts/publishWidget.js
@@ -1,12 +1,11 @@
+#!/usr/bin/env node
import path from "path"
import fs from "fs"
import axios from "axios"
import sevenzip from "7zip-min"
import formdata from "form-data"
-const tmpPath = path.join(process.cwd(), ".tmp")
-
-const widgetsApi = "http://localhost:3040"
+const marketplaceAPIOrigin = "https://indev.comty.app/api/extensions"
const token = process.argv[2]
const excludedFiles = [
@@ -17,9 +16,18 @@ const excludedFiles = [
"/package-lock.json",
]
-async function copyToTmp(origin) {
+const rootPath = process.cwd()
+const tmpPath = path.join(rootPath, ".tmp")
+const buildPath = path.join(tmpPath, "build")
+const bundlePath = path.join(tmpPath, "bundle.7z")
+
+async function copySources(origin, to) {
const files = fs.readdirSync(origin)
+ if (!fs.existsSync(to)) {
+ await fs.promises.mkdir(to, { recursive: true })
+ }
+
for (const file of files) {
const filePath = path.join(origin, file)
@@ -33,14 +41,9 @@ async function copyToTmp(origin) {
}
if (fs.lstatSync(filePath).isDirectory()) {
- await copyToTmp(filePath)
+ await copySources(filePath, path.join(to, file))
} else {
- const fileContent = fs.readFileSync(filePath)
- const relativePath = filePath.replace(process.cwd(), "")
- const tmpFilePath = path.join(tmpPath, relativePath)
-
- fs.mkdirSync(path.dirname(tmpFilePath), { recursive: true })
- fs.writeFileSync(tmpFilePath, fileContent)
+ await fs.promises.copyFile(filePath, path.join(to, file))
}
}
}
@@ -63,50 +66,69 @@ async function main() {
return
}
- const rootPath = process.cwd()
-
// create a .tmp folder
- if (!fs.existsSync(tmpPath)) {
- fs.mkdirSync(tmpPath)
+ if (fs.existsSync(tmpPath)) {
+ await fs.promises.rm(tmpPath, { recursive: true, force: true })
}
- const bundlePath = path.join(rootPath, "bundle.7z")
+ try {
+ // try to read package.json
+ if (!fs.existsSync(path.resolve(rootPath, "package.json"))) {
+ console.error("π package.json not found")
+ return
+ }
- console.log("π¦ Creating bundle...")
+ const packageJSON = require(path.resolve(rootPath, "package.json"))
- await copyToTmp(rootPath)
+ // check if package.json has a main file
+ if (!packageJSON.main) {
+ console.error("π package.json does not have a main file")
+ return
+ }
- await createBundle(`${tmpPath}/*`, bundlePath)
+ if (!fs.existsSync(path.resolve(rootPath, packageJSON.main))) {
+ console.error("π main file not found")
+ return
+ }
+
+ console.log(packageJSON)
- await fs.promises.rm(tmpPath, { recursive: true, force: true })
+ console.log("π¦ Creating bundle...")
- console.log("π¦β
Bundle created successfully")
+ await copySources(rootPath, buildPath)
+ await createBundle(`${buildPath}/*`, bundlePath)
- console.log("π Publishing bundle...")
+ console.log("π¦β
Bundle created successfully")
- const formData = new formdata()
+ console.log("π Publishing bundle...")
- formData.append("bundle", fs.createReadStream(bundlePath))
+ const formData = new formdata()
- const response = await axios({
- method: "POST",
- url: `${widgetsApi}/widgets/publish`,
- headers: {
- ...formData.getHeaders(),
- Authorization: `Bearer ${token}`,
- },
- data: formData,
- }).catch((error) => {
- console.error("π Error while publishing bundle \n\t", error.response?.data ?? error)
+ formData.append("file", fs.createReadStream(bundlePath))
- return false
- })
+ const response = await axios({
+ method: "PUT",
+ url: `${marketplaceAPIOrigin}/publish`,
+ headers: {
+ ...formData.getHeaders(),
+ pkg: JSON.stringify(packageJSON),
+ Authorization: `Bearer ${token}`,
+ },
+ data: formData,
+ }).catch((error) => {
+ console.error("π Error while publishing bundle \n\t", error.response?.data ?? error)
- await fs.promises.rm(bundlePath, { recursive: true, force: true })
- await fs.promises.rm(tmpPath, { recursive: true, force: true })
+ return false
+ })
- if (response) {
- console.log("πβ
Bundle published successfully! \n", response.data)
+ if (response) {
+ console.log("πβ
Bundle published successfully! \n", response.data)
+ }
+
+ await fs.promises.rm(tmpPath, { recursive: true, force: true })
+ } catch (error) {
+ console.error("π Error while publishing bundle \n\t", error)
+ await fs.promises.rm(tmpPath, { recursive: true, force: true })
}
}
diff --git a/widgets/Clock/package.json b/widgets/Clock/package.json
new file mode 100644
index 00000000..bb0cf10b
--- /dev/null
+++ b/widgets/Clock/package.json
@@ -0,0 +1,6 @@
+{
+ "name": "clock",
+ "version": "1.0.6",
+ "description": "Display the current time",
+ "main": "./src/extension.js"
+}
\ No newline at end of file
diff --git a/widgets/Clock/src/clock.jsx b/widgets/Clock/src/clock.jsx
new file mode 100644
index 00000000..f0054ede
--- /dev/null
+++ b/widgets/Clock/src/clock.jsx
@@ -0,0 +1,21 @@
+import React from "react"
+
+import "./index.less"
+
+const Clock = () => {
+ const [time, setTime] = React.useState(new Date())
+
+ React.useEffect(() => {
+ const interval = setInterval(() => {
+ setTime(new Date())
+ }, 1000)
+
+ return () => clearInterval(interval)
+ }, [])
+
+ return
+ {time.toLocaleTimeString()}
+
+}
+
+export default Clock
\ No newline at end of file
diff --git a/widgets/Clock/src/extension.js b/widgets/Clock/src/extension.js
new file mode 100644
index 00000000..cbc3cea8
--- /dev/null
+++ b/widgets/Clock/src/extension.js
@@ -0,0 +1,45 @@
+export default class Clock {
+ registerWidgets = [
+ {
+ name: "Clock",
+ description: "Display the current time",
+ component: () => import("./clock.jsx"),
+ }
+ ]
+
+ registerPages = [
+ {
+ path: "/clock",
+ component: () => import("./clock.jsx"),
+ }
+ ]
+
+ public = {
+ echo: (...str) => {
+ this.console.log(...str)
+ },
+ fib: (n) => {
+ let a = 0, b = 1
+ for (let i = 0; i < n; i++) {
+ let c = a + b
+ a = b
+ b = c
+ }
+ return a
+ }
+ }
+
+ events = {
+ "test": (data) => {
+ this.console.log("test")
+
+ if (data) {
+ this.console.log(data)
+ }
+ }
+ }
+
+ async onInitialize() {
+ this.console.log("Hi from the extension worker!")
+ }
+}
\ No newline at end of file
diff --git a/widgets/Clock/src/index.less b/widgets/Clock/src/index.less
new file mode 100644
index 00000000..4b5556dc
--- /dev/null
+++ b/widgets/Clock/src/index.less
@@ -0,0 +1,6 @@
+.clock {
+ font-size: 2rem;
+ color: blue;
+
+ font-family: "DM Mono", monospace;
+}
\ No newline at end of file