mirror of
https://github.com/PHIDIAS0303/ClusterChatSync.git
synced 2026-11-11 15:14:52 +09:00
.
This commit is contained in:
1 parent
ef5d18a171
commit
b56904e8ae
13 files changed
+296
-222
No files matched your search
@@ -1,5 +1,9 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v1.0.3
|
||||||
|
|
||||||
|
- Changed to TS
|
||||||
|
|
||||||
## v1.0.0
|
## v1.0.0
|
||||||
|
|
||||||
- Initial
|
- Initial
|
||||||
|
|||||||
-117
@@ -1,117 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
const Discord = require('discord.js');
|
|
||||||
const lib = require('@clusterio/lib');
|
|
||||||
const {BaseControllerPlugin} = require('@clusterio/controller');
|
|
||||||
const {InstanceActionEvent} = require('./index.js');
|
|
||||||
|
|
||||||
const MAX_DISCORD_MESSAGE_LENGTH = 1950;
|
|
||||||
|
|
||||||
class ControllerPlugin extends BaseControllerPlugin {
|
|
||||||
async init() {
|
|
||||||
this.controller.config.on('fieldChanged', (field, curr, prev) => {
|
|
||||||
if (field === 'ClusterChatSync.discord_bot_token') {
|
|
||||||
this.connect().catch(err => {
|
|
||||||
this.logger.error(`[Chat Sync] Discord bot token:\n${err.stack}`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.controller.handle(InstanceActionEvent, this.handleInstanceAction.bind(this));
|
|
||||||
this.client = null;
|
|
||||||
await this.connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
async clientDestroy() {
|
|
||||||
if (this.client) {
|
|
||||||
this.client.destroy();
|
|
||||||
this.client = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async connect() {
|
|
||||||
await this.clientDestroy();
|
|
||||||
|
|
||||||
if (!this.controller.config.get('ClusterChatSync.discord_bot_token')) {
|
|
||||||
this.logger.error('[Chat Sync] Discord bot token not configured.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.client = new Discord.Client({intents: [Discord.GatewayIntentBits.Guilds, Discord.GatewayIntentBits.GuildMessages, Discord.GatewayIntentBits.MessageContent]});
|
|
||||||
this.logger.info('[Chat Sync] Logging into Discord.');
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.client.login(this.controller.config.get('ClusterChatSync.discord_bot_token'));
|
|
||||||
} catch (err) {
|
|
||||||
this.logger.error(`[Chat Sync] Discord login error:\n${err.stack}`);
|
|
||||||
await this.clientDestroy();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.info('[Chat Sync] Logged in Discord successfully.');
|
|
||||||
}
|
|
||||||
|
|
||||||
async onShutdown() {
|
|
||||||
await this.clientDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
async sendMessage(request, nrc_msg) {
|
|
||||||
const channel_id = this.controller.config.get('ClusterChatSync.discord_channel_mapping')[request.instanceName];
|
|
||||||
if (!channel_id) return;
|
|
||||||
let channel;
|
|
||||||
|
|
||||||
try {
|
|
||||||
channel = await this.client.channels.fetch(channel_id);
|
|
||||||
|
|
||||||
if (channel === null) {
|
|
||||||
this.logger.error(`[Chat Sync] Discord Channel ID ${channel_id} not found.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
if (err.code !== 10003) {
|
|
||||||
this.logger.error(`[Chat Sync] Discord channel fetch error:\n${err.stack}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.controller.config.get('ClusterChatSync.datetime_on_message')) {
|
|
||||||
let now = new Date();
|
|
||||||
nrc_msg = `${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, '0')}${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}${String(now.getMinutes()).padStart(2, '0')}${String(now.getSeconds()).padStart(2, '0')} ${nrc_msg}`
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nrc_msg.length <= MAX_DISCORD_MESSAGE_LENGTH) {
|
|
||||||
await channel.send(nrc_msg, {allowedMentions: {parse: []}});
|
|
||||||
} else {
|
|
||||||
while (nrc_msg.length > 0) {
|
|
||||||
let nrc_cmsg = nrc_msg.slice(0, MAX_DISCORD_MESSAGE_LENGTH);
|
|
||||||
let nrc_lindex = nrc_cmsg.lastIndexOf(' ');
|
|
||||||
|
|
||||||
if (nrc_lindex !== -1) {
|
|
||||||
nrc_cmsg = nrc_cmsg.slice(0, nrc_lindex);
|
|
||||||
nrc_msg = nrc_msg.slice(nrc_lindex).trim();
|
|
||||||
} else {
|
|
||||||
nrc_msg = nrc_msg.slice(MAX_DISCORD_MESSAGE_LENGTH).trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
await channel.send(nrc_cmsg, {allowedMentions: {parse: []}});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async handleInstanceAction(request, src) {
|
|
||||||
if (request.action === 'CHAT' || request.action === 'SHOUT') {
|
|
||||||
const nrc = request.content.replace(/\[special-item=.*?\]/g, '<blueprint>').replace(/<@/g, '<@\u200c>');
|
|
||||||
const nrc_index = nrc.indexOf(':');
|
|
||||||
const nrc_username = nrc.substring(0, nrc_index);
|
|
||||||
const nrc_message = nrc.substring(nrc_index + 1).trim();
|
|
||||||
await this.sendMessage(request, `**\`${nrc_username}\`**: ${nrc_message}`);
|
|
||||||
} else if (request.action === 'JOIN') {
|
|
||||||
await this.sendMessage(request, `**\`${nrc_username}\`** joined the game`);
|
|
||||||
} else if (request.action === 'LEAVE') {
|
|
||||||
await this.sendMessage(request, `**\`${nrc_username}\`** left the game`);
|
|
||||||
} else if (request.action === 'KICK') {
|
|
||||||
await this.sendMessage(request, `**\`${nrc_username}\`** was kicked from the game`);
|
|
||||||
} else if (request.action === 'BAN') {
|
|
||||||
await this.sendMessage(request, `**\`${nrc_username}\`** was banned from the game`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {ControllerPlugin};
|
|
||||||
+148
@@ -0,0 +1,148 @@
|
|||||||
|
import type {ControllerPluginContext} from "@clusterio/controller";
|
||||||
|
import {ChatEvent} from './index.js';
|
||||||
|
import * as Discord from 'discord.js';
|
||||||
|
|
||||||
|
const MAX_DISCORD_MESSAGE_LENGTH = 1950;
|
||||||
|
const ACTION_VERBS: Record<string, string> = {
|
||||||
|
JOIN: 'joined the game',
|
||||||
|
LEAVE: 'left the game',
|
||||||
|
KICK: 'was kicked from the game',
|
||||||
|
BAN: 'was banned from the game',
|
||||||
|
};
|
||||||
|
const escapeMentions = (content: string) => content
|
||||||
|
.replace(/\[special-item=.*?\]/g, '<blueprint>')
|
||||||
|
.replace(/<@/g, '<@\u200c>');
|
||||||
|
|
||||||
|
export default async function(context: ControllerPluginContext) {
|
||||||
|
const {controller, plugin, logger} = context;
|
||||||
|
|
||||||
|
let client: Discord.Client | null = null;
|
||||||
|
|
||||||
|
const clientDestroy = async () => {
|
||||||
|
const old = client;
|
||||||
|
client = null;
|
||||||
|
if (old) await old.destroy();
|
||||||
|
};
|
||||||
|
|
||||||
|
const connect = async () => {
|
||||||
|
await clientDestroy();
|
||||||
|
|
||||||
|
const token = controller.config.get('ClusterChatSync.discord_bot_token') as string | undefined;
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
logger.error('[Chat Sync] Discord bot token not configured.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const discordClient = new Discord.Client({intents: [
|
||||||
|
Discord.GatewayIntentBits.Guilds,
|
||||||
|
Discord.GatewayIntentBits.GuildMessages,
|
||||||
|
Discord.GatewayIntentBits.MessageContent,
|
||||||
|
]});
|
||||||
|
|
||||||
|
client = discordClient;
|
||||||
|
|
||||||
|
logger.info('[Chat Sync] Logging into Discord.');
|
||||||
|
|
||||||
|
try {
|
||||||
|
await discordClient.login(token);
|
||||||
|
} catch (err) {
|
||||||
|
logger.error(`[Chat Sync] Discord login error:\n${(err as Error).stack}`);
|
||||||
|
await clientDestroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info('[Chat Sync] Logged in Discord successfully.');
|
||||||
|
};
|
||||||
|
|
||||||
|
const sendMessage = async (instanceName: string, message: string) => {
|
||||||
|
const discordClient = client;
|
||||||
|
if (!discordClient) return;
|
||||||
|
|
||||||
|
const mapping = controller.config.get('ClusterChatSync.discord_channel_mapping') as Record<string, string>;
|
||||||
|
const channelId = mapping?.[instanceName];
|
||||||
|
if (!channelId) return;
|
||||||
|
|
||||||
|
let channel: Discord.Channel | null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
channel = await discordClient.channels.fetch(channelId);
|
||||||
|
} catch (err) {
|
||||||
|
if ((err as {code?: number}).code !== 10003) {
|
||||||
|
logger.error(`[Chat Sync] Discord channel fetch error:\n${(err as Error).stack}`);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channel === null || !channel.isTextBased()) {
|
||||||
|
logger.error(`[Chat Sync] Discord Channel ID ${channelId} is not a usable text channel.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const textChannel = channel;
|
||||||
|
|
||||||
|
let nrcMsg = message;
|
||||||
|
|
||||||
|
if (controller.config.get('ClusterChatSync.datetime_on_message')) {
|
||||||
|
const now = new Date();
|
||||||
|
const p = (n: number) => String(n).padStart(2, '0');
|
||||||
|
const stamp = `${now.getFullYear()}${p(now.getMonth() + 1)}${p(now.getDate())}` + ` ${p(now.getHours())}${p(now.getMinutes())}${p(now.getSeconds())}`;
|
||||||
|
nrcMsg = `${stamp} ${nrcMsg}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const send = (content: string) => textChannel.send({content, allowedMentions: {parse: []}});
|
||||||
|
|
||||||
|
if (nrcMsg.length <= MAX_DISCORD_MESSAGE_LENGTH) {
|
||||||
|
await send(nrcMsg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let remaining = nrcMsg;
|
||||||
|
while (remaining.length > 0) {
|
||||||
|
let chunk = remaining.slice(0, MAX_DISCORD_MESSAGE_LENGTH);
|
||||||
|
const lastSpace = chunk.lastIndexOf(' ');
|
||||||
|
|
||||||
|
if (lastSpace > 0) {
|
||||||
|
chunk = chunk.slice(0, lastSpace);
|
||||||
|
remaining = remaining.slice(lastSpace).trim();
|
||||||
|
} else {
|
||||||
|
remaining = remaining.slice(MAX_DISCORD_MESSAGE_LENGTH).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
await send(chunk);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
controller.handle(ChatEvent, async (request: ChatEvent) => {
|
||||||
|
const {instanceName, action, content} = request;
|
||||||
|
|
||||||
|
if (action === 'CHAT' || action === 'SHOUT') {
|
||||||
|
const nrc = escapeMentions(content);
|
||||||
|
const index = nrc.indexOf(':');
|
||||||
|
const username = index === -1 ? nrc.trim() : nrc.slice(0, index);
|
||||||
|
const msg = index === -1 ? '' : nrc.slice(index + 1).trim();
|
||||||
|
await sendMessage(instanceName, `**\`${username}\`**: ${msg}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const verb = ACTION_VERBS[action];
|
||||||
|
|
||||||
|
if (verb) {
|
||||||
|
await sendMessage(instanceName, `**\`${content.trim()}\`** ${verb}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
controller.config.on('fieldChanged', (field) => {
|
||||||
|
if (field === 'ClusterChatSync.discord_bot_token') {
|
||||||
|
connect().catch(err => {
|
||||||
|
logger.error(`[Chat Sync] Discord bot token:\n${(err as Error).stack}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
controller.hooks.shutdown.attach(plugin.name, async () => {
|
||||||
|
await clientDestroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
await connect();
|
||||||
|
}
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
const lib = require('@clusterio/lib');
|
|
||||||
|
|
||||||
class InstanceActionEvent {
|
|
||||||
static type = 'event';
|
|
||||||
static src = 'instance';
|
|
||||||
static dst = 'controller';
|
|
||||||
static plugin = 'ClusterChatSync';
|
|
||||||
|
|
||||||
constructor(instanceName, action, content) {
|
|
||||||
this.instanceName = instanceName;
|
|
||||||
this.action = action;
|
|
||||||
this.content = content;
|
|
||||||
}
|
|
||||||
|
|
||||||
static jsonSchema = {
|
|
||||||
type: 'object',
|
|
||||||
required: ['instanceName', 'action', 'content'],
|
|
||||||
properties: {'instanceName': {type: 'string'}, 'action': {type: 'string'}, 'content': {type: 'string'}}
|
|
||||||
}
|
|
||||||
|
|
||||||
static fromJSON(json) {
|
|
||||||
return new this(json.instanceName, json.action, json.content);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Response = lib.JsonString;
|
|
||||||
}
|
|
||||||
|
|
||||||
const plugin = {
|
|
||||||
name: 'ClusterChatSync',
|
|
||||||
title: 'Cluster Chat Sync',
|
|
||||||
description: 'One way chat sync.',
|
|
||||||
instanceEntrypoint: './instance.js',
|
|
||||||
controllerEntrypoint: './controller.js',
|
|
||||||
controllerConfigFields: {
|
|
||||||
'ClusterChatSync.discord_bot_token': {
|
|
||||||
title: 'Discord Bot Token',
|
|
||||||
description: 'API Token',
|
|
||||||
type: 'string'
|
|
||||||
},
|
|
||||||
'ClusterChatSync.datetime_on_message': {
|
|
||||||
title: 'Message Datetime',
|
|
||||||
description: 'Append datetime in front',
|
|
||||||
type: 'boolean',
|
|
||||||
initialValue: true
|
|
||||||
},
|
|
||||||
'ClusterChatSync.discord_channel_mapping': {
|
|
||||||
title: 'Channels',
|
|
||||||
description: 'Putting the discord channel id and instance relations here',
|
|
||||||
type: 'object',
|
|
||||||
initialValue: {
|
|
||||||
'S1': '123'
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
messages: [InstanceActionEvent],
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {plugin, InstanceActionEvent};
|
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import type * as lib from '@clusterio/lib';
|
||||||
|
import {Type, Static} from '@sinclair/typebox';
|
||||||
|
|
||||||
|
export class ChatEvent {
|
||||||
|
declare ['constructor']: typeof ChatEvent;
|
||||||
|
static type = 'event' as const;
|
||||||
|
static src = 'instance' as const;
|
||||||
|
static dst = 'controller' as const;
|
||||||
|
static plugin = 'ClusterChatSync' as const;
|
||||||
|
static permission = null;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public instanceName: string,
|
||||||
|
public action: string,
|
||||||
|
public content: string,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static jsonSchema = Type.Object({
|
||||||
|
'instanceName': Type.String(),
|
||||||
|
'action': Type.String(),
|
||||||
|
'content': Type.String(),
|
||||||
|
});
|
||||||
|
|
||||||
|
static fromJSON(json: Static<typeof ChatEvent.jsonSchema>) {
|
||||||
|
return new this(json.instanceName, json.action, json.content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const plugin: lib.PluginDeclaration = {
|
||||||
|
name: 'ClusterChatSync',
|
||||||
|
title: 'Cluster Chat Sync',
|
||||||
|
description: 'One way chat forward to Discord.',
|
||||||
|
webEntrypoint: './web',
|
||||||
|
instanceEntrypoint: 'dist/node/instance.js',
|
||||||
|
controllerEntrypoint: 'dist/node/controller.js',
|
||||||
|
controllerConfigFields: {
|
||||||
|
'ClusterChatSync.discord_bot_token': {
|
||||||
|
title: 'Discord Bot Token',
|
||||||
|
description: 'API Token',
|
||||||
|
type: 'string'
|
||||||
|
},
|
||||||
|
'ClusterChatSync.datetime_on_message': {
|
||||||
|
title: 'Message Datetime',
|
||||||
|
description: 'Append datetime in front',
|
||||||
|
type: 'boolean',
|
||||||
|
initialValue: true
|
||||||
|
},
|
||||||
|
'ClusterChatSync.discord_channel_mapping': {
|
||||||
|
title: 'Channels',
|
||||||
|
description: 'Putting the discord channel id and instance relations here',
|
||||||
|
type: 'object',
|
||||||
|
initialValue: {
|
||||||
|
'S1': '123'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
messages: [
|
||||||
|
ChatEvent,
|
||||||
|
],
|
||||||
|
};
|
||||||
-34
@@ -1,34 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
const lib = require('@clusterio/lib');
|
|
||||||
const {BaseInstancePlugin} = require('@clusterio/host');
|
|
||||||
const {InstanceActionEvent} = require('./index.js');
|
|
||||||
|
|
||||||
class InstancePlugin extends BaseInstancePlugin {
|
|
||||||
async init() {
|
|
||||||
this.messageQueue = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
onControllerConnectionEvent(event) {
|
|
||||||
if (event === 'connect') {
|
|
||||||
for (const [action, content] of this.messageQueue) {
|
|
||||||
try {
|
|
||||||
this.instance.sendTo('controller', new InstanceActionEvent(this.instance.name, action, content));
|
|
||||||
} catch (err) {
|
|
||||||
this.messageQueue.push([output.action, output.message]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.messageQueue = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async onOutput(output) {
|
|
||||||
if (output.type !== 'action') return;
|
|
||||||
if (this.host.connector.connected) {
|
|
||||||
this.instance.sendTo('controller', new InstanceActionEvent(this.instance.name, output.action, output.message));
|
|
||||||
} else {
|
|
||||||
this.messageQueue.push([output.action, output.message]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {InstancePlugin};
|
|
||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
import type {InstancePluginContext} from '@clusterio/host';
|
||||||
|
import {ChatEvent} from './index.js';
|
||||||
|
|
||||||
|
export default async function(context: InstancePluginContext) {
|
||||||
|
const {instance, host, plugin} = context;
|
||||||
|
let queue: [string, string][] = [];
|
||||||
|
|
||||||
|
instance.hooks.controllerConnectionEvent.attach(plugin.name, async (event) => {
|
||||||
|
if (event !== 'connect' || queue.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pending = queue;
|
||||||
|
queue = [];
|
||||||
|
const failed: [string, string][] = [];
|
||||||
|
|
||||||
|
for (const [action, content] of pending) {
|
||||||
|
try {
|
||||||
|
await instance.sendTo('controller', new ChatEvent(instance.name, action, content));
|
||||||
|
} catch (err) {
|
||||||
|
failed.push([action, content]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
queue = failed;
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.hooks.output.attach(plugin.name, async (output) => {
|
||||||
|
if (output.type !== 'action') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (host.connector.connected) {
|
||||||
|
try {
|
||||||
|
await instance.sendTo('controller', new ChatEvent(instance.name, output.action, output.message));
|
||||||
|
} catch (err) {
|
||||||
|
queue.push([output.action, output.message]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
queue.push([output.action, output.message]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.hooks.controllerConnectionEvent.attach(plugin.name, async (event) => {
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
+6
-6
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@phidias0303/clusterio_chat_sync",
|
"name": "@phidias0303/clusterio_chat_sync",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"description": "One way chat sync. Created with the help of Cooldude2606",
|
"description": "One way chat forward to Discord",
|
||||||
"author": "PHIDIAS <phidias@aperx.org>",
|
"author": "PHIDIAS <phidias@aperx.org>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"homepage": "https://github.com/PHIDIAS0303/ClusterChatSync#readme",
|
"homepage": "https://github.com/PHIDIAS0303/ClusterChatSync#readme",
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/PHIDIAS0303/ClusterChatSync/issues"
|
"url": "https://github.com/PHIDIAS0303/ClusterChatSync/issues"
|
||||||
},
|
},
|
||||||
"type": "commonjs",
|
"type": "module",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"aperx",
|
"aperx",
|
||||||
"clusterio",
|
"clusterio",
|
||||||
@@ -20,10 +20,10 @@
|
|||||||
"discord",
|
"discord",
|
||||||
"clusterio-plugin"
|
"clusterio-plugin"
|
||||||
],
|
],
|
||||||
"main": "index.js",
|
"main": "dist/node/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"prepare": "tsc --build && webpack-cli --mode production",
|
||||||
"prepare": "webpack-cli --env production"
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@clusterio/lib": "workspace:^"
|
"@clusterio/lib": "workspace:^"
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.browser.json",
|
||||||
|
"references": [
|
||||||
|
{"path": "../../packages/lib/tsconfig.browser.json"},
|
||||||
|
{"path": "../../packages/web_ui/tsconfig.browser.json"}
|
||||||
|
],
|
||||||
|
"include": ["web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json"]
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{"path": "./tsconfig.node.json"},
|
||||||
|
{"path": "./tsconfig.browser.json"}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.node.json",
|
||||||
|
"references": [
|
||||||
|
{"path": "../../packages/lib/tsconfig.node.json"},
|
||||||
|
{"path": "../../packages/host/tsconfig.node.json"},
|
||||||
|
{"path": "../../packages/ctl/tsconfig.node.json"}
|
||||||
|
],
|
||||||
|
"include": ["./**/*.ts"],
|
||||||
|
"exclude": ["test/*", "./dist/*"]
|
||||||
|
}
|
||||||
File renamed without changes.
@@ -5,20 +5,19 @@ const { merge } = require('webpack-merge');
|
|||||||
|
|
||||||
const common = require('@clusterio/web_ui/webpack.common');
|
const common = require('@clusterio/web_ui/webpack.common');
|
||||||
|
|
||||||
module.exports = (env = {}) => merge(common(env), {
|
module.exports = (env = {}, argv = {}) => merge(common(env, argv), {
|
||||||
context: __dirname,
|
context: __dirname,
|
||||||
entry: './web/index.jsx',
|
entry: './web/index.tsx',
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, 'dist', 'web'),
|
path: path.resolve(__dirname, 'dist', 'web'),
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new webpack.container.ModuleFederationPlugin({
|
new webpack.container.ModuleFederationPlugin({
|
||||||
name: 'ClusterChatSync',
|
name: 'ClusterChatSync',
|
||||||
library: {type: 'window', name: 'plugin_ClusterChatSync' },
|
library: {type: 'var', name: 'plugin_ClusterChatSync'},
|
||||||
exposes: {
|
exposes: {
|
||||||
'./': './index.js',
|
'./': './index.ts',
|
||||||
'./package.json': './package.json',
|
'./package.json': './package.json'
|
||||||
'./web': './web/index.jsx',
|
|
||||||
},
|
},
|
||||||
shared: {
|
shared: {
|
||||||
'@clusterio/lib': {import: false},
|
'@clusterio/lib': {import: false},
|
||||||
Reference in new issue
Block a user