meta-messenger.js 0.0.1 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,32 +1,41 @@
1
- import { execSync } from 'node:child_process'
2
-
3
- export function detectPlatform() {
4
- const platform = process.platform
5
- const arch = process.arch
6
- const isMusl = detectMusl()
7
-
8
- const libc = platform === 'linux' ? (isMusl ? 'musl' : 'gnu') : ''
9
- const triplet = platform === 'linux' ? `${platform}-${arch}-${libc}` : `${platform}-${arch}`
10
-
11
- const ext = platform === 'win32' ? 'dll' : platform === 'darwin' ? 'dylib' : 'so'
12
-
13
- return { platform, arch, libc, triplet, ext }
14
- }
15
-
16
- function detectMusl() {
17
- try {
18
- if (process.platform !== 'linux') return false
19
- if (process.report && typeof process.report.getReport === 'function') {
20
- const rep = process.report.getReport()
21
- const glibc = rep.header && rep.header.glibcVersionRuntime
22
- return !glibc
23
- }
24
- } catch {}
25
- try {
26
- const out = execSync('ldd --version 2>&1 || true', { encoding: 'utf8' })
27
- return /musl/i.test(out)
28
- } catch {}
29
- return false
30
- }
31
-
32
- export default detectPlatform
1
+ /*
2
+ * meta-messenger.js, Unofficial Meta Messenger Chat API for NodeJS
3
+ * Copyright (c) 2026 Elysia and contributors
4
+ */
5
+
6
+ import { execSync } from "node:child_process";
7
+
8
+ export function detectPlatform() {
9
+ const { platform } = process;
10
+ const { arch } = process;
11
+ const isMusl = detectMusl();
12
+
13
+ const libc = platform === "linux" ? (isMusl ? "musl" : "gnu") : "";
14
+ const triplet = platform === "linux" ? `${platform}-${arch}-${libc}` : `${platform}-${arch}`;
15
+
16
+ const ext = platform === "win32" ? "dll" : platform === "darwin" ? "dylib" : "so";
17
+
18
+ return { platform, arch, libc, triplet, ext };
19
+ }
20
+
21
+ function detectMusl() {
22
+ try {
23
+ if (process.platform !== "linux") return false;
24
+ if (process.report && typeof process.report.getReport === "function") {
25
+ const rep = process.report.getReport();
26
+ const glibc = rep.header && rep.header.glibcVersionRuntime;
27
+ return !glibc;
28
+ }
29
+ } catch {
30
+ //
31
+ }
32
+ try {
33
+ const out = execSync("ldd --version 2>&1 || true", { encoding: "utf8" });
34
+ return /musl/i.test(out);
35
+ } catch {
36
+ //
37
+ }
38
+ return false;
39
+ }
40
+
41
+ export default detectPlatform;
@@ -1,88 +1,126 @@
1
- import { createWriteStream } from 'node:fs'
2
- import { mkdir, unlink, rename } from 'node:fs/promises'
3
- import { join, dirname } from 'node:path'
4
- import { fileURLToPath } from 'node:url'
5
- import https from 'node:https'
6
- import { detectPlatform } from './detect-platform.mjs'
7
- import { packageJson as pkg } from './package.mjs'
8
-
9
- const __dirname = dirname(fileURLToPath(import.meta.url))
10
-
11
- function defaultRepoSlug() {
12
- const repo = pkg.repository
13
- if (typeof repo === 'string') {
14
- const m = repo.match(/github:(.+)/i)
15
- if (m) return m[1]
16
- if (/^[\w-]+\/[\w.-]+$/.test(repo)) return repo
17
- } else if (repo && typeof repo === 'object' && repo.url) {
18
- const m = repo.url.match(/github\.com[:/]+([^#]+?)(?:\.git)?$/i)
19
- if (m) return m[1]
20
- }
21
- return `${pkg.author}/${pkg.name}`
22
- }
23
-
24
- function buildBaseURL() {
25
- const repo = defaultRepoSlug()
26
- const versionTag = `v${pkg.version}`
27
- const baseURL = `https://github.com/${repo}/releases/download/${versionTag}`
28
- return baseURL.replace(/\/$/, '')
29
- }
30
-
31
- function httpGet(url) {
32
- return new Promise((resolve, reject) => {
33
- https
34
- .get(url, (res) => {
35
- if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
36
- return resolve(httpGet(res.headers.location))
37
- }
38
- if (res.statusCode !== 200) {
39
- return reject(new Error(`HTTP ${res.statusCode} for ${url}`))
40
- }
41
- resolve(res)
42
- })
43
- .on('error', reject)
44
- })
45
- }
46
-
47
- async function downloadTo(url, dstPath) {
48
- await mkdir(dirname(dstPath), { recursive: true })
49
- const tmp = `${dstPath}.download`
50
- try { await unlink(tmp) } catch {}
51
- const res = await httpGet(url)
52
- await new Promise((resolve, reject) => {
53
- const out = createWriteStream(tmp)
54
- res.pipe(out)
55
- res.on('error', reject)
56
- out.on('error', reject)
57
- out.on('finish', resolve)
58
- })
59
- await rename(tmp, dstPath)
60
- }
61
-
62
- export async function downloadPrebuilt() {
63
- const { triplet, ext } = detectPlatform()
64
- const baseURL = buildBaseURL()
65
- const filename = `messagix-${triplet}.${ext}`
66
- const url = `${baseURL}/${filename}`
67
-
68
- const out = join(__dirname, '..', 'build', `messagix.${ext}`)
69
- try {
70
- await downloadTo(url, out)
71
- console.log(`[${pkg.name}] Downloaded prebuilt from ${url}`)
72
- return true
73
- } catch (err) {
74
- console.warn(`[${pkg.name}] No remote prebuilt found at ${url}:`, err?.message || String(err))
75
- return false
76
- }
77
- }
78
-
79
- // node scripts/download-prebuilt.mjs
80
- const isMain = process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1]
81
- if (isMain) {
82
- downloadPrebuilt()
83
- .then((ok) => { if (!ok) process.exit(1) })
84
- .catch((err) => {
85
- console.error(`[${pkg.name}] download-prebuilt failed:`, err?.message || String(err))
86
- process.exit(1)
87
- })
88
- }
1
+ /*
2
+ * meta-messenger.js, Unofficial Meta Messenger Chat API for NodeJS
3
+ * Copyright (c) 2026 Elysia and contributors
4
+ */
5
+
6
+ import { createWriteStream } from "node:fs";
7
+ import { mkdir, rename, unlink } from "node:fs/promises";
8
+ import https from "node:https";
9
+ import { dirname, join } from "node:path";
10
+ import { fileURLToPath } from "node:url";
11
+
12
+ import { detectPlatform } from "./detect-platform.mjs";
13
+ import { packageJson as pkg } from "./package.mjs";
14
+
15
+ const __dirname = dirname(fileURLToPath(import.meta.url));
16
+
17
+ function defaultRepoSlug() {
18
+ const repo = pkg.repository;
19
+ if (typeof repo === "string") {
20
+ const m = repo.match(/github:(.+)/i);
21
+ if (m) return m[1];
22
+ if (/^[\w-]+\/[\w.-]+$/.test(repo)) return repo;
23
+ } else if (repo && typeof repo === "object" && repo.url) {
24
+ const m = repo.url.match(/github\.com[:/]+([^#]+?)(?:\.git)?$/i);
25
+ if (m) return m[1];
26
+ }
27
+ return `${pkg.author}/${pkg.name}`;
28
+ }
29
+
30
+ function buildBaseURL() {
31
+ const repo = defaultRepoSlug();
32
+ const versionTag = `v${pkg.version}`;
33
+ const baseURL = `https://github.com/${repo}/releases/download/${versionTag}`;
34
+ return baseURL.replace(/\/$/, "");
35
+ }
36
+
37
+ function httpGet(url, redirectCount = 0) {
38
+ console.log(`[${pkg.name}] HTTP GET: ${url}${redirectCount > 0 ? ` (redirect #${redirectCount})` : ""}`);
39
+ const reqStart = Date.now();
40
+ return new Promise((resolve, reject) => {
41
+ https
42
+ .get(url, res => {
43
+ console.log(`[${pkg.name}] Response: HTTP ${res.statusCode} in ${Date.now() - reqStart}ms`);
44
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
45
+ console.log(`[${pkg.name}] Following redirect to: ${res.headers.location}`);
46
+ return resolve(httpGet(res.headers.location, redirectCount + 1));
47
+ }
48
+ if (res.statusCode !== 200) {
49
+ return reject(new Error(`HTTP ${res.statusCode} for ${url}`));
50
+ }
51
+ resolve(res);
52
+ })
53
+ .on("error", err => {
54
+ console.log(`[${pkg.name}] HTTP error after ${Date.now() - reqStart}ms:`, err?.message);
55
+ reject(err);
56
+ });
57
+ });
58
+ }
59
+
60
+ async function downloadTo(url, dstPath) {
61
+ console.log(`[${pkg.name}] Downloading to: ${dstPath}`);
62
+ await mkdir(dirname(dstPath), { recursive: true });
63
+ const tmp = `${dstPath}.download`;
64
+ try {
65
+ await unlink(tmp);
66
+ } catch {
67
+ //
68
+ }
69
+ const res = await httpGet(url);
70
+ console.log(`[${pkg.name}] Starting file write...`);
71
+ const writeStart = Date.now();
72
+ let bytesWritten = 0;
73
+ await new Promise((resolve, reject) => {
74
+ const out = createWriteStream(tmp);
75
+ res.on("data", chunk => {
76
+ bytesWritten += chunk.length;
77
+ });
78
+ res.pipe(out);
79
+ res.on("error", reject);
80
+ out.on("error", reject);
81
+ out.on("finish", () => {
82
+ console.log(`[${pkg.name}] File write completed: ${bytesWritten} bytes in ${Date.now() - writeStart}ms`);
83
+ // Destroy the response stream to release the socket
84
+ res.destroy();
85
+ resolve();
86
+ });
87
+ });
88
+ await rename(tmp, dstPath);
89
+ console.log(`[${pkg.name}] File renamed to final destination`);
90
+ }
91
+
92
+ export async function downloadPrebuilt() {
93
+ console.log(`[${pkg.name}] downloadPrebuilt() started`);
94
+ const { triplet, ext } = detectPlatform();
95
+ const baseURL = buildBaseURL();
96
+ const filename = `messagix-${triplet}.${ext}`;
97
+ const url = `${baseURL}/${filename}`;
98
+ console.log(`[${pkg.name}] Target URL: ${url}`);
99
+
100
+ const out = join(__dirname, "..", "build", `messagix.${ext}`);
101
+ const totalStart = Date.now();
102
+ try {
103
+ await downloadTo(url, out);
104
+ console.log(`[${pkg.name}] Downloaded prebuilt from ${url} in ${Date.now() - totalStart}ms`);
105
+ return true;
106
+ } catch (err) {
107
+ console.warn(
108
+ `[${pkg.name}] No remote prebuilt found at ${url} (after ${Date.now() - totalStart}ms):`,
109
+ err?.message || String(err),
110
+ );
111
+ return false;
112
+ }
113
+ }
114
+
115
+ // node scripts/download-prebuilt.mjs
116
+ const isMain = process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1];
117
+ if (isMain) {
118
+ downloadPrebuilt()
119
+ .then(ok => {
120
+ if (!ok) process.exit(1);
121
+ })
122
+ .catch(err => {
123
+ console.error(`[${pkg.name}] download-prebuilt failed:`, err?.message || String(err));
124
+ process.exit(1);
125
+ });
126
+ }
@@ -1,6 +1,11 @@
1
- import { readFileSync } from 'node:fs'
2
- import { dirname, join } from 'node:path'
3
- import { fileURLToPath } from 'node:url'
4
-
5
- const __dirname = dirname(fileURLToPath(import.meta.url))
6
- export const packageJson = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'))
1
+ /*
2
+ * meta-messenger.js, Unofficial Meta Messenger Chat API for NodeJS
3
+ * Copyright (c) 2026 Elysia and contributors
4
+ */
5
+
6
+ import { readFileSync } from "node:fs";
7
+ import { dirname, join } from "node:path";
8
+ import { fileURLToPath } from "node:url";
9
+
10
+ const __dirname = dirname(fileURLToPath(import.meta.url));
11
+ export const packageJson = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
@@ -1,73 +1,109 @@
1
- import { existsSync } from 'node:fs'
2
- import { mkdir, copyFile, rm } from 'node:fs/promises'
3
- import { join, dirname } from 'node:path'
4
- import { fileURLToPath } from 'node:url'
5
- import { spawnSync } from 'node:child_process'
6
- import { detectPlatform } from './detect-platform.mjs'
7
- import { downloadPrebuilt } from './download-prebuilt.mjs'
8
- import { packageJson as pkg } from './package.mjs'
9
-
10
- const __dirname = dirname(fileURLToPath(import.meta.url))
11
-
12
- async function copyIfExists(src, dst) {
13
- try {
14
- await mkdir(dirname(dst), { recursive: true })
15
- await copyFile(src, dst)
16
- return true
17
- } catch (err) {
18
- if (err?.code === 'ENOENT') return false
19
- throw err
20
- }
21
- }
22
-
23
- async function run() {
24
- if (process.env.MESSAGIX_SKIP_POSTINSTALL === 'true') {
25
- console.log(`[${pkg.name}] Skipping postinstall (MESSAGIX_SKIP_POSTINSTALL=true)`)
26
- return
27
- }
28
-
29
- const { triplet, ext } = detectPlatform()
30
- const buildOut = join(__dirname, '..', 'build', `messagix.${ext}`)
31
-
32
- // 1) Prefer local prebuilt shipped in npm tarball
33
- const prebuiltDir = join(__dirname, '..', 'prebuilt', triplet)
34
- const prebuilt = join(prebuiltDir, `messagix.${ext}`)
35
- if (await copyIfExists(prebuilt, buildOut)) {
36
- console.log(`[${pkg.name}] Using local prebuilt for ${triplet}`)
37
- if (process.env.MESSAGIX_KEEP_PREBUILT !== 'true') {
38
- try { await rm(prebuiltDir, { recursive: true, force: true }) } catch {}
39
- }
40
- return
41
- }
42
-
43
- // 2) Try remote prebuilt from GitHub Releases
44
- try { if (await downloadPrebuilt()) return } catch {}
45
-
46
- // 3) No prebuilt available. Try local build if allowed
47
- if (process.env.MESSAGIX_BUILD_FROM_SOURCE === 'true') {
48
- console.log(`[${pkg.name}] No prebuilt found. Attempting local build...`)
49
- try {
50
- const res = spawnSync(
51
- process.platform === 'win32' ? 'npm.cmd' : 'npm',
52
- ['run', 'build:go'],
53
- { cwd: join(__dirname, '..'), stdio: 'inherit', env: process.env }
54
- )
55
- if (res.status === 0 && existsSync(buildOut)) return
56
- console.warn(`[${pkg.name}] Local build did not produce the native library.`)
57
- } catch (err) {
58
- console.warn(`[${pkg.name}] Local build failed:`, err?.message || String(err))
59
- }
60
- }
61
-
62
- console.warn(`[${pkg.name}] No prebuilt found (local/remote) and no local build completed.`)
63
- console.warn(`[${pkg.name}] Expected triplet: ${triplet}, file: messagix-${triplet}.${ext}`)
64
- console.warn(
65
- `[${pkg.name}] You can:\n` +
66
- ` - set MESSAGIX_BUILD_FROM_SOURCE=true and re-run install\n` +
67
- ` - or build manually with: npm run build:go`
68
- )
69
- }
70
-
71
- run().catch((err) => {
72
- console.error(`[${pkg.name}] postinstall failed:`, err?.message || String(err))
73
- })
1
+ /*
2
+ * meta-messenger.js, Unofficial Meta Messenger Chat API for NodeJS
3
+ * Copyright (c) 2026 Elysia and contributors
4
+ */
5
+
6
+ import { spawnSync } from "node:child_process";
7
+ import { existsSync } from "node:fs";
8
+ import { copyFile, mkdir, rm } from "node:fs/promises";
9
+ import { dirname, join } from "node:path";
10
+ import { fileURLToPath } from "node:url";
11
+
12
+ import { detectPlatform } from "./detect-platform.mjs";
13
+ import { downloadPrebuilt } from "./download-prebuilt.mjs";
14
+ import { packageJson as pkg } from "./package.mjs";
15
+
16
+ const __dirname = dirname(fileURLToPath(import.meta.url));
17
+
18
+ async function copyIfExists(src, dst) {
19
+ try {
20
+ await mkdir(dirname(dst), { recursive: true });
21
+ await copyFile(src, dst);
22
+ return true;
23
+ } catch (err) {
24
+ if (err?.code === "ENOENT") return false;
25
+ throw err;
26
+ }
27
+ }
28
+
29
+ async function run() {
30
+ console.log(`[${pkg.name}] postinstall started`);
31
+ const startTime = Date.now();
32
+
33
+ if (process.env.MESSAGIX_SKIP_POSTINSTALL === "true") {
34
+ console.log(`[${pkg.name}] Skipping postinstall (MESSAGIX_SKIP_POSTINSTALL=true)`);
35
+ return;
36
+ }
37
+
38
+ console.log(`[${pkg.name}] Detecting platform...`);
39
+ const { triplet, ext } = detectPlatform();
40
+ console.log(`[${pkg.name}] Platform: ${triplet}, ext: ${ext}`);
41
+
42
+ const buildOut = join(__dirname, "..", "build", `messagix.${ext}`);
43
+ console.log(`[${pkg.name}] Build output path: ${buildOut}`);
44
+
45
+ // 1) Prefer local prebuilt shipped in npm tarball
46
+ const prebuiltDir = join(__dirname, "..", "prebuilt", triplet);
47
+ const prebuilt = join(prebuiltDir, `messagix.${ext}`);
48
+ console.log(`[${pkg.name}] Checking local prebuilt at: ${prebuilt}`);
49
+ if (await copyIfExists(prebuilt, buildOut)) {
50
+ console.log(`[${pkg.name}] Using local prebuilt for ${triplet}`);
51
+ if (process.env.MESSAGIX_KEEP_PREBUILT !== "true") {
52
+ try {
53
+ await rm(prebuiltDir, { recursive: true, force: true });
54
+ } catch {
55
+ //
56
+ }
57
+ }
58
+ console.log(`[${pkg.name}] postinstall completed in ${Date.now() - startTime}ms`);
59
+ return;
60
+ }
61
+ console.log(`[${pkg.name}] No local prebuilt found`);
62
+
63
+ // 2) Try remote prebuilt from GitHub Releases
64
+ console.log(`[${pkg.name}] Attempting to download remote prebuilt...`);
65
+ const downloadStart = Date.now();
66
+ try {
67
+ if (await downloadPrebuilt()) {
68
+ console.log(`[${pkg.name}] Download completed in ${Date.now() - downloadStart}ms`);
69
+ console.log(`[${pkg.name}] postinstall completed in ${Date.now() - startTime}ms`);
70
+ return;
71
+ }
72
+ } catch (err) {
73
+ console.log(
74
+ `[${pkg.name}] Download failed after ${Date.now() - downloadStart}ms:`,
75
+ err?.message || String(err),
76
+ );
77
+ }
78
+
79
+ // 3) No prebuilt available. Try local build if allowed
80
+ if (process.env.MESSAGIX_BUILD_FROM_SOURCE === "true") {
81
+ console.log(`[${pkg.name}] No prebuilt found. Attempting local build...`);
82
+ try {
83
+ const res = spawnSync(process.platform === "win32" ? "npm.cmd" : "npm", ["run", "build:go"], {
84
+ cwd: join(__dirname, ".."),
85
+ stdio: "inherit",
86
+ env: process.env,
87
+ });
88
+ if (res.status === 0 && existsSync(buildOut)) return;
89
+ console.warn(`[${pkg.name}] Local build did not produce the native library.`);
90
+ } catch (err) {
91
+ console.warn(`[${pkg.name}] Local build failed:`, err?.message || String(err));
92
+ }
93
+ }
94
+
95
+ console.warn(`[${pkg.name}] No prebuilt found (local/remote) and no local build completed.`);
96
+ console.warn(`[${pkg.name}] Expected triplet: ${triplet}, file: messagix-${triplet}.${ext}`);
97
+ console.warn(
98
+ `[${pkg.name}] You can:\n` +
99
+ " - set MESSAGIX_BUILD_FROM_SOURCE=true and re-run install\n" +
100
+ " - or build manually with: npm run build:go",
101
+ );
102
+ }
103
+
104
+ run()
105
+ .then(() => process.exit(0))
106
+ .catch(err => {
107
+ console.error(`[${pkg.name}] postinstall failed:`, err?.message || String(err));
108
+ process.exit(1);
109
+ });