build(cli): target skill validators for Node 22

This commit is contained in:
digua committed 2026-08-18 17:27:48 +08:00
1 parent 163ef41118
commit c2382b77f2
3 files changed
+5 -5

No files matched your search

+1 -1
View File
@@ -97,7 +97,7 @@ try {
'--bundle',
'--platform=node',
'--format=esm',
'--target=node20',
'--target=node22',
'--minify',
`--outfile=${outputPath}`,
'--banner:js=#!/usr/bin/env node\n// Generated from the canonical ChatLab validator. Do not edit directly.\n/* eslint-disable */',
@@ -1,5 +1,5 @@
#!/usr/bin/env node
// Generated from the canonical ChatLab validator. Do not edit directly.
/* eslint-disable */
import{existsSync as j}from"node:fs";import H from"node:path";import{createReadStream as P}from"node:fs";import{readFile as k,stat as V}from"node:fs/promises";import{extname as D}from"node:path";import{createInterface as M}from"node:readline";var R="0.0.2",S=["0.0.1",R];function C(e){return S.includes(e)}var h=(s=>(s[s.TEXT=0]="TEXT",s[s.IMAGE=1]="IMAGE",s[s.VOICE=2]="VOICE",s[s.VIDEO=3]="VIDEO",s[s.FILE=4]="FILE",s[s.EMOJI=5]="EMOJI",s[s.LINK=7]="LINK",s[s.LOCATION=8]="LOCATION",s[s.RED_PACKET=20]="RED_PACKET",s[s.TRANSFER=21]="TRANSFER",s[s.POKE=22]="POKE",s[s.CALL=23]="CALL",s[s.SHARE=24]="SHARE",s[s.REPLY=25]="REPLY",s[s.FORWARD=26]="FORWARD",s[s.CONTACT=27]="CONTACT",s[s.SYSTEM=80]="SYSTEM",s[s.RECALL=81]="RECALL",s[s.OTHER=99]="OTHER",s))(h||{});var v=100,G=1e11,F=new Set(Object.values(h).filter(e=>typeof e=="number")),y="SYSTEM",$=new Set([80,81]);function A(e,r){return{format:e,fileSize:r,errorCount:0,warningCount:0,issues:[],stats:{headerCount:0,memberCount:0,messageCount:0,uniqueSenderCount:0,commentLineCount:0,blankLineCount:0},memberIds:new Set,ownerIds:new Set,senderIds:new Set,messageIds:new Set,replyTargetIds:new Set}}function o(e,r,n,t,i={}){r==="error"?e.errorCount++:e.warningCount++,e.issues.length<v&&e.issues.push({severity:r,code:n,message:t,...i})}function p(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function d(e,r){return Object.prototype.hasOwnProperty.call(e,r)}function c(e,r){return{...e,path:r}}function u(e,r,n,t){return typeof r=="string"&&r.trim().length>0?!0:(o(e,"error","INVALID_REQUIRED_STRING","Expected a non-empty string.",c(t,n)),!1)}function m(e,r,n,t,i){d(r,n)&&typeof r[n]!="string"&&o(e,"error","INVALID_OPTIONAL_STRING","Expected a string.",c(i,t))}function x(e,r,n,t){return typeof r=="number"&&Number.isInteger(r)&&r>=0&&r<G?!0:(o(e,"error","INVALID_UNIX_SECONDS","Expected a non-negative integer Unix timestamp in seconds, not milliseconds.",c(t,n)),!1)}function N(e,r,n,t,i=""){if(e.stats.headerCount++,!p(r))o(e,"error","INVALID_CHATLAB_HEADER","Expected a chatlab object.",{...t,path:`${i}chatlab`});else{let a=`${i}chatlab.version`;typeof r.version!="string"?o(e,"error","INVALID_VERSION","Expected a string format version.",{...t,path:a}):(e.version=r.version,C(r.version)||o(e,"error","UNSUPPORTED_VERSION",`Supported ChatLab format versions: ${S.join(", ")}.`,{...t,path:a})),x(e,r.exportedAt,`${i}chatlab.exportedAt`,t),m(e,r,"generator",`${i}chatlab.generator`,t),m(e,r,"description",`${i}chatlab.description`,t)}if(!p(n)){o(e,"error","INVALID_META","Expected a meta object.",{...t,path:`${i}meta`});return}u(e,n.name,`${i}meta.name`,t),u(e,n.platform,`${i}meta.platform`,t),n.type!=="group"&&n.type!=="private"&&o(e,"error","INVALID_CHAT_TYPE",'Expected chat type "group" or "private".',{...t,path:`${i}meta.type`}),m(e,n,"groupId",`${i}meta.groupId`,t),m(e,n,"groupAvatar",`${i}meta.groupAvatar`,t),d(n,"ownerId")&&u(e,n.ownerId,`${i}meta.ownerId`,t)&&e.ownerIds.add(n.ownerId),m(e,n,"sourceSessionId",`${i}meta.sourceSessionId`,t)}function T(e,r,n,t){if(e.stats.memberCount++,!p(r)){o(e,"error","INVALID_MEMBER","Expected a member object.",c(t,n));return}u(e,r.platformId,`${n}.platformId`,t)&&(e.memberIds.has(r.platformId)?o(e,"error","DUPLICATE_MEMBER_ID","Member platformId must be unique.",{...t,path:`${n}.platformId`}):e.memberIds.add(r.platformId)),u(e,r.accountName,`${n}.accountName`,t),m(e,r,"groupNickname",`${n}.groupNickname`,t),m(e,r,"avatar",`${n}.avatar`,t),d(r,"aliases")&&(!Array.isArray(r.aliases)||r.aliases.some(i=>typeof i!="string"))&&o(e,"error","INVALID_ALIASES","Expected aliases to be an array of strings.",{...t,path:`${n}.aliases`}),d(r,"roles")&&(Array.isArray(r.roles)?r.roles.forEach((i,a)=>{let g=`${n}.roles[${a}]`;if(!p(i)){o(e,"error","INVALID_ROLE","Expected a role object.",{...t,path:g});return}u(e,i.id,`${g}.id`,t),m(e,i,"name",`${g}.name`,t)}):o(e,"error","INVALID_ROLES","Expected roles to be an array.",{...t,path:`${n}.roles`}))}function _(e,r,n,t){if(e.stats.messageCount++,!p(r)){o(e,"error","INVALID_MESSAGE","Expected a message object.",c(t,n));return}let i=u(e,r.sender,`${n}.sender`,t)?r.sender:void 0;i!==void 0&&e.senderIds.add(i),u(e,r.accountName,`${n}.accountName`,t),x(e,r.timestamp,`${n}.timestamp`,t)&&(e.lastTimestamp!==void 0&&r.timestamp<e.lastTimestamp&&o(e,"warning","OUT_OF_ORDER_TIMESTAMP","Messages should be ordered by timestamp ascending.",c(t,`${n}.timestamp`)),e.lastTimestamp=r.timestamp);let a=typeof r.type=="number"&&Number.isInteger(r.type)&&F.has(r.type)?r.type:void 0;a===void 0?o(e,"error","INVALID_MESSAGE_TYPE","Expected a supported numeric ChatLab message type.",{...t,path:`${n}.type`}):i===y&&!$.has(a)&&o(e,"error","INVALID_SYSTEM_SENDER_TYPE","The reserved SYSTEM sender is only valid for system and recall messages.",c(t,`${n}.sender`)),(!d(r,"content")||typeof r.content!="string"&&r.content!==null)&&o(e,"error","INVALID_MESSAGE_CONTENT","Expected content to be a string or null.",{...t,path:`${n}.content`}),m(e,rLine truncated
`)}if(!w)f({ok:!1,command:"validate",error:{code:"MISSING_FILE",message:"Usage: node validate-chatlab.mjs <file>"},meta:{apiVersion:1,standalone:!0}}),process.exitCode=2;else{let e=H.resolve(w);if(!j(e))f({ok:!1,command:"validate",error:{code:"FILE_NOT_FOUND",message:`File not found: ${e}`,hint:"Pass an absolute path or a path relative to the current working directory."},meta:{apiVersion:1,standalone:!0}}),process.exitCode=3;else try{let r=await L(e);f(r.valid?{ok:!0,command:"validate",data:r,meta:{apiVersion:1,standalone:!0}}:{ok:!1,command:"validate",data:r,error:{code:"INVALID_CHATLAB_FORMAT",message:`Validation found ${r.errorCount} error(s).`,hint:"Fix every error before importing the file into ChatLab."},meta:{apiVersion:1,standalone:!0}}),r.valid||(process.exitCode=1)}catch(r){f({ok:!1,command:"validate",error:{code:"VALIDATION_FAILED",message:r instanceof Error?r.message:String(r)},meta:{apiVersion:1,standalone:!0}}),process.exitCode=1}}
import{existsSync as H}from"node:fs";import j from"node:path";import{createReadStream as P}from"node:fs";import{readFile as v,stat as k}from"node:fs/promises";import{extname as D}from"node:path";import{createInterface as V}from"node:readline";var R="0.0.2",S=["0.0.1",R];function C(e){return S.includes(e)}var h=(s=>(s[s.TEXT=0]="TEXT",s[s.IMAGE=1]="IMAGE",s[s.VOICE=2]="VOICE",s[s.VIDEO=3]="VIDEO",s[s.FILE=4]="FILE",s[s.EMOJI=5]="EMOJI",s[s.LINK=7]="LINK",s[s.LOCATION=8]="LOCATION",s[s.RED_PACKET=20]="RED_PACKET",s[s.TRANSFER=21]="TRANSFER",s[s.POKE=22]="POKE",s[s.CALL=23]="CALL",s[s.SHARE=24]="SHARE",s[s.REPLY=25]="REPLY",s[s.FORWARD=26]="FORWARD",s[s.CONTACT=27]="CONTACT",s[s.SYSTEM=80]="SYSTEM",s[s.RECALL=81]="RECALL",s[s.OTHER=99]="OTHER",s))(h||{});var G=100,M=1e11,F=new Set(Object.values(h).filter(e=>typeof e=="number")),E="SYSTEM",$=new Set([80,81]);function y(e,t){return{format:e,fileSize:t,errorCount:0,warningCount:0,issues:[],stats:{headerCount:0,memberCount:0,messageCount:0,uniqueSenderCount:0,commentLineCount:0,blankLineCount:0},memberIds:new Set,ownerIds:new Set,senderIds:new Set,messageIds:new Set,replyTargetIds:new Set}}function a(e,t,r,n,o={}){t==="error"?e.errorCount++:e.warningCount++,e.issues.length<G&&e.issues.push({severity:t,code:r,message:n,...o})}function d(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function c(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function p(e,t){return{...e,path:t}}function m(e,t,r,n){return typeof t=="string"&&t.trim().length>0?!0:(a(e,"error","INVALID_REQUIRED_STRING","Expected a non-empty string.",p(n,r)),!1)}function u(e,t,r,n,o){c(t,r)&&typeof t[r]!="string"&&a(e,"error","INVALID_OPTIONAL_STRING","Expected a string.",p(o,n))}function x(e,t,r,n){return typeof t=="number"&&Number.isInteger(t)&&t>=0&&t<M?!0:(a(e,"error","INVALID_UNIX_SECONDS","Expected a non-negative integer Unix timestamp in seconds, not milliseconds.",p(n,r)),!1)}function T(e,t,r,n,o=""){if(e.stats.headerCount++,!d(t))a(e,"error","INVALID_CHATLAB_HEADER","Expected a chatlab object.",{...n,path:`${o}chatlab`});else{let i=`${o}chatlab.version`;typeof t.version!="string"?a(e,"error","INVALID_VERSION","Expected a string format version.",{...n,path:i}):(e.version=t.version,C(t.version)||a(e,"error","UNSUPPORTED_VERSION",`Supported ChatLab format versions: ${S.join(", ")}.`,{...n,path:i})),x(e,t.exportedAt,`${o}chatlab.exportedAt`,n),u(e,t,"generator",`${o}chatlab.generator`,n),u(e,t,"description",`${o}chatlab.description`,n)}if(!d(r)){a(e,"error","INVALID_META","Expected a meta object.",{...n,path:`${o}meta`});return}m(e,r.name,`${o}meta.name`,n),m(e,r.platform,`${o}meta.platform`,n),r.type!=="group"&&r.type!=="private"&&a(e,"error","INVALID_CHAT_TYPE",'Expected chat type "group" or "private".',{...n,path:`${o}meta.type`}),u(e,r,"groupId",`${o}meta.groupId`,n),u(e,r,"groupAvatar",`${o}meta.groupAvatar`,n),c(r,"ownerId")&&m(e,r.ownerId,`${o}meta.ownerId`,n)&&e.ownerIds.add(r.ownerId),u(e,r,"sourceSessionId",`${o}meta.sourceSessionId`,n)}function _(e,t,r,n){if(e.stats.memberCount++,!d(t)){a(e,"error","INVALID_MEMBER","Expected a member object.",p(n,r));return}m(e,t.platformId,`${r}.platformId`,n)&&(e.memberIds.has(t.platformId)?a(e,"error","DUPLICATE_MEMBER_ID","Member platformId must be unique.",{...n,path:`${r}.platformId`}):e.memberIds.add(t.platformId)),m(e,t.accountName,`${r}.accountName`,n),u(e,t,"groupNickname",`${r}.groupNickname`,n),u(e,t,"avatar",`${r}.avatar`,n),c(t,"aliases")&&(!Array.isArray(t.aliases)||t.aliases.some(o=>typeof o!="string"))&&a(e,"error","INVALID_ALIASES","Expected aliases to be an array of strings.",{...n,path:`${r}.aliases`}),c(t,"roles")&&(Array.isArray(t.roles)?t.roles.forEach((o,i)=>{let g=`${r}.roles[${i}]`;if(!d(o)){a(e,"error","INVALID_ROLE","Expected a role object.",{...n,path:g});return}m(e,o.id,`${g}.id`,n),u(e,o,"name",`${g}.name`,n)}):a(e,"error","INVALID_ROLES","Expected roles to be an array.",{...n,path:`${r}.roles`}))}function N(e,t,r,n){if(e.stats.messageCount++,!d(t)){a(e,"error","INVALID_MESSAGE","Expected a message object.",p(n,r));return}let o=m(e,t.sender,`${r}.sender`,n)?t.sender:void 0;o!==void 0&&e.senderIds.add(o),m(e,t.accountName,`${r}.accountName`,n),x(e,t.timestamp,`${r}.timestamp`,n)&&(e.lastTimestamp!==void 0&&t.timestamp<e.lastTimestamp&&a(e,"warning","OUT_OF_ORDER_TIMESTAMP","Messages should be ordered by timestamp ascending.",p(n,`${r}.timestamp`)),e.lastTimestamp=t.timestamp);let i=typeof t.type=="number"&&Number.isInteger(t.type)&&F.has(t.type)?t.type:void 0;i===void 0?a(e,"error","INVALID_MESSAGE_TYPE","Expected a supported numeric ChatLab message type.",{...n,path:`${r}.type`}):o===E&&!$.has(i)&&a(e,"error","INVALID_SYSTEM_SENDER_TYPE","The reserved SYSTEM sender is only valid for system and recall messages.",p(n,`${r}.sender`)),(!c(t,"content")||typeof t.content!="string"&&t.content!==null)&&a(e,"error","INVALID_MESSAGE_CONTENT","Expected content to be a string or null.",{...n,path:`${r}.content`}),u(e,tLine truncated
`)}if(!O)f({ok:!1,command:"validate",error:{code:"MISSING_FILE",message:"Usage: node validate-chatlab.mjs <file>"},meta:{apiVersion:1,standalone:!0}}),process.exitCode=2;else{let e=j.resolve(O);if(!H(e))f({ok:!1,command:"validate",error:{code:"FILE_NOT_FOUND",message:`File not found: ${e}`,hint:"Pass an absolute path or a path relative to the current working directory."},meta:{apiVersion:1,standalone:!0}}),process.exitCode=3;else try{let t=await L(e);f(t.valid?{ok:!0,command:"validate",data:t,meta:{apiVersion:1,standalone:!0}}:{ok:!1,command:"validate",data:t,error:{code:"INVALID_CHATLAB_FORMAT",message:`Validation found ${t.errorCount} error(s).`,hint:"Fix every error before importing the file into ChatLab."},meta:{apiVersion:1,standalone:!0}}),t.valid||(process.exitCode=1)}catch(t){f({ok:!1,command:"validate",error:{code:"VALIDATION_FAILED",message:t instanceof Error?t.message:String(t)},meta:{apiVersion:1,standalone:!0}}),process.exitCode=1}}
@@ -1,5 +1,5 @@
#!/usr/bin/env node
// Generated from the canonical ChatLab validator. Do not edit directly.
/* eslint-disable */
import{existsSync as j}from"node:fs";import H from"node:path";import{createReadStream as P}from"node:fs";import{readFile as k,stat as V}from"node:fs/promises";import{extname as D}from"node:path";import{createInterface as M}from"node:readline";var R="0.0.2",S=["0.0.1",R];function C(e){return S.includes(e)}var h=(s=>(s[s.TEXT=0]="TEXT",s[s.IMAGE=1]="IMAGE",s[s.VOICE=2]="VOICE",s[s.VIDEO=3]="VIDEO",s[s.FILE=4]="FILE",s[s.EMOJI=5]="EMOJI",s[s.LINK=7]="LINK",s[s.LOCATION=8]="LOCATION",s[s.RED_PACKET=20]="RED_PACKET",s[s.TRANSFER=21]="TRANSFER",s[s.POKE=22]="POKE",s[s.CALL=23]="CALL",s[s.SHARE=24]="SHARE",s[s.REPLY=25]="REPLY",s[s.FORWARD=26]="FORWARD",s[s.CONTACT=27]="CONTACT",s[s.SYSTEM=80]="SYSTEM",s[s.RECALL=81]="RECALL",s[s.OTHER=99]="OTHER",s))(h||{});var v=100,G=1e11,F=new Set(Object.values(h).filter(e=>typeof e=="number")),y="SYSTEM",$=new Set([80,81]);function A(e,r){return{format:e,fileSize:r,errorCount:0,warningCount:0,issues:[],stats:{headerCount:0,memberCount:0,messageCount:0,uniqueSenderCount:0,commentLineCount:0,blankLineCount:0},memberIds:new Set,ownerIds:new Set,senderIds:new Set,messageIds:new Set,replyTargetIds:new Set}}function o(e,r,n,t,i={}){r==="error"?e.errorCount++:e.warningCount++,e.issues.length<v&&e.issues.push({severity:r,code:n,message:t,...i})}function p(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function d(e,r){return Object.prototype.hasOwnProperty.call(e,r)}function c(e,r){return{...e,path:r}}function u(e,r,n,t){return typeof r=="string"&&r.trim().length>0?!0:(o(e,"error","INVALID_REQUIRED_STRING","Expected a non-empty string.",c(t,n)),!1)}function m(e,r,n,t,i){d(r,n)&&typeof r[n]!="string"&&o(e,"error","INVALID_OPTIONAL_STRING","Expected a string.",c(i,t))}function x(e,r,n,t){return typeof r=="number"&&Number.isInteger(r)&&r>=0&&r<G?!0:(o(e,"error","INVALID_UNIX_SECONDS","Expected a non-negative integer Unix timestamp in seconds, not milliseconds.",c(t,n)),!1)}function N(e,r,n,t,i=""){if(e.stats.headerCount++,!p(r))o(e,"error","INVALID_CHATLAB_HEADER","Expected a chatlab object.",{...t,path:`${i}chatlab`});else{let a=`${i}chatlab.version`;typeof r.version!="string"?o(e,"error","INVALID_VERSION","Expected a string format version.",{...t,path:a}):(e.version=r.version,C(r.version)||o(e,"error","UNSUPPORTED_VERSION",`Supported ChatLab format versions: ${S.join(", ")}.`,{...t,path:a})),x(e,r.exportedAt,`${i}chatlab.exportedAt`,t),m(e,r,"generator",`${i}chatlab.generator`,t),m(e,r,"description",`${i}chatlab.description`,t)}if(!p(n)){o(e,"error","INVALID_META","Expected a meta object.",{...t,path:`${i}meta`});return}u(e,n.name,`${i}meta.name`,t),u(e,n.platform,`${i}meta.platform`,t),n.type!=="group"&&n.type!=="private"&&o(e,"error","INVALID_CHAT_TYPE",'Expected chat type "group" or "private".',{...t,path:`${i}meta.type`}),m(e,n,"groupId",`${i}meta.groupId`,t),m(e,n,"groupAvatar",`${i}meta.groupAvatar`,t),d(n,"ownerId")&&u(e,n.ownerId,`${i}meta.ownerId`,t)&&e.ownerIds.add(n.ownerId),m(e,n,"sourceSessionId",`${i}meta.sourceSessionId`,t)}function T(e,r,n,t){if(e.stats.memberCount++,!p(r)){o(e,"error","INVALID_MEMBER","Expected a member object.",c(t,n));return}u(e,r.platformId,`${n}.platformId`,t)&&(e.memberIds.has(r.platformId)?o(e,"error","DUPLICATE_MEMBER_ID","Member platformId must be unique.",{...t,path:`${n}.platformId`}):e.memberIds.add(r.platformId)),u(e,r.accountName,`${n}.accountName`,t),m(e,r,"groupNickname",`${n}.groupNickname`,t),m(e,r,"avatar",`${n}.avatar`,t),d(r,"aliases")&&(!Array.isArray(r.aliases)||r.aliases.some(i=>typeof i!="string"))&&o(e,"error","INVALID_ALIASES","Expected aliases to be an array of strings.",{...t,path:`${n}.aliases`}),d(r,"roles")&&(Array.isArray(r.roles)?r.roles.forEach((i,a)=>{let g=`${n}.roles[${a}]`;if(!p(i)){o(e,"error","INVALID_ROLE","Expected a role object.",{...t,path:g});return}u(e,i.id,`${g}.id`,t),m(e,i,"name",`${g}.name`,t)}):o(e,"error","INVALID_ROLES","Expected roles to be an array.",{...t,path:`${n}.roles`}))}function _(e,r,n,t){if(e.stats.messageCount++,!p(r)){o(e,"error","INVALID_MESSAGE","Expected a message object.",c(t,n));return}let i=u(e,r.sender,`${n}.sender`,t)?r.sender:void 0;i!==void 0&&e.senderIds.add(i),u(e,r.accountName,`${n}.accountName`,t),x(e,r.timestamp,`${n}.timestamp`,t)&&(e.lastTimestamp!==void 0&&r.timestamp<e.lastTimestamp&&o(e,"warning","OUT_OF_ORDER_TIMESTAMP","Messages should be ordered by timestamp ascending.",c(t,`${n}.timestamp`)),e.lastTimestamp=r.timestamp);let a=typeof r.type=="number"&&Number.isInteger(r.type)&&F.has(r.type)?r.type:void 0;a===void 0?o(e,"error","INVALID_MESSAGE_TYPE","Expected a supported numeric ChatLab message type.",{...t,path:`${n}.type`}):i===y&&!$.has(a)&&o(e,"error","INVALID_SYSTEM_SENDER_TYPE","The reserved SYSTEM sender is only valid for system and recall messages.",c(t,`${n}.sender`)),(!d(r,"content")||typeof r.content!="string"&&r.content!==null)&&o(e,"error","INVALID_MESSAGE_CONTENT","Expected content to be a string or null.",{...t,path:`${n}.content`}),m(e,rLine truncated
`)}if(!w)f({ok:!1,command:"validate",error:{code:"MISSING_FILE",message:"Usage: node validate-chatlab.mjs <file>"},meta:{apiVersion:1,standalone:!0}}),process.exitCode=2;else{let e=H.resolve(w);if(!j(e))f({ok:!1,command:"validate",error:{code:"FILE_NOT_FOUND",message:`File not found: ${e}`,hint:"Pass an absolute path or a path relative to the current working directory."},meta:{apiVersion:1,standalone:!0}}),process.exitCode=3;else try{let r=await L(e);f(r.valid?{ok:!0,command:"validate",data:r,meta:{apiVersion:1,standalone:!0}}:{ok:!1,command:"validate",data:r,error:{code:"INVALID_CHATLAB_FORMAT",message:`Validation found ${r.errorCount} error(s).`,hint:"Fix every error before importing the file into ChatLab."},meta:{apiVersion:1,standalone:!0}}),r.valid||(process.exitCode=1)}catch(r){f({ok:!1,command:"validate",error:{code:"VALIDATION_FAILED",message:r instanceof Error?r.message:String(r)},meta:{apiVersion:1,standalone:!0}}),process.exitCode=1}}
import{existsSync as H}from"node:fs";import j from"node:path";import{createReadStream as P}from"node:fs";import{readFile as v,stat as k}from"node:fs/promises";import{extname as D}from"node:path";import{createInterface as V}from"node:readline";var R="0.0.2",S=["0.0.1",R];function C(e){return S.includes(e)}var h=(s=>(s[s.TEXT=0]="TEXT",s[s.IMAGE=1]="IMAGE",s[s.VOICE=2]="VOICE",s[s.VIDEO=3]="VIDEO",s[s.FILE=4]="FILE",s[s.EMOJI=5]="EMOJI",s[s.LINK=7]="LINK",s[s.LOCATION=8]="LOCATION",s[s.RED_PACKET=20]="RED_PACKET",s[s.TRANSFER=21]="TRANSFER",s[s.POKE=22]="POKE",s[s.CALL=23]="CALL",s[s.SHARE=24]="SHARE",s[s.REPLY=25]="REPLY",s[s.FORWARD=26]="FORWARD",s[s.CONTACT=27]="CONTACT",s[s.SYSTEM=80]="SYSTEM",s[s.RECALL=81]="RECALL",s[s.OTHER=99]="OTHER",s))(h||{});var G=100,M=1e11,F=new Set(Object.values(h).filter(e=>typeof e=="number")),E="SYSTEM",$=new Set([80,81]);function y(e,t){return{format:e,fileSize:t,errorCount:0,warningCount:0,issues:[],stats:{headerCount:0,memberCount:0,messageCount:0,uniqueSenderCount:0,commentLineCount:0,blankLineCount:0},memberIds:new Set,ownerIds:new Set,senderIds:new Set,messageIds:new Set,replyTargetIds:new Set}}function a(e,t,r,n,o={}){t==="error"?e.errorCount++:e.warningCount++,e.issues.length<G&&e.issues.push({severity:t,code:r,message:n,...o})}function d(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function c(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function p(e,t){return{...e,path:t}}function m(e,t,r,n){return typeof t=="string"&&t.trim().length>0?!0:(a(e,"error","INVALID_REQUIRED_STRING","Expected a non-empty string.",p(n,r)),!1)}function u(e,t,r,n,o){c(t,r)&&typeof t[r]!="string"&&a(e,"error","INVALID_OPTIONAL_STRING","Expected a string.",p(o,n))}function x(e,t,r,n){return typeof t=="number"&&Number.isInteger(t)&&t>=0&&t<M?!0:(a(e,"error","INVALID_UNIX_SECONDS","Expected a non-negative integer Unix timestamp in seconds, not milliseconds.",p(n,r)),!1)}function T(e,t,r,n,o=""){if(e.stats.headerCount++,!d(t))a(e,"error","INVALID_CHATLAB_HEADER","Expected a chatlab object.",{...n,path:`${o}chatlab`});else{let i=`${o}chatlab.version`;typeof t.version!="string"?a(e,"error","INVALID_VERSION","Expected a string format version.",{...n,path:i}):(e.version=t.version,C(t.version)||a(e,"error","UNSUPPORTED_VERSION",`Supported ChatLab format versions: ${S.join(", ")}.`,{...n,path:i})),x(e,t.exportedAt,`${o}chatlab.exportedAt`,n),u(e,t,"generator",`${o}chatlab.generator`,n),u(e,t,"description",`${o}chatlab.description`,n)}if(!d(r)){a(e,"error","INVALID_META","Expected a meta object.",{...n,path:`${o}meta`});return}m(e,r.name,`${o}meta.name`,n),m(e,r.platform,`${o}meta.platform`,n),r.type!=="group"&&r.type!=="private"&&a(e,"error","INVALID_CHAT_TYPE",'Expected chat type "group" or "private".',{...n,path:`${o}meta.type`}),u(e,r,"groupId",`${o}meta.groupId`,n),u(e,r,"groupAvatar",`${o}meta.groupAvatar`,n),c(r,"ownerId")&&m(e,r.ownerId,`${o}meta.ownerId`,n)&&e.ownerIds.add(r.ownerId),u(e,r,"sourceSessionId",`${o}meta.sourceSessionId`,n)}function _(e,t,r,n){if(e.stats.memberCount++,!d(t)){a(e,"error","INVALID_MEMBER","Expected a member object.",p(n,r));return}m(e,t.platformId,`${r}.platformId`,n)&&(e.memberIds.has(t.platformId)?a(e,"error","DUPLICATE_MEMBER_ID","Member platformId must be unique.",{...n,path:`${r}.platformId`}):e.memberIds.add(t.platformId)),m(e,t.accountName,`${r}.accountName`,n),u(e,t,"groupNickname",`${r}.groupNickname`,n),u(e,t,"avatar",`${r}.avatar`,n),c(t,"aliases")&&(!Array.isArray(t.aliases)||t.aliases.some(o=>typeof o!="string"))&&a(e,"error","INVALID_ALIASES","Expected aliases to be an array of strings.",{...n,path:`${r}.aliases`}),c(t,"roles")&&(Array.isArray(t.roles)?t.roles.forEach((o,i)=>{let g=`${r}.roles[${i}]`;if(!d(o)){a(e,"error","INVALID_ROLE","Expected a role object.",{...n,path:g});return}m(e,o.id,`${g}.id`,n),u(e,o,"name",`${g}.name`,n)}):a(e,"error","INVALID_ROLES","Expected roles to be an array.",{...n,path:`${r}.roles`}))}function N(e,t,r,n){if(e.stats.messageCount++,!d(t)){a(e,"error","INVALID_MESSAGE","Expected a message object.",p(n,r));return}let o=m(e,t.sender,`${r}.sender`,n)?t.sender:void 0;o!==void 0&&e.senderIds.add(o),m(e,t.accountName,`${r}.accountName`,n),x(e,t.timestamp,`${r}.timestamp`,n)&&(e.lastTimestamp!==void 0&&t.timestamp<e.lastTimestamp&&a(e,"warning","OUT_OF_ORDER_TIMESTAMP","Messages should be ordered by timestamp ascending.",p(n,`${r}.timestamp`)),e.lastTimestamp=t.timestamp);let i=typeof t.type=="number"&&Number.isInteger(t.type)&&F.has(t.type)?t.type:void 0;i===void 0?a(e,"error","INVALID_MESSAGE_TYPE","Expected a supported numeric ChatLab message type.",{...n,path:`${r}.type`}):o===E&&!$.has(i)&&a(e,"error","INVALID_SYSTEM_SENDER_TYPE","The reserved SYSTEM sender is only valid for system and recall messages.",p(n,`${r}.sender`)),(!c(t,"content")||typeof t.content!="string"&&t.content!==null)&&a(e,"error","INVALID_MESSAGE_CONTENT","Expected content to be a string or null.",{...n,path:`${r}.content`}),u(e,tLine truncated
`)}if(!O)f({ok:!1,command:"validate",error:{code:"MISSING_FILE",message:"Usage: node validate-chatlab.mjs <file>"},meta:{apiVersion:1,standalone:!0}}),process.exitCode=2;else{let e=j.resolve(O);if(!H(e))f({ok:!1,command:"validate",error:{code:"FILE_NOT_FOUND",message:`File not found: ${e}`,hint:"Pass an absolute path or a path relative to the current working directory."},meta:{apiVersion:1,standalone:!0}}),process.exitCode=3;else try{let t=await L(e);f(t.valid?{ok:!0,command:"validate",data:t,meta:{apiVersion:1,standalone:!0}}:{ok:!1,command:"validate",data:t,error:{code:"INVALID_CHATLAB_FORMAT",message:`Validation found ${t.errorCount} error(s).`,hint:"Fix every error before importing the file into ChatLab."},meta:{apiVersion:1,standalone:!0}}),t.valid||(process.exitCode=1)}catch(t){f({ok:!1,command:"validate",error:{code:"VALIDATION_FAILED",message:t instanceof Error?t.message:String(t)},meta:{apiVersion:1,standalone:!0}}),process.exitCode=1}}