@treeseed/core 0.6.25 → 0.6.27
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.
|
@@ -3,6 +3,10 @@ async function hasRuntimeRecordsTable(db) {
|
|
|
3
3
|
const row = await db.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'runtime_records' LIMIT 1").first();
|
|
4
4
|
return Boolean(row?.name);
|
|
5
5
|
}
|
|
6
|
+
async function tableColumns(db, tableName) {
|
|
7
|
+
const { results } = await db.prepare(`PRAGMA table_info(${tableName})`).all();
|
|
8
|
+
return new Set(results.map((row) => row.name).filter((name) => Boolean(name)));
|
|
9
|
+
}
|
|
6
10
|
async function createContactSubmission(db, input) {
|
|
7
11
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
8
12
|
const ipHash = await hashValue(input.ip || "unknown");
|
|
@@ -43,6 +47,29 @@ async function createContactSubmission(db, input) {
|
|
|
43
47
|
).run();
|
|
44
48
|
return;
|
|
45
49
|
}
|
|
50
|
+
const columns = await tableColumns(db, "contact_submissions");
|
|
51
|
+
if (!columns.has("contact_type")) {
|
|
52
|
+
await db.prepare(
|
|
53
|
+
`INSERT INTO contact_submissions (
|
|
54
|
+
email,
|
|
55
|
+
message,
|
|
56
|
+
created_at
|
|
57
|
+
) VALUES (?, ?, ?)`
|
|
58
|
+
).bind(
|
|
59
|
+
input.email,
|
|
60
|
+
[
|
|
61
|
+
input.subject,
|
|
62
|
+
"",
|
|
63
|
+
input.message,
|
|
64
|
+
"",
|
|
65
|
+
`Name: ${input.name}`,
|
|
66
|
+
input.organization ? `Organization: ${input.organization}` : null,
|
|
67
|
+
`Contact type: ${input.contactType}`
|
|
68
|
+
].filter(Boolean).join("\n"),
|
|
69
|
+
now
|
|
70
|
+
).run();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
46
73
|
await db.prepare(
|
|
47
74
|
`INSERT INTO contact_submissions (
|
|
48
75
|
name,
|
|
@@ -3,7 +3,7 @@ async function createSocketContext(port, host) {
|
|
|
3
3
|
const socket = connect(
|
|
4
4
|
{ hostname: host, port },
|
|
5
5
|
{
|
|
6
|
-
secureTransport: port === 465 ? "on" : "off"
|
|
6
|
+
secureTransport: port === 465 ? "on" : port === 587 ? "starttls" : "off"
|
|
7
7
|
}
|
|
8
8
|
);
|
|
9
9
|
return {
|
|
@@ -63,6 +63,8 @@ async function upgradeToTls(context) {
|
|
|
63
63
|
if (typeof context.socket.startTls !== "function") {
|
|
64
64
|
throw new Error("SMTP socket does not support STARTTLS upgrade.");
|
|
65
65
|
}
|
|
66
|
+
context.reader.releaseLock();
|
|
67
|
+
context.writer.releaseLock();
|
|
66
68
|
const secureSocket = context.socket.startTls();
|
|
67
69
|
return {
|
|
68
70
|
socket: secureSocket,
|
|
@@ -3,6 +3,10 @@ async function hasRuntimeRecordsTable(db) {
|
|
|
3
3
|
const row = await db.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'runtime_records' LIMIT 1").first();
|
|
4
4
|
return Boolean(row?.name);
|
|
5
5
|
}
|
|
6
|
+
async function hasTable(db, tableName) {
|
|
7
|
+
const row = await db.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ? LIMIT 1").bind(tableName).first();
|
|
8
|
+
return Boolean(row?.name);
|
|
9
|
+
}
|
|
6
10
|
async function upsertSubscriber(db, input) {
|
|
7
11
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
8
12
|
const ipHash = await hashValue(input.ip || "unknown");
|
|
@@ -36,17 +40,25 @@ async function upsertSubscriber(db, input) {
|
|
|
36
40
|
).bind("subscription", input.email, input.email, now, now, payloadJson, metaJson).run();
|
|
37
41
|
return;
|
|
38
42
|
}
|
|
43
|
+
if (await hasTable(db, "subscriptions")) {
|
|
44
|
+
await db.prepare(
|
|
45
|
+
`INSERT INTO subscriptions (email, name, status, source, consent_at, created_at, updated_at, ip_hash)
|
|
46
|
+
VALUES (?, ?, 'active', ?, ?, ?, ?, ?)
|
|
47
|
+
ON CONFLICT(email) DO UPDATE SET
|
|
48
|
+
name = excluded.name,
|
|
49
|
+
status = 'active',
|
|
50
|
+
source = excluded.source,
|
|
51
|
+
consent_at = excluded.consent_at,
|
|
52
|
+
updated_at = excluded.updated_at,
|
|
53
|
+
ip_hash = excluded.ip_hash`
|
|
54
|
+
).bind(input.email, input.name || null, input.source, now, now, now, ipHash).run();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
39
57
|
await db.prepare(
|
|
40
|
-
`INSERT INTO
|
|
41
|
-
VALUES (?,
|
|
42
|
-
ON CONFLICT(email) DO
|
|
43
|
-
|
|
44
|
-
status = 'active',
|
|
45
|
-
source = excluded.source,
|
|
46
|
-
consent_at = excluded.consent_at,
|
|
47
|
-
updated_at = excluded.updated_at,
|
|
48
|
-
ip_hash = excluded.ip_hash`
|
|
49
|
-
).bind(input.email, input.name || null, input.source, now, now, now, ipHash).run();
|
|
58
|
+
`INSERT INTO subscribers (email, created_at)
|
|
59
|
+
VALUES (?, ?)
|
|
60
|
+
ON CONFLICT(email) DO NOTHING`
|
|
61
|
+
).bind(input.email, now).run();
|
|
50
62
|
}
|
|
51
63
|
export {
|
|
52
64
|
upsertSubscriber
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@treeseed/core",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.27",
|
|
4
4
|
"description": "Treeseed integrated platform starter for Astro/Starlight web runtimes and Hono API runtimes.",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"repository": {
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"@astrojs/sitemap": "3.7.0",
|
|
77
77
|
"@astrojs/starlight": "0.37.6",
|
|
78
78
|
"@tailwindcss/vite": "^4.1.4",
|
|
79
|
-
"@treeseed/sdk": "0.6.
|
|
79
|
+
"@treeseed/sdk": "0.6.26",
|
|
80
80
|
"astro": "^5.6.1",
|
|
81
81
|
"esbuild": "^0.28.0",
|
|
82
82
|
"hono": "^4.8.2",
|