@soloworks/smking-next 0.17.0 → 0.19.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/CHANGELOG.md +29 -0
- package/package.json +1 -1
- package/src/lib/client.ts +5 -7
- package/src/lib/cms-client.ts +30 -2
- package/src/lib/version.ts +1 -0
- package/src/types.ts +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @soloworks/smking-next
|
|
2
2
|
|
|
3
|
+
## 0.19.0 — 2026-05-29
|
|
4
|
+
|
|
5
|
+
**CMS base path reported via heartbeat — dashboard "View page" resolves real URLs without per-page visits.**
|
|
6
|
+
|
|
7
|
+
`getAeoContent()`'s heartbeat (`sdk_meta`) now sends `cms_base_path` from
|
|
8
|
+
`SMKING_CMS_PATH` (default `/blog`). smking stores it site-level and builds
|
|
9
|
+
"View page" links as `domain + base path + slug` — a page resolves the
|
|
10
|
+
moment any page on the site is crawled, instead of waiting for that specific
|
|
11
|
+
page to be visited (supersedes 0.18.0's per-slug URL reporting). Set
|
|
12
|
+
`SMKING_CMS_PATH` if your CMS catch-all is mounted somewhere other than
|
|
13
|
+
`/blog`.
|
|
14
|
+
|
|
15
|
+
## 0.18.0 — 2026-05-28
|
|
16
|
+
|
|
17
|
+
**CMS live-URL reporting — `<SmkingCms>` now tells the dashboard each page's real public URL.**
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- `getCmsPage()` appends `sdk` / `sdk_version` / `url` / `path` / `app_env` query params to its `GET /api/v1/public/page` (mirroring the AEO heartbeat). saas stores the real per-slug `pageUrl` — so the dashboard "View page ↗" link points at the actual customer URL instead of a guessed domain — and upserts `sdk_health_snapshots` with the CMS-side heartbeat.
|
|
22
|
+
- `getCmsPage({ url, path })` accept optional overrides; `<SmkingCms>` resolves them from `next/headers` when omitted (same pattern as `<SmkingAEO>`).
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- `SDK_VERSION` moved into `version.ts`, now the single source shared by `client.ts` (AEO) and `cms-client.ts` (CMS) so the reported heartbeat version can't drift between the two call sites.
|
|
27
|
+
|
|
28
|
+
### Why
|
|
29
|
+
|
|
30
|
+
CMS reads are high-frequency and ISR-cached, so the request stays a `GET` — switching to POST to carry a body would break the data cache. Piggybacking query params keeps the cache while letting saas learn each page's real URL + liveness.
|
|
31
|
+
|
|
3
32
|
## 0.17.0 — 2026-05-26
|
|
4
33
|
|
|
5
34
|
**SDK self-report (heartbeat) — dashboard SDK Health chip stops getting WAF false-negatives.**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soloworks/smking-next",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "AI-native SEO (AEO) for Next.js — auto-inject JSON-LD, FAQ, AI summary, and SEO metadata so AI crawlers (ChatGPT, Perplexity, Google AI) can cite your pages.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/sillyleo/smking/tree/main/packages/smking-next",
|
package/src/lib/client.ts
CHANGED
|
@@ -4,17 +4,11 @@ import type {} from "next";
|
|
|
4
4
|
|
|
5
5
|
import type { AeoResponse, DiscoverParams } from "../types";
|
|
6
6
|
import { normalizePath, resolveRequestPath } from "./path";
|
|
7
|
+
import { SDK_VERSION } from "./version";
|
|
7
8
|
|
|
8
9
|
const DEFAULT_REVALIDATE_SECONDS = 3600;
|
|
9
10
|
const FETCH_TIMEOUT_MS = 2000;
|
|
10
11
|
|
|
11
|
-
/**
|
|
12
|
-
* SDK version self-reported in heartbeat `sdk_meta.sdk_version`. Must stay
|
|
13
|
-
* in sync with package.json `version` — `publish-smking-package` skill
|
|
14
|
-
* bumps both together.
|
|
15
|
-
*/
|
|
16
|
-
const SDK_VERSION = "0.17.0";
|
|
17
|
-
|
|
18
12
|
/**
|
|
19
13
|
* Extract hostname from a full URL string. Returns null on parse failure
|
|
20
14
|
* (malformed URL would otherwise throw). Used to populate heartbeat
|
|
@@ -116,7 +110,11 @@ export async function getAeoContent(
|
|
|
116
110
|
sdk_version: SDK_VERSION,
|
|
117
111
|
app_env: process.env.NODE_ENV ?? null,
|
|
118
112
|
host: safeHostname(url),
|
|
113
|
+
// Site-level CMS base path → smking dashboard "View page" URLs.
|
|
114
|
+
// Default "/blog"; override with SMKING_CMS_PATH (wizard sets it).
|
|
115
|
+
cms_base_path: process.env.SMKING_CMS_PATH ?? "/blog",
|
|
119
116
|
},
|
|
117
|
+
|
|
120
118
|
}),
|
|
121
119
|
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
|
|
122
120
|
next: {
|
package/src/lib/cms-client.ts
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
import type {} from "next";
|
|
4
4
|
|
|
5
5
|
import type { CmsParams, CmsResponse } from "../types";
|
|
6
|
+
import { resolveRequestPath } from "./path";
|
|
7
|
+
import { SDK_VERSION } from "./version";
|
|
6
8
|
|
|
7
9
|
// CMS-specific TTL — shorter than AEO's 1h because CMS body is
|
|
8
10
|
// hand-edited (frequent updates) vs AEO which is SaaS-generated
|
|
@@ -72,11 +74,37 @@ export async function getCmsPage(
|
|
|
72
74
|
return null;
|
|
73
75
|
}
|
|
74
76
|
|
|
77
|
+
let requestPath = params.path;
|
|
78
|
+
let requestUrl = params.url;
|
|
79
|
+
if (!requestPath || !requestUrl) {
|
|
80
|
+
try {
|
|
81
|
+
const resolved = await resolveRequestPath();
|
|
82
|
+
if (!requestPath) requestPath = resolved.path;
|
|
83
|
+
if (!requestUrl) requestUrl = resolved.url;
|
|
84
|
+
} catch {
|
|
85
|
+
// Fallback silently if outside request scope
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
75
89
|
try {
|
|
76
|
-
|
|
90
|
+
let apiUrl = `${baseUrl}/api/v1/public/page?key=${encodeURIComponent(
|
|
77
91
|
params.apiKey,
|
|
78
92
|
)}&slug=${encodeURIComponent(params.slug)}`;
|
|
79
|
-
|
|
93
|
+
|
|
94
|
+
if (requestPath) {
|
|
95
|
+
apiUrl += `&path=${encodeURIComponent(requestPath)}`;
|
|
96
|
+
}
|
|
97
|
+
if (requestUrl) {
|
|
98
|
+
apiUrl += `&url=${encodeURIComponent(requestUrl)}`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
apiUrl += `&sdk=next&sdk_version=${encodeURIComponent(SDK_VERSION)}`;
|
|
102
|
+
const appEnv = params.appEnv ?? process.env.NODE_ENV;
|
|
103
|
+
if (appEnv) {
|
|
104
|
+
apiUrl += `&app_env=${encodeURIComponent(appEnv)}`;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const res = await fetch(apiUrl, {
|
|
80
108
|
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
|
|
81
109
|
next: {
|
|
82
110
|
revalidate: params.revalidate ?? DEFAULT_REVALIDATE_SECONDS,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const SDK_VERSION = "0.18.0";
|
package/src/types.ts
CHANGED
|
@@ -225,6 +225,12 @@ export interface CmsParams {
|
|
|
225
225
|
* and changes more often; matches `smking/laravel`'s `cms_ttl`).
|
|
226
226
|
*/
|
|
227
227
|
revalidate?: number;
|
|
228
|
+
/** Optional current request URL for live preview link on the SaaS dashboard. */
|
|
229
|
+
url?: string;
|
|
230
|
+
/** Optional request path. */
|
|
231
|
+
path?: string;
|
|
232
|
+
/** Optional app environment (e.g. 'development', 'production'). */
|
|
233
|
+
appEnv?: string;
|
|
228
234
|
}
|
|
229
235
|
|
|
230
236
|
export interface DiscoverParams {
|