@rankmyseo/storage 0.1.0
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.
- package/LICENSE +201 -0
- package/dist/index.cjs +641 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +605 -0
- package/dist/index.js.map +1 -0
- package/package.json +45 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,641 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
createSqliteStore: () => createSqliteStore,
|
|
34
|
+
createStore: () => createStore
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(index_exports);
|
|
37
|
+
var import_server_only3 = require("server-only");
|
|
38
|
+
|
|
39
|
+
// src/factory.ts
|
|
40
|
+
var import_server_only2 = require("server-only");
|
|
41
|
+
|
|
42
|
+
// src/sqlite-store.ts
|
|
43
|
+
var import_server_only = require("server-only");
|
|
44
|
+
var import_node_crypto = require("crypto");
|
|
45
|
+
var import_better_sqlite3 = __toESM(require("better-sqlite3"), 1);
|
|
46
|
+
var import_better_sqlite32 = require("drizzle-orm/better-sqlite3");
|
|
47
|
+
var import_drizzle_orm = require("drizzle-orm");
|
|
48
|
+
|
|
49
|
+
// src/schema/sqlite.ts
|
|
50
|
+
var import_sqlite_core = require("drizzle-orm/sqlite-core");
|
|
51
|
+
var projects = (0, import_sqlite_core.sqliteTable)("rms_projects", {
|
|
52
|
+
id: (0, import_sqlite_core.text)("id").primaryKey(),
|
|
53
|
+
tenantId: (0, import_sqlite_core.text)("tenant_id").notNull(),
|
|
54
|
+
name: (0, import_sqlite_core.text)("name").notNull(),
|
|
55
|
+
domain: (0, import_sqlite_core.text)("domain").notNull(),
|
|
56
|
+
createdAt: (0, import_sqlite_core.integer)("created_at", { mode: "timestamp_ms" }).notNull(),
|
|
57
|
+
updatedAt: (0, import_sqlite_core.integer)("updated_at", { mode: "timestamp_ms" }).notNull()
|
|
58
|
+
});
|
|
59
|
+
var keywords = (0, import_sqlite_core.sqliteTable)("rms_keywords", {
|
|
60
|
+
id: (0, import_sqlite_core.text)("id").primaryKey(),
|
|
61
|
+
tenantId: (0, import_sqlite_core.text)("tenant_id").notNull(),
|
|
62
|
+
projectId: (0, import_sqlite_core.text)("project_id").notNull(),
|
|
63
|
+
text: (0, import_sqlite_core.text)("text").notNull(),
|
|
64
|
+
country: (0, import_sqlite_core.text)("country").notNull(),
|
|
65
|
+
device: (0, import_sqlite_core.text)("device").notNull(),
|
|
66
|
+
tags: (0, import_sqlite_core.text)("tags").notNull(),
|
|
67
|
+
createdAt: (0, import_sqlite_core.integer)("created_at", { mode: "timestamp_ms" }).notNull()
|
|
68
|
+
});
|
|
69
|
+
var rankSnapshots = (0, import_sqlite_core.sqliteTable)("rms_rank_snapshots", {
|
|
70
|
+
id: (0, import_sqlite_core.text)("id").primaryKey(),
|
|
71
|
+
tenantId: (0, import_sqlite_core.text)("tenant_id").notNull(),
|
|
72
|
+
projectId: (0, import_sqlite_core.text)("project_id").notNull(),
|
|
73
|
+
keywordId: (0, import_sqlite_core.text)("keyword_id").notNull(),
|
|
74
|
+
position: (0, import_sqlite_core.integer)("position"),
|
|
75
|
+
url: (0, import_sqlite_core.text)("url"),
|
|
76
|
+
source: (0, import_sqlite_core.text)("source").notNull(),
|
|
77
|
+
device: (0, import_sqlite_core.text)("device").notNull(),
|
|
78
|
+
country: (0, import_sqlite_core.text)("country").notNull(),
|
|
79
|
+
capturedAt: (0, import_sqlite_core.integer)("captured_at", { mode: "timestamp_ms" }).notNull(),
|
|
80
|
+
serpFeatures: (0, import_sqlite_core.text)("serp_features")
|
|
81
|
+
});
|
|
82
|
+
var audits = (0, import_sqlite_core.sqliteTable)("rms_audits", {
|
|
83
|
+
id: (0, import_sqlite_core.text)("id").primaryKey(),
|
|
84
|
+
tenantId: (0, import_sqlite_core.text)("tenant_id").notNull(),
|
|
85
|
+
projectId: (0, import_sqlite_core.text)("project_id").notNull(),
|
|
86
|
+
url: (0, import_sqlite_core.text)("url").notNull(),
|
|
87
|
+
score: (0, import_sqlite_core.integer)("score").notNull(),
|
|
88
|
+
checks: (0, import_sqlite_core.text)("checks").notNull().default("[]"),
|
|
89
|
+
createdAt: (0, import_sqlite_core.integer)("created_at", { mode: "timestamp_ms" }).notNull()
|
|
90
|
+
});
|
|
91
|
+
var reports = (0, import_sqlite_core.sqliteTable)("rms_reports", {
|
|
92
|
+
id: (0, import_sqlite_core.text)("id").primaryKey(),
|
|
93
|
+
tenantId: (0, import_sqlite_core.text)("tenant_id").notNull(),
|
|
94
|
+
projectId: (0, import_sqlite_core.text)("project_id").notNull(),
|
|
95
|
+
title: (0, import_sqlite_core.text)("title").notNull(),
|
|
96
|
+
from: (0, import_sqlite_core.integer)("from", { mode: "timestamp_ms" }).notNull(),
|
|
97
|
+
to: (0, import_sqlite_core.integer)("to", { mode: "timestamp_ms" }).notNull(),
|
|
98
|
+
summary: (0, import_sqlite_core.text)("summary"),
|
|
99
|
+
createdAt: (0, import_sqlite_core.integer)("created_at", { mode: "timestamp_ms" }).notNull()
|
|
100
|
+
});
|
|
101
|
+
var dashboardConfigs = (0, import_sqlite_core.sqliteTable)("rms_dashboard_configs", {
|
|
102
|
+
id: (0, import_sqlite_core.text)("id").primaryKey(),
|
|
103
|
+
tenantId: (0, import_sqlite_core.text)("tenant_id").notNull(),
|
|
104
|
+
projectId: (0, import_sqlite_core.text)("project_id").notNull(),
|
|
105
|
+
widgets: (0, import_sqlite_core.text)("widgets").notNull(),
|
|
106
|
+
updatedAt: (0, import_sqlite_core.integer)("updated_at", { mode: "timestamp_ms" }).notNull()
|
|
107
|
+
});
|
|
108
|
+
var blogPosts = (0, import_sqlite_core.sqliteTable)("rms_blog_posts", {
|
|
109
|
+
id: (0, import_sqlite_core.text)("id").primaryKey(),
|
|
110
|
+
tenantId: (0, import_sqlite_core.text)("tenant_id").notNull(),
|
|
111
|
+
projectId: (0, import_sqlite_core.text)("project_id").notNull(),
|
|
112
|
+
title: (0, import_sqlite_core.text)("title").notNull(),
|
|
113
|
+
slug: (0, import_sqlite_core.text)("slug").notNull(),
|
|
114
|
+
content: (0, import_sqlite_core.text)("content").notNull().default(""),
|
|
115
|
+
targetKeyword: (0, import_sqlite_core.text)("target_keyword").notNull().default(""),
|
|
116
|
+
intent: (0, import_sqlite_core.text)("intent").notNull().default("informational"),
|
|
117
|
+
metaTitle: (0, import_sqlite_core.text)("meta_title").notNull().default(""),
|
|
118
|
+
metaDescription: (0, import_sqlite_core.text)("meta_description").notNull().default(""),
|
|
119
|
+
status: (0, import_sqlite_core.text)("status").notNull().default("draft"),
|
|
120
|
+
createdAt: (0, import_sqlite_core.integer)("created_at", { mode: "timestamp_ms" }).notNull(),
|
|
121
|
+
updatedAt: (0, import_sqlite_core.integer)("updated_at", { mode: "timestamp_ms" }).notNull()
|
|
122
|
+
});
|
|
123
|
+
var sqliteSchema = {
|
|
124
|
+
projects,
|
|
125
|
+
keywords,
|
|
126
|
+
rankSnapshots,
|
|
127
|
+
audits,
|
|
128
|
+
reports,
|
|
129
|
+
dashboardConfigs,
|
|
130
|
+
blogPosts
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// src/sqlite-store.ts
|
|
134
|
+
function mapBlogRow(row) {
|
|
135
|
+
return {
|
|
136
|
+
id: row.id,
|
|
137
|
+
tenantId: row.tenantId,
|
|
138
|
+
projectId: row.projectId,
|
|
139
|
+
title: row.title,
|
|
140
|
+
slug: row.slug,
|
|
141
|
+
content: row.content,
|
|
142
|
+
targetKeyword: row.targetKeyword,
|
|
143
|
+
intent: row.intent,
|
|
144
|
+
metaTitle: row.metaTitle,
|
|
145
|
+
metaDescription: row.metaDescription,
|
|
146
|
+
status: row.status,
|
|
147
|
+
createdAt: row.createdAt,
|
|
148
|
+
updatedAt: row.updatedAt
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function parseChecks(raw) {
|
|
152
|
+
if (!raw) return [];
|
|
153
|
+
try {
|
|
154
|
+
const parsed = JSON.parse(raw);
|
|
155
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
156
|
+
} catch {
|
|
157
|
+
return [];
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function parseSummary(raw) {
|
|
161
|
+
if (!raw) return void 0;
|
|
162
|
+
try {
|
|
163
|
+
return JSON.parse(raw);
|
|
164
|
+
} catch {
|
|
165
|
+
return void 0;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function mapAuditRow(row) {
|
|
169
|
+
return {
|
|
170
|
+
id: row.id,
|
|
171
|
+
tenantId: row.tenantId,
|
|
172
|
+
projectId: row.projectId,
|
|
173
|
+
url: row.url,
|
|
174
|
+
score: row.score,
|
|
175
|
+
checks: parseChecks(row.checks),
|
|
176
|
+
createdAt: row.createdAt
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function mapReportRow(row) {
|
|
180
|
+
return {
|
|
181
|
+
id: row.id,
|
|
182
|
+
tenantId: row.tenantId,
|
|
183
|
+
projectId: row.projectId,
|
|
184
|
+
title: row.title,
|
|
185
|
+
from: row.from,
|
|
186
|
+
to: row.to,
|
|
187
|
+
summary: parseSummary(row.summary),
|
|
188
|
+
createdAt: row.createdAt
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
function parseTags(raw) {
|
|
192
|
+
try {
|
|
193
|
+
const parsed = JSON.parse(raw);
|
|
194
|
+
return Array.isArray(parsed) ? parsed.filter((t) => typeof t === "string") : [];
|
|
195
|
+
} catch {
|
|
196
|
+
return [];
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function migrate(sqlite) {
|
|
200
|
+
sqlite.exec(`
|
|
201
|
+
CREATE TABLE IF NOT EXISTS rms_projects (
|
|
202
|
+
id TEXT PRIMARY KEY,
|
|
203
|
+
tenant_id TEXT NOT NULL,
|
|
204
|
+
name TEXT NOT NULL,
|
|
205
|
+
domain TEXT NOT NULL,
|
|
206
|
+
created_at INTEGER NOT NULL,
|
|
207
|
+
updated_at INTEGER NOT NULL
|
|
208
|
+
);
|
|
209
|
+
CREATE TABLE IF NOT EXISTS rms_keywords (
|
|
210
|
+
id TEXT PRIMARY KEY,
|
|
211
|
+
tenant_id TEXT NOT NULL,
|
|
212
|
+
project_id TEXT NOT NULL,
|
|
213
|
+
text TEXT NOT NULL,
|
|
214
|
+
country TEXT NOT NULL,
|
|
215
|
+
device TEXT NOT NULL,
|
|
216
|
+
tags TEXT NOT NULL,
|
|
217
|
+
created_at INTEGER NOT NULL
|
|
218
|
+
);
|
|
219
|
+
CREATE TABLE IF NOT EXISTS rms_rank_snapshots (
|
|
220
|
+
id TEXT PRIMARY KEY,
|
|
221
|
+
tenant_id TEXT NOT NULL,
|
|
222
|
+
project_id TEXT NOT NULL,
|
|
223
|
+
keyword_id TEXT NOT NULL,
|
|
224
|
+
position INTEGER,
|
|
225
|
+
url TEXT,
|
|
226
|
+
source TEXT NOT NULL,
|
|
227
|
+
device TEXT NOT NULL,
|
|
228
|
+
country TEXT NOT NULL,
|
|
229
|
+
captured_at INTEGER NOT NULL,
|
|
230
|
+
serp_features TEXT
|
|
231
|
+
);
|
|
232
|
+
CREATE TABLE IF NOT EXISTS rms_audits (
|
|
233
|
+
id TEXT PRIMARY KEY,
|
|
234
|
+
tenant_id TEXT NOT NULL,
|
|
235
|
+
project_id TEXT NOT NULL,
|
|
236
|
+
url TEXT NOT NULL,
|
|
237
|
+
score INTEGER NOT NULL,
|
|
238
|
+
checks TEXT NOT NULL DEFAULT '[]',
|
|
239
|
+
created_at INTEGER NOT NULL
|
|
240
|
+
);
|
|
241
|
+
CREATE TABLE IF NOT EXISTS rms_reports (
|
|
242
|
+
id TEXT PRIMARY KEY,
|
|
243
|
+
tenant_id TEXT NOT NULL,
|
|
244
|
+
project_id TEXT NOT NULL,
|
|
245
|
+
title TEXT NOT NULL,
|
|
246
|
+
"from" INTEGER NOT NULL,
|
|
247
|
+
"to" INTEGER NOT NULL,
|
|
248
|
+
summary TEXT,
|
|
249
|
+
created_at INTEGER NOT NULL
|
|
250
|
+
);
|
|
251
|
+
CREATE TABLE IF NOT EXISTS rms_dashboard_configs (
|
|
252
|
+
id TEXT PRIMARY KEY,
|
|
253
|
+
tenant_id TEXT NOT NULL,
|
|
254
|
+
project_id TEXT NOT NULL,
|
|
255
|
+
widgets TEXT NOT NULL,
|
|
256
|
+
updated_at INTEGER NOT NULL
|
|
257
|
+
);
|
|
258
|
+
CREATE TABLE IF NOT EXISTS rms_blog_posts (
|
|
259
|
+
id TEXT PRIMARY KEY,
|
|
260
|
+
tenant_id TEXT NOT NULL,
|
|
261
|
+
project_id TEXT NOT NULL,
|
|
262
|
+
title TEXT NOT NULL,
|
|
263
|
+
slug TEXT NOT NULL,
|
|
264
|
+
content TEXT NOT NULL DEFAULT '',
|
|
265
|
+
target_keyword TEXT NOT NULL DEFAULT '',
|
|
266
|
+
intent TEXT NOT NULL DEFAULT 'informational',
|
|
267
|
+
meta_title TEXT NOT NULL DEFAULT '',
|
|
268
|
+
meta_description TEXT NOT NULL DEFAULT '',
|
|
269
|
+
status TEXT NOT NULL DEFAULT 'draft',
|
|
270
|
+
created_at INTEGER NOT NULL,
|
|
271
|
+
updated_at INTEGER NOT NULL
|
|
272
|
+
);
|
|
273
|
+
`);
|
|
274
|
+
try {
|
|
275
|
+
sqlite.exec(`ALTER TABLE rms_audits ADD COLUMN checks TEXT NOT NULL DEFAULT '[]'`);
|
|
276
|
+
} catch {
|
|
277
|
+
}
|
|
278
|
+
try {
|
|
279
|
+
sqlite.exec(`ALTER TABLE rms_reports ADD COLUMN summary TEXT`);
|
|
280
|
+
} catch {
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
function createSqliteStore(databasePath) {
|
|
284
|
+
const sqlite = new import_better_sqlite3.default(databasePath);
|
|
285
|
+
migrate(sqlite);
|
|
286
|
+
const db = (0, import_better_sqlite32.drizzle)(sqlite, { schema: sqliteSchema });
|
|
287
|
+
const keywordScopeWhere = (scope) => (0, import_drizzle_orm.and)(
|
|
288
|
+
(0, import_drizzle_orm.eq)(keywords.tenantId, scope.tenantId),
|
|
289
|
+
(0, import_drizzle_orm.eq)(keywords.projectId, scope.projectId)
|
|
290
|
+
);
|
|
291
|
+
return {
|
|
292
|
+
projects: {
|
|
293
|
+
async create(input) {
|
|
294
|
+
const now = /* @__PURE__ */ new Date();
|
|
295
|
+
const row = {
|
|
296
|
+
...input,
|
|
297
|
+
createdAt: now,
|
|
298
|
+
updatedAt: now
|
|
299
|
+
};
|
|
300
|
+
db.insert(projects).values({
|
|
301
|
+
id: row.id,
|
|
302
|
+
tenantId: row.tenantId,
|
|
303
|
+
name: row.name,
|
|
304
|
+
domain: row.domain,
|
|
305
|
+
createdAt: row.createdAt,
|
|
306
|
+
updatedAt: row.updatedAt
|
|
307
|
+
}).run();
|
|
308
|
+
return row;
|
|
309
|
+
},
|
|
310
|
+
async getById(scope, id) {
|
|
311
|
+
const rows = db.select().from(projects).where((0, import_drizzle_orm.and)((0, import_drizzle_orm.eq)(projects.tenantId, scope.tenantId), (0, import_drizzle_orm.eq)(projects.id, id))).all();
|
|
312
|
+
const row = rows[0];
|
|
313
|
+
if (!row) return void 0;
|
|
314
|
+
return {
|
|
315
|
+
id: row.id,
|
|
316
|
+
tenantId: row.tenantId,
|
|
317
|
+
name: row.name,
|
|
318
|
+
domain: row.domain,
|
|
319
|
+
createdAt: row.createdAt,
|
|
320
|
+
updatedAt: row.updatedAt
|
|
321
|
+
};
|
|
322
|
+
},
|
|
323
|
+
async list(scope) {
|
|
324
|
+
return db.select().from(projects).where((0, import_drizzle_orm.eq)(projects.tenantId, scope.tenantId)).all().map((row) => ({
|
|
325
|
+
id: row.id,
|
|
326
|
+
tenantId: row.tenantId,
|
|
327
|
+
name: row.name,
|
|
328
|
+
domain: row.domain,
|
|
329
|
+
createdAt: row.createdAt,
|
|
330
|
+
updatedAt: row.updatedAt
|
|
331
|
+
}));
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
keywords: {
|
|
335
|
+
async create(input) {
|
|
336
|
+
const row = {
|
|
337
|
+
id: (0, import_node_crypto.randomUUID)(),
|
|
338
|
+
...input,
|
|
339
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
340
|
+
};
|
|
341
|
+
db.insert(keywords).values({
|
|
342
|
+
id: row.id,
|
|
343
|
+
tenantId: row.tenantId,
|
|
344
|
+
projectId: row.projectId,
|
|
345
|
+
text: row.text,
|
|
346
|
+
country: row.country,
|
|
347
|
+
device: row.device,
|
|
348
|
+
tags: JSON.stringify(row.tags),
|
|
349
|
+
createdAt: row.createdAt
|
|
350
|
+
}).run();
|
|
351
|
+
return row;
|
|
352
|
+
},
|
|
353
|
+
async getById(scope, id) {
|
|
354
|
+
const rows = db.select().from(keywords).where((0, import_drizzle_orm.and)(keywordScopeWhere(scope), (0, import_drizzle_orm.eq)(keywords.id, id))).all();
|
|
355
|
+
const row = rows[0];
|
|
356
|
+
if (!row) return void 0;
|
|
357
|
+
return {
|
|
358
|
+
id: row.id,
|
|
359
|
+
tenantId: row.tenantId,
|
|
360
|
+
projectId: row.projectId,
|
|
361
|
+
text: row.text,
|
|
362
|
+
country: row.country,
|
|
363
|
+
device: row.device,
|
|
364
|
+
tags: parseTags(row.tags),
|
|
365
|
+
createdAt: row.createdAt
|
|
366
|
+
};
|
|
367
|
+
},
|
|
368
|
+
async list(scope) {
|
|
369
|
+
return db.select().from(keywords).where(keywordScopeWhere(scope)).all().map((row) => ({
|
|
370
|
+
id: row.id,
|
|
371
|
+
tenantId: row.tenantId,
|
|
372
|
+
projectId: row.projectId,
|
|
373
|
+
text: row.text,
|
|
374
|
+
country: row.country,
|
|
375
|
+
device: row.device,
|
|
376
|
+
tags: parseTags(row.tags),
|
|
377
|
+
createdAt: row.createdAt
|
|
378
|
+
}));
|
|
379
|
+
},
|
|
380
|
+
async delete(scope, id) {
|
|
381
|
+
const result = db.delete(keywords).where((0, import_drizzle_orm.and)(keywordScopeWhere(scope), (0, import_drizzle_orm.eq)(keywords.id, id))).run();
|
|
382
|
+
return result.changes > 0;
|
|
383
|
+
}
|
|
384
|
+
},
|
|
385
|
+
snapshots: {
|
|
386
|
+
async append(input) {
|
|
387
|
+
const row = {
|
|
388
|
+
id: (0, import_node_crypto.randomUUID)(),
|
|
389
|
+
...input
|
|
390
|
+
};
|
|
391
|
+
db.insert(rankSnapshots).values({
|
|
392
|
+
id: row.id,
|
|
393
|
+
tenantId: row.tenantId,
|
|
394
|
+
projectId: row.projectId,
|
|
395
|
+
keywordId: row.keywordId,
|
|
396
|
+
position: row.position,
|
|
397
|
+
url: row.url,
|
|
398
|
+
source: row.source,
|
|
399
|
+
device: row.device,
|
|
400
|
+
country: row.country,
|
|
401
|
+
capturedAt: row.capturedAt,
|
|
402
|
+
serpFeatures: row.serpFeatures ? JSON.stringify(row.serpFeatures) : null
|
|
403
|
+
}).run();
|
|
404
|
+
return row;
|
|
405
|
+
},
|
|
406
|
+
async listByRange(query) {
|
|
407
|
+
const conditions = [
|
|
408
|
+
(0, import_drizzle_orm.eq)(rankSnapshots.tenantId, query.tenantId),
|
|
409
|
+
(0, import_drizzle_orm.eq)(rankSnapshots.projectId, query.projectId),
|
|
410
|
+
(0, import_drizzle_orm.gte)(rankSnapshots.capturedAt, query.from),
|
|
411
|
+
(0, import_drizzle_orm.lte)(rankSnapshots.capturedAt, query.to)
|
|
412
|
+
];
|
|
413
|
+
if (query.keywordId) {
|
|
414
|
+
conditions.push((0, import_drizzle_orm.eq)(rankSnapshots.keywordId, query.keywordId));
|
|
415
|
+
}
|
|
416
|
+
return db.select().from(rankSnapshots).where((0, import_drizzle_orm.and)(...conditions)).all().map((row) => ({
|
|
417
|
+
id: row.id,
|
|
418
|
+
tenantId: row.tenantId,
|
|
419
|
+
projectId: row.projectId,
|
|
420
|
+
keywordId: row.keywordId,
|
|
421
|
+
position: row.position,
|
|
422
|
+
url: row.url,
|
|
423
|
+
source: row.source,
|
|
424
|
+
device: row.device,
|
|
425
|
+
country: row.country,
|
|
426
|
+
capturedAt: row.capturedAt,
|
|
427
|
+
serpFeatures: row.serpFeatures ? JSON.parse(row.serpFeatures) : void 0
|
|
428
|
+
}));
|
|
429
|
+
}
|
|
430
|
+
},
|
|
431
|
+
audits: {
|
|
432
|
+
async create(input) {
|
|
433
|
+
const row = { ...input, checks: input.checks ?? [], createdAt: /* @__PURE__ */ new Date() };
|
|
434
|
+
db.insert(audits).values({
|
|
435
|
+
id: row.id,
|
|
436
|
+
tenantId: row.tenantId,
|
|
437
|
+
projectId: row.projectId,
|
|
438
|
+
url: row.url,
|
|
439
|
+
score: row.score,
|
|
440
|
+
checks: JSON.stringify(row.checks),
|
|
441
|
+
createdAt: row.createdAt
|
|
442
|
+
}).run();
|
|
443
|
+
return row;
|
|
444
|
+
},
|
|
445
|
+
async getById(scope, id) {
|
|
446
|
+
const rows = db.select().from(audits).where(
|
|
447
|
+
(0, import_drizzle_orm.and)(
|
|
448
|
+
(0, import_drizzle_orm.eq)(audits.tenantId, scope.tenantId),
|
|
449
|
+
(0, import_drizzle_orm.eq)(audits.projectId, scope.projectId),
|
|
450
|
+
(0, import_drizzle_orm.eq)(audits.id, id)
|
|
451
|
+
)
|
|
452
|
+
).all();
|
|
453
|
+
const row = rows[0];
|
|
454
|
+
if (!row) return void 0;
|
|
455
|
+
return mapAuditRow(row);
|
|
456
|
+
},
|
|
457
|
+
async list(scope) {
|
|
458
|
+
return db.select().from(audits).where(
|
|
459
|
+
(0, import_drizzle_orm.and)(
|
|
460
|
+
(0, import_drizzle_orm.eq)(audits.tenantId, scope.tenantId),
|
|
461
|
+
(0, import_drizzle_orm.eq)(audits.projectId, scope.projectId)
|
|
462
|
+
)
|
|
463
|
+
).all().map(mapAuditRow);
|
|
464
|
+
}
|
|
465
|
+
},
|
|
466
|
+
reports: {
|
|
467
|
+
async create(input) {
|
|
468
|
+
const row = { ...input, createdAt: /* @__PURE__ */ new Date() };
|
|
469
|
+
db.insert(reports).values({
|
|
470
|
+
id: row.id,
|
|
471
|
+
tenantId: row.tenantId,
|
|
472
|
+
projectId: row.projectId,
|
|
473
|
+
title: row.title,
|
|
474
|
+
from: row.from,
|
|
475
|
+
to: row.to,
|
|
476
|
+
summary: row.summary ? JSON.stringify(row.summary) : null,
|
|
477
|
+
createdAt: row.createdAt
|
|
478
|
+
}).run();
|
|
479
|
+
return row;
|
|
480
|
+
},
|
|
481
|
+
async getById(scope, id) {
|
|
482
|
+
const rows = db.select().from(reports).where(
|
|
483
|
+
(0, import_drizzle_orm.and)(
|
|
484
|
+
(0, import_drizzle_orm.eq)(reports.tenantId, scope.tenantId),
|
|
485
|
+
(0, import_drizzle_orm.eq)(reports.projectId, scope.projectId),
|
|
486
|
+
(0, import_drizzle_orm.eq)(reports.id, id)
|
|
487
|
+
)
|
|
488
|
+
).all();
|
|
489
|
+
const row = rows[0];
|
|
490
|
+
if (!row) return void 0;
|
|
491
|
+
return mapReportRow(row);
|
|
492
|
+
},
|
|
493
|
+
async list(scope) {
|
|
494
|
+
return db.select().from(reports).where(
|
|
495
|
+
(0, import_drizzle_orm.and)(
|
|
496
|
+
(0, import_drizzle_orm.eq)(reports.tenantId, scope.tenantId),
|
|
497
|
+
(0, import_drizzle_orm.eq)(reports.projectId, scope.projectId)
|
|
498
|
+
)
|
|
499
|
+
).all().map(mapReportRow);
|
|
500
|
+
}
|
|
501
|
+
},
|
|
502
|
+
dashboard: {
|
|
503
|
+
async get(scope) {
|
|
504
|
+
const rows = db.select().from(dashboardConfigs).where(
|
|
505
|
+
(0, import_drizzle_orm.and)(
|
|
506
|
+
(0, import_drizzle_orm.eq)(dashboardConfigs.tenantId, scope.tenantId),
|
|
507
|
+
(0, import_drizzle_orm.eq)(dashboardConfigs.projectId, scope.projectId)
|
|
508
|
+
)
|
|
509
|
+
).all();
|
|
510
|
+
const row = rows[0];
|
|
511
|
+
if (!row) return void 0;
|
|
512
|
+
return {
|
|
513
|
+
id: row.id,
|
|
514
|
+
tenantId: row.tenantId,
|
|
515
|
+
projectId: row.projectId,
|
|
516
|
+
widgets: JSON.parse(row.widgets),
|
|
517
|
+
updatedAt: row.updatedAt
|
|
518
|
+
};
|
|
519
|
+
},
|
|
520
|
+
async upsert(config) {
|
|
521
|
+
db.insert(dashboardConfigs).values({
|
|
522
|
+
id: config.id,
|
|
523
|
+
tenantId: config.tenantId,
|
|
524
|
+
projectId: config.projectId,
|
|
525
|
+
widgets: JSON.stringify(config.widgets),
|
|
526
|
+
updatedAt: config.updatedAt
|
|
527
|
+
}).onConflictDoUpdate({
|
|
528
|
+
target: dashboardConfigs.id,
|
|
529
|
+
set: {
|
|
530
|
+
widgets: JSON.stringify(config.widgets),
|
|
531
|
+
updatedAt: config.updatedAt
|
|
532
|
+
}
|
|
533
|
+
}).run();
|
|
534
|
+
return config;
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
blog: {
|
|
538
|
+
async create(input) {
|
|
539
|
+
const now = /* @__PURE__ */ new Date();
|
|
540
|
+
const row = { ...input, createdAt: now, updatedAt: now };
|
|
541
|
+
db.insert(blogPosts).values({
|
|
542
|
+
id: row.id,
|
|
543
|
+
tenantId: row.tenantId,
|
|
544
|
+
projectId: row.projectId,
|
|
545
|
+
title: row.title,
|
|
546
|
+
slug: row.slug,
|
|
547
|
+
content: row.content,
|
|
548
|
+
targetKeyword: row.targetKeyword,
|
|
549
|
+
intent: row.intent,
|
|
550
|
+
metaTitle: row.metaTitle,
|
|
551
|
+
metaDescription: row.metaDescription,
|
|
552
|
+
status: row.status,
|
|
553
|
+
createdAt: row.createdAt,
|
|
554
|
+
updatedAt: row.updatedAt
|
|
555
|
+
}).run();
|
|
556
|
+
return row;
|
|
557
|
+
},
|
|
558
|
+
async getById(scope, id) {
|
|
559
|
+
const rows = db.select().from(blogPosts).where(
|
|
560
|
+
(0, import_drizzle_orm.and)(
|
|
561
|
+
(0, import_drizzle_orm.eq)(blogPosts.tenantId, scope.tenantId),
|
|
562
|
+
(0, import_drizzle_orm.eq)(blogPosts.projectId, scope.projectId),
|
|
563
|
+
(0, import_drizzle_orm.eq)(blogPosts.id, id)
|
|
564
|
+
)
|
|
565
|
+
).all();
|
|
566
|
+
const row = rows[0];
|
|
567
|
+
return row ? mapBlogRow(row) : void 0;
|
|
568
|
+
},
|
|
569
|
+
async list(scope) {
|
|
570
|
+
return db.select().from(blogPosts).where(
|
|
571
|
+
(0, import_drizzle_orm.and)(
|
|
572
|
+
(0, import_drizzle_orm.eq)(blogPosts.tenantId, scope.tenantId),
|
|
573
|
+
(0, import_drizzle_orm.eq)(blogPosts.projectId, scope.projectId)
|
|
574
|
+
)
|
|
575
|
+
).all().map(mapBlogRow);
|
|
576
|
+
},
|
|
577
|
+
async update(scope, id, patch) {
|
|
578
|
+
const rows = db.select().from(blogPosts).where(
|
|
579
|
+
(0, import_drizzle_orm.and)(
|
|
580
|
+
(0, import_drizzle_orm.eq)(blogPosts.tenantId, scope.tenantId),
|
|
581
|
+
(0, import_drizzle_orm.eq)(blogPosts.projectId, scope.projectId),
|
|
582
|
+
(0, import_drizzle_orm.eq)(blogPosts.id, id)
|
|
583
|
+
)
|
|
584
|
+
).all();
|
|
585
|
+
const existing = rows[0];
|
|
586
|
+
if (!existing) return void 0;
|
|
587
|
+
const merged = mapBlogRow(existing);
|
|
588
|
+
const next = {
|
|
589
|
+
...merged,
|
|
590
|
+
...patch,
|
|
591
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
592
|
+
};
|
|
593
|
+
db.update(blogPosts).set({
|
|
594
|
+
title: next.title,
|
|
595
|
+
slug: next.slug,
|
|
596
|
+
content: next.content,
|
|
597
|
+
targetKeyword: next.targetKeyword,
|
|
598
|
+
intent: next.intent,
|
|
599
|
+
metaTitle: next.metaTitle,
|
|
600
|
+
metaDescription: next.metaDescription,
|
|
601
|
+
status: next.status,
|
|
602
|
+
updatedAt: next.updatedAt
|
|
603
|
+
}).where(
|
|
604
|
+
(0, import_drizzle_orm.and)(
|
|
605
|
+
(0, import_drizzle_orm.eq)(blogPosts.tenantId, scope.tenantId),
|
|
606
|
+
(0, import_drizzle_orm.eq)(blogPosts.projectId, scope.projectId),
|
|
607
|
+
(0, import_drizzle_orm.eq)(blogPosts.id, id)
|
|
608
|
+
)
|
|
609
|
+
).run();
|
|
610
|
+
return next;
|
|
611
|
+
},
|
|
612
|
+
async delete(scope, id) {
|
|
613
|
+
const result = db.delete(blogPosts).where(
|
|
614
|
+
(0, import_drizzle_orm.and)(
|
|
615
|
+
(0, import_drizzle_orm.eq)(blogPosts.tenantId, scope.tenantId),
|
|
616
|
+
(0, import_drizzle_orm.eq)(blogPosts.projectId, scope.projectId),
|
|
617
|
+
(0, import_drizzle_orm.eq)(blogPosts.id, id)
|
|
618
|
+
)
|
|
619
|
+
).run();
|
|
620
|
+
return result.changes > 0;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
// src/factory.ts
|
|
627
|
+
function createStore(databaseUrl) {
|
|
628
|
+
if (databaseUrl.startsWith("postgres") || databaseUrl.startsWith("mysql")) {
|
|
629
|
+
throw new Error(
|
|
630
|
+
"Postgres and MySQL adapters are not implemented in M0. Use sqlite:// or :memory:"
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
const path = databaseUrl.startsWith("sqlite://") ? databaseUrl.slice("sqlite://".length) : databaseUrl;
|
|
634
|
+
return createSqliteStore(path);
|
|
635
|
+
}
|
|
636
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
637
|
+
0 && (module.exports = {
|
|
638
|
+
createSqliteStore,
|
|
639
|
+
createStore
|
|
640
|
+
});
|
|
641
|
+
//# sourceMappingURL=index.cjs.map
|