mktcms 0.3.9 → 0.3.10

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/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mktcms",
3
3
  "configKey": "mktcms",
4
- "version": "0.3.9",
4
+ "version": "0.3.10",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -83,6 +83,11 @@ const module$1 = defineNuxtModule({
83
83
  name: "useForm",
84
84
  as: "useForm",
85
85
  from: resolver.resolve("runtime/app/composables/useForm")
86
+ },
87
+ {
88
+ name: "useTrackTraffic",
89
+ as: "useTrackTraffic",
90
+ from: resolver.resolve("runtime/app/composables/useTrackTraffic")
86
91
  }
87
92
  ]);
88
93
  addServerImports({
@@ -197,6 +202,11 @@ const module$1 = defineNuxtModule({
197
202
  route: "/api/health",
198
203
  handler: resolver.resolve("./runtime/server/api/health")
199
204
  });
205
+ addServerHandler({
206
+ route: "/api/traffic/track",
207
+ method: "post",
208
+ handler: resolver.resolve("./runtime/server/api/traffic/track.post")
209
+ });
200
210
  extendPages((pages) => {
201
211
  pages.push({
202
212
  name: "Admin Dashboard",
@@ -0,0 +1 @@
1
+ export declare function useTrackTraffic(): void;
@@ -0,0 +1,12 @@
1
+ import { onMounted } from "vue";
2
+ export function useTrackTraffic() {
3
+ if (import.meta.server) {
4
+ return;
5
+ }
6
+ onMounted(() => {
7
+ void $fetch("/api/traffic/track", {
8
+ method: "POST"
9
+ }).catch(() => {
10
+ });
11
+ });
12
+ }
@@ -1,8 +1,10 @@
1
1
  import { createError, defineEventHandler, setHeader } from "h3";
2
2
  import { getStorageUsageBytes } from "../utils/storageUsage.js";
3
+ import { getTrafficMetrics } from "../utils/trafficMetrics.js";
3
4
  export default defineEventHandler(async (event) => {
4
5
  try {
5
6
  const storageUsageBytes = await getStorageUsageBytes();
7
+ const { requestsTotal, uniqueIpsTotal } = getTrafficMetrics();
6
8
  setHeader(event, "Content-Type", "text/plain; version=0.0.4; charset=utf-8");
7
9
  return [
8
10
  "# HELP mktcms_up Whether the mktcms API is healthy (1 = healthy).",
@@ -10,7 +12,13 @@ export default defineEventHandler(async (event) => {
10
12
  "mktcms_up 1",
11
13
  "# HELP mktcms_storage_usage_bytes Current .storage directory size in bytes.",
12
14
  "# TYPE mktcms_storage_usage_bytes gauge",
13
- `mktcms_storage_usage_bytes ${storageUsageBytes}`
15
+ `mktcms_storage_usage_bytes ${storageUsageBytes}`,
16
+ "# HELP mktcms_requests_total Total number of counted page requests.",
17
+ "# TYPE mktcms_requests_total counter",
18
+ `mktcms_requests_total ${requestsTotal}`,
19
+ "# HELP mktcms_unique_ips_total Total number of unique visitor IPs seen in memory.",
20
+ "# TYPE mktcms_unique_ips_total counter",
21
+ `mktcms_unique_ips_total ${uniqueIpsTotal}`
14
22
  ].join("\n") + "\n";
15
23
  } catch (error) {
16
24
  throw createError({
@@ -0,0 +1,4 @@
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, {
2
+ tracked: boolean;
3
+ }>;
4
+ export default _default;
@@ -0,0 +1,22 @@
1
+ import { defineEventHandler, getRequestIP } from "h3";
2
+ import { incrementTrafficRequests, trackUniqueIp } from "../../utils/trafficMetrics.js";
3
+ function normalizeIp(ip) {
4
+ if (!ip) {
5
+ return void 0;
6
+ }
7
+ const normalizedIp = ip.trim();
8
+ if (normalizedIp.startsWith("::ffff:")) {
9
+ return normalizedIp.slice(7);
10
+ }
11
+ return normalizedIp;
12
+ }
13
+ export default defineEventHandler((event) => {
14
+ const userAgent = event.node.req.headers["user-agent"];
15
+ if (typeof userAgent === "string" && userAgent.includes("Blackbox")) {
16
+ return { tracked: false };
17
+ }
18
+ incrementTrafficRequests();
19
+ const requestIp = normalizeIp(getRequestIP(event, { xForwardedFor: true }) || event.node.req.socket.remoteAddress);
20
+ trackUniqueIp(requestIp);
21
+ return { tracked: true };
22
+ });
@@ -0,0 +1,6 @@
1
+ export declare function incrementTrafficRequests(): void;
2
+ export declare function trackUniqueIp(ip?: string): void;
3
+ export declare function getTrafficMetrics(): {
4
+ requestsTotal: number;
5
+ uniqueIpsTotal: number;
6
+ };
@@ -0,0 +1,23 @@
1
+ const MAX_STORED_IPS = 1e4;
2
+ let requestsTotal = 0;
3
+ let uniqueIpsTotal = 0;
4
+ const seenIps = /* @__PURE__ */ new Set();
5
+ export function incrementTrafficRequests() {
6
+ requestsTotal += 1;
7
+ }
8
+ export function trackUniqueIp(ip) {
9
+ if (!ip || seenIps.has(ip)) {
10
+ return;
11
+ }
12
+ if (seenIps.size >= MAX_STORED_IPS) {
13
+ return;
14
+ }
15
+ seenIps.add(ip);
16
+ uniqueIpsTotal += 1;
17
+ }
18
+ export function getTrafficMetrics() {
19
+ return {
20
+ requestsTotal,
21
+ uniqueIpsTotal
22
+ };
23
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mktcms",
3
- "version": "0.3.9",
3
+ "version": "0.3.10",
4
4
  "description": "Simple CMS module for Nuxt",
5
5
  "repository": "mktcode/mktcms",
6
6
  "license": "MIT",