mirror of
https://github.com/tmlnv/obsidian-telegram-bridge.git
synced 2026-07-22 06:53:13 +00:00
fix: resolve obsidian community review issues for 0.1.1
- tsconfig: drop deprecated baseUrl and moduleResolution=node10 (node->bundler)
that failed build verification on newer TypeScript
- esbuild: replace builtin-modules dependency with node:module builtinModules
- settings-tab: use createDiv/createSpan instead of createEl("div"/"span")
- main: avoid globalThis; reference crypto.randomUUID directly
- type Supabase rpc/select responses and loadData to remove unsafe-any flows
(destructuring, assignment, member access, arguments)
- template-engine: annotate replace() callback params to drop unsafe arguments
- styles: drop !important; override via selector specificity
- bump version to 0.1.1 (manifest, package, versions)
This commit is contained in:
parent
b70131db90
commit
0351218fff
11 changed files with 64 additions and 76 deletions
|
|
@ -1,6 +1,8 @@
|
|||
import esbuild from "esbuild";
|
||||
import process from "process";
|
||||
import builtins from "builtin-modules";
|
||||
import { builtinModules } from "node:module";
|
||||
|
||||
const builtins = [...builtinModules, ...builtinModules.map((name) => `node:${name}`)];
|
||||
|
||||
const banner = `/*
|
||||
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "telegram-bridge",
|
||||
"name": "Telegram Bridge",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"minAppVersion": "1.5.0",
|
||||
"description": "Sync messages from Telegram into your vault through a self-hosted Supabase backend.",
|
||||
"author": "tmlnv",
|
||||
|
|
|
|||
18
package-lock.json
generated
18
package-lock.json
generated
|
|
@ -1,18 +1,17 @@
|
|||
{
|
||||
"name": "telegram-bridge",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "telegram-bridge",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"dependencies": {
|
||||
"@supabase/supabase-js": "^2.49.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.17.30",
|
||||
"builtin-modules": "^3.3.0",
|
||||
"esbuild": "^0.25.1",
|
||||
"obsidian": "latest",
|
||||
"typescript": "^5.8.2",
|
||||
|
|
@ -1128,19 +1127,6 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/builtin-modules": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
|
||||
"integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/cac": {
|
||||
"version": "6.7.14",
|
||||
"resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "telegram-bridge",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"description": "Sync messages from Telegram into your vault through a self-hosted Supabase backend.",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
|
@ -16,7 +16,6 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.17.30",
|
||||
"builtin-modules": "^3.3.0",
|
||||
"esbuild": "^0.25.1",
|
||||
"obsidian": "latest",
|
||||
"typescript": "^5.8.2",
|
||||
|
|
|
|||
35
src/main.ts
35
src/main.ts
|
|
@ -29,8 +29,8 @@ import { findMatchingRule } from "./distribution-rules";
|
|||
import { expandTemplate } from "./template-engine";
|
||||
|
||||
function createClientId(): string {
|
||||
if (globalThis.crypto?.randomUUID) {
|
||||
return globalThis.crypto.randomUUID();
|
||||
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
||||
return crypto.randomUUID();
|
||||
}
|
||||
|
||||
return `client-${Date.now()}`;
|
||||
|
|
@ -114,7 +114,7 @@ export default class ObsidianTelegramPlugin extends Plugin {
|
|||
}
|
||||
|
||||
async loadSettings(): Promise<void> {
|
||||
const loaded = await this.loadData();
|
||||
const loaded = (await this.loadData()) as Partial<PluginSettings> | null;
|
||||
this.settings = {
|
||||
...DEFAULT_SETTINGS,
|
||||
...loaded,
|
||||
|
|
@ -294,13 +294,13 @@ export default class ObsidianTelegramPlugin extends Plugin {
|
|||
return null;
|
||||
}
|
||||
|
||||
const { data, error } = await getClient().rpc("get_usage_estimate");
|
||||
if (error) {
|
||||
throw new Error(`Failed to load usage estimate: ${error.message}`);
|
||||
const response = await getClient().rpc("get_usage_estimate");
|
||||
if (response.error) {
|
||||
throw new Error(`Failed to load usage estimate: ${response.error.message}`);
|
||||
}
|
||||
|
||||
const row = Array.isArray(data) ? data[0] : data;
|
||||
this.latestUsageEstimate = (row ?? null) as UsageEstimateRow | null;
|
||||
const rows = (response.data ?? []) as UsageEstimateRow[];
|
||||
this.latestUsageEstimate = rows[0] ?? null;
|
||||
this.updateStatusIndicator();
|
||||
return this.latestUsageEstimate;
|
||||
}
|
||||
|
|
@ -311,21 +311,22 @@ export default class ObsidianTelegramPlugin extends Plugin {
|
|||
return null;
|
||||
}
|
||||
|
||||
const { data, error } = await getClient()
|
||||
const response = await getClient()
|
||||
.from("user_preferences")
|
||||
.select("*")
|
||||
.eq("user_id", getSession()!.user.id)
|
||||
.maybeSingle();
|
||||
|
||||
if (error) {
|
||||
throw new Error(`Failed to load usage settings: ${error.message}`);
|
||||
if (response.error) {
|
||||
throw new Error(`Failed to load usage settings: ${response.error.message}`);
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
const preferences = response.data as UserPreferencesRow | null;
|
||||
if (!preferences) {
|
||||
return await this.pushUserPreferencesToServer();
|
||||
}
|
||||
|
||||
this.latestUserPreferences = data as UserPreferencesRow;
|
||||
this.latestUserPreferences = preferences;
|
||||
this.settings.estimated_storage_limit_mb = Math.max(
|
||||
1,
|
||||
Math.round(this.latestUserPreferences.estimated_storage_limit_bytes / (1024 * 1024)),
|
||||
|
|
@ -353,17 +354,17 @@ export default class ObsidianTelegramPlugin extends Plugin {
|
|||
updated_at: new Date().toISOString(),
|
||||
};
|
||||
|
||||
const { data, error } = await getClient()
|
||||
const response = await getClient()
|
||||
.from("user_preferences")
|
||||
.upsert(payload)
|
||||
.select("*")
|
||||
.single();
|
||||
|
||||
if (error) {
|
||||
throw new Error(`Failed to save usage settings: ${error.message}`);
|
||||
if (response.error) {
|
||||
throw new Error(`Failed to save usage settings: ${response.error.message}`);
|
||||
}
|
||||
|
||||
this.latestUserPreferences = data as UserPreferencesRow;
|
||||
this.latestUserPreferences = response.data as UserPreferencesRow;
|
||||
this.settings.estimated_storage_limit_mb = Math.max(
|
||||
1,
|
||||
Math.round(this.latestUserPreferences.estimated_storage_limit_bytes / (1024 * 1024)),
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ export class ObsidianTelegramSettingTab extends PluginSettingTab {
|
|||
}
|
||||
|
||||
const intro = containerEl.createDiv({ cls: "obsidian-telegram-intro" });
|
||||
intro.createEl("div", {
|
||||
intro.createDiv({
|
||||
cls: "obsidian-telegram-intro-title",
|
||||
text: "Requires a self-hosted Supabase project",
|
||||
});
|
||||
intro.createEl("div", {
|
||||
intro.createDiv({
|
||||
cls: "obsidian-telegram-intro-body",
|
||||
text: "This plugin reads Telegram messages from your own Supabase backend. Follow the README to provision a free Supabase project, deploy the edge functions, and create a Telegram bot before connecting below.",
|
||||
});
|
||||
|
|
@ -58,7 +58,7 @@ export class ObsidianTelegramSettingTab extends PluginSettingTab {
|
|||
const summary = details.createEl("summary", {
|
||||
cls: "obsidian-telegram-section-summary",
|
||||
});
|
||||
summary.createEl("span", {
|
||||
summary.createSpan({
|
||||
cls: "obsidian-telegram-section-title",
|
||||
text: title,
|
||||
});
|
||||
|
|
@ -585,11 +585,11 @@ export class ObsidianTelegramSettingTab extends PluginSettingTab {
|
|||
description: string,
|
||||
): void {
|
||||
const row = containerEl.createDiv({ cls: "obsidian-telegram-connection-row" });
|
||||
row.createEl("div", { cls: "obsidian-telegram-connection-label", text: label });
|
||||
row.createDiv({ cls: "obsidian-telegram-connection-label", text: label });
|
||||
|
||||
const body = row.createDiv({ cls: "obsidian-telegram-connection-body" });
|
||||
body.createEl("div", { cls: "obsidian-telegram-connection-value", text: value });
|
||||
body.createEl("div", { cls: "obsidian-telegram-connection-description", text: description });
|
||||
body.createDiv({ cls: "obsidian-telegram-connection-value", text: value });
|
||||
body.createDiv({ cls: "obsidian-telegram-connection-description", text: description });
|
||||
}
|
||||
|
||||
private usageSummaryEl: HTMLElement | null = null;
|
||||
|
|
@ -618,16 +618,16 @@ export class ObsidianTelegramSettingTab extends PluginSettingTab {
|
|||
|
||||
const headerEl = summaryEl.createDiv({ cls: "obsidian-telegram-usage-header" });
|
||||
const headerCopyEl = headerEl.createDiv();
|
||||
headerCopyEl.createEl("div", { cls: "obsidian-telegram-usage-eyebrow", text: "Estimated usage" });
|
||||
headerCopyEl.createEl("div", {
|
||||
headerCopyEl.createDiv({ cls: "obsidian-telegram-usage-eyebrow", text: "Estimated usage" });
|
||||
headerCopyEl.createDiv({
|
||||
cls: "obsidian-telegram-usage-title obsidian-telegram-skeleton-text",
|
||||
text: "—",
|
||||
});
|
||||
headerCopyEl.createEl("div", {
|
||||
headerCopyEl.createDiv({
|
||||
cls: "obsidian-telegram-usage-subtitle obsidian-telegram-skeleton-text",
|
||||
text: "Loading estimated storage usage…",
|
||||
});
|
||||
headerEl.createEl("div", {
|
||||
headerEl.createDiv({
|
||||
cls: "obsidian-telegram-usage-badge obsidian-telegram-skeleton-badge",
|
||||
text: "—",
|
||||
});
|
||||
|
|
@ -650,11 +650,11 @@ export class ObsidianTelegramSettingTab extends PluginSettingTab {
|
|||
this.createUsageStat(statsEl, "Files", "—", "— of estimate");
|
||||
|
||||
const footerEl = summaryEl.createDiv({ cls: "obsidian-telegram-usage-footer" });
|
||||
footerEl.createEl("div", {
|
||||
footerEl.createDiv({
|
||||
cls: "obsidian-telegram-usage-note obsidian-telegram-skeleton-text",
|
||||
text: "Fetching notification status…",
|
||||
});
|
||||
footerEl.createEl("div", {
|
||||
footerEl.createDiv({
|
||||
cls: "obsidian-telegram-usage-note obsidian-telegram-skeleton-text",
|
||||
text: "Fetching warning state…",
|
||||
});
|
||||
|
|
@ -696,22 +696,22 @@ export class ObsidianTelegramSettingTab extends PluginSettingTab {
|
|||
|
||||
const headerEl = summaryEl.createDiv({ cls: "obsidian-telegram-usage-header" });
|
||||
const headerCopyEl = headerEl.createDiv();
|
||||
headerCopyEl.createEl("div", { cls: "obsidian-telegram-usage-eyebrow", text: "Estimated usage" });
|
||||
headerCopyEl.createEl("div", {
|
||||
headerCopyEl.createDiv({ cls: "obsidian-telegram-usage-eyebrow", text: "Estimated usage" });
|
||||
headerCopyEl.createDiv({
|
||||
cls: "obsidian-telegram-usage-title",
|
||||
text:
|
||||
usage === null
|
||||
? "No synced data yet"
|
||||
: `${this.formatBytes(usageBytes)} of ${this.formatBytes(limitBytes)}`,
|
||||
});
|
||||
headerCopyEl.createEl("div", {
|
||||
headerCopyEl.createDiv({
|
||||
cls: "obsidian-telegram-usage-subtitle",
|
||||
text:
|
||||
usage === null
|
||||
? "The chart will appear after your first synced messages."
|
||||
: `${usage.message_count} messages and ${usage.file_count} files tracked by the estimate.`,
|
||||
});
|
||||
headerEl.createEl("div", {
|
||||
headerEl.createDiv({
|
||||
cls: "obsidian-telegram-usage-badge",
|
||||
text: `${usagePercent}%`,
|
||||
});
|
||||
|
|
@ -752,11 +752,11 @@ export class ObsidianTelegramSettingTab extends PluginSettingTab {
|
|||
);
|
||||
|
||||
const footerEl = summaryEl.createDiv({ cls: "obsidian-telegram-usage-footer" });
|
||||
footerEl.createEl("div", {
|
||||
footerEl.createDiv({
|
||||
cls: "obsidian-telegram-usage-note",
|
||||
text: notificationStatus,
|
||||
});
|
||||
footerEl.createEl("div", {
|
||||
footerEl.createDiv({
|
||||
cls: "obsidian-telegram-usage-note",
|
||||
text: preferences?.telegram_warnings_enabled
|
||||
? "Telegram warnings are enabled."
|
||||
|
|
@ -766,10 +766,10 @@ export class ObsidianTelegramSettingTab extends PluginSettingTab {
|
|||
|
||||
private createUsageStat(containerEl: HTMLElement, label: string, value: string, meta?: string): void {
|
||||
const statEl = containerEl.createDiv({ cls: "obsidian-telegram-usage-stat" });
|
||||
statEl.createEl("div", { cls: "obsidian-telegram-usage-stat-label", text: label });
|
||||
statEl.createEl("div", { cls: "obsidian-telegram-usage-stat-value", text: value });
|
||||
statEl.createDiv({ cls: "obsidian-telegram-usage-stat-label", text: label });
|
||||
statEl.createDiv({ cls: "obsidian-telegram-usage-stat-value", text: value });
|
||||
if (meta) {
|
||||
statEl.createEl("div", { cls: "obsidian-telegram-usage-stat-meta", text: meta });
|
||||
statEl.createDiv({ cls: "obsidian-telegram-usage-stat-meta", text: meta });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -107,18 +107,18 @@ export class SyncEngine {
|
|||
throw new Error("Cannot start sync without an authenticated session.");
|
||||
}
|
||||
|
||||
const { data, error } = await getClient()
|
||||
const response = await getClient()
|
||||
.from("sync_clients")
|
||||
.select("*")
|
||||
.eq("id", this.clientId)
|
||||
.maybeSingle();
|
||||
|
||||
if (error) {
|
||||
throw new Error(`Failed to load sync client: ${error.message}`);
|
||||
if (response.error) {
|
||||
throw new Error(`Failed to load sync client: ${response.error.message}`);
|
||||
}
|
||||
|
||||
if (data) {
|
||||
const row = data as SyncClientRow;
|
||||
const row = response.data as SyncClientRow | null;
|
||||
if (row) {
|
||||
this.cursor = {
|
||||
last_processed_message_updated_at: row.last_processed_message_updated_at,
|
||||
last_processed_message_id: row.last_processed_message_id,
|
||||
|
|
@ -177,17 +177,17 @@ export class SyncEngine {
|
|||
}
|
||||
|
||||
private async fetchMessagesAfterCursor(): Promise<MessageRow[]> {
|
||||
const { data, error } = await getClient().rpc("fetch_messages_after_cursor", {
|
||||
const response = await getClient().rpc("fetch_messages_after_cursor", {
|
||||
p_last_processed_message_updated_at: this.cursor.last_processed_message_updated_at,
|
||||
p_last_processed_message_id: this.cursor.last_processed_message_id,
|
||||
p_limit: 50,
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw new Error(`Failed to fetch messages: ${error.message}`);
|
||||
if (response.error) {
|
||||
throw new Error(`Failed to fetch messages: ${response.error.message}`);
|
||||
}
|
||||
|
||||
return (data ?? []) as MessageRow[];
|
||||
return (response.data ?? []) as MessageRow[];
|
||||
}
|
||||
|
||||
private subscribeRealtime(): void {
|
||||
|
|
|
|||
|
|
@ -98,10 +98,10 @@ export function expandTemplate(
|
|||
const content = getContent(message);
|
||||
let result = template;
|
||||
|
||||
result = result.replace(/\{\{messageDate:([^}]+)\}\}/g, (_match, format) =>
|
||||
result = result.replace(/\{\{messageDate:([^}]+)\}\}/g, (_match: string, format: string) =>
|
||||
formatDate(message.telegram_date, format),
|
||||
);
|
||||
result = result.replace(/\{\{content(?::(\d+))?\}\}/g, (_match, length) =>
|
||||
result = result.replace(/\{\{content(?::(\d+))?\}\}/g, (_match: string, length?: string) =>
|
||||
sliceContent(content, length),
|
||||
);
|
||||
result = result.replace(/\{\{chatId\}\}/g, String(message.telegram_chat_id));
|
||||
|
|
|
|||
|
|
@ -267,10 +267,10 @@
|
|||
border-top: 0;
|
||||
}
|
||||
|
||||
.obsidian-telegram-section-note {
|
||||
border-top: 0 !important;
|
||||
padding-top: 4px !important;
|
||||
padding-bottom: 4px !important;
|
||||
.obsidian-telegram-section-body .obsidian-telegram-section-note {
|
||||
border-top: 0;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.obsidian-telegram-section-note .setting-item-control {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"baseUrl": ".",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"inlineSourceMap": true,
|
||||
"inlineSources": true,
|
||||
"module": "ESNext",
|
||||
"target": "ES2020",
|
||||
"moduleResolution": "node",
|
||||
"moduleResolution": "bundler",
|
||||
"strict": true,
|
||||
"isolatedModules": true,
|
||||
"lib": ["DOM", "ES2020"],
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
{
|
||||
"0.1.0": "1.5.0"
|
||||
"0.1.0": "1.5.0",
|
||||
"0.1.1": "1.5.0"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue