@asteroidcms/core-utils 0.1.1 → 0.1.3

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/index.cjs CHANGED
@@ -1,29 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var react = require('react');
4
- var react$1 = require('@apollo/client/react');
5
3
  var client = require('@apollo/client');
6
4
  var context = require('@apollo/client/link/context');
7
5
  var error = require('@apollo/client/link/error');
8
- var jsxRuntime = require('react/jsx-runtime');
9
- var hljs = require('highlight.js/lib/common');
10
- require('highlight.js/styles/tokyo-night-dark.css');
11
6
 
12
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
-
14
- var hljs__default = /*#__PURE__*/_interopDefault(hljs);
15
-
16
- // src/provider/AsteroidCMSProvider.tsx
17
- var AsteroidCMSContext = react.createContext(null);
18
- function useAsteroidCMSConfig() {
19
- const ctx = react.useContext(AsteroidCMSContext);
20
- if (!ctx) {
21
- throw new Error(
22
- "useAsteroidCMSConfig must be used inside <AsteroidCMSProvider>. Wrap your app with <AsteroidCMSProvider cmsUrl=... apiKey=... />."
23
- );
24
- }
25
- return ctx;
26
- }
7
+ // src/apollo/createApolloClient.ts
27
8
  function createErrorLink(onError) {
28
9
  return new error.ErrorLink(({ error }) => {
29
10
  if (!onError) return;
@@ -83,30 +64,32 @@ function createApolloClient(config) {
83
64
  ...config.apolloOptions
84
65
  });
85
66
  }
86
- function AsteroidCMSProvider({ children, ...config }) {
87
- const resolved = react.useMemo(() => resolveConfig(config), [
88
- config.cmsUrl,
89
- config.apiKey,
90
- config.graphqlPath,
91
- config.mediaPath,
92
- config.headers,
93
- config.onError
94
- ]);
95
- const client = react.useMemo(
96
- () => createApolloClient(config),
97
- // The client is intentionally rebuilt only when the identity-shaping props change.
98
- [
99
- config.client,
100
- resolved.cmsUrl,
101
- resolved.apiKey,
102
- resolved.graphqlPath,
103
- config.cacheConfig,
104
- config.apolloOptions
105
- ]
106
- );
107
- return /* @__PURE__ */ jsxRuntime.jsx(AsteroidCMSContext.Provider, { value: resolved, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.ApolloProvider, { client, children }) });
67
+ function buildSelection(items = []) {
68
+ const lines = [];
69
+ items.forEach((item) => {
70
+ if (typeof item === "string") {
71
+ lines.push(`${item}: dataField(slug: "${item}")`);
72
+ return;
73
+ }
74
+ if ("field" in item && typeof item.field === "string") {
75
+ if (!("select" in item)) {
76
+ const alias2 = item.as || item.field;
77
+ lines.push(`${alias2}: dataField(slug: "${item.field}")`);
78
+ return;
79
+ }
80
+ const alias = item.as || item.field;
81
+ const resolver = item.single ? "expandedReferenceObject" : "expandedReference";
82
+ const subSelection = item.select?.length ? buildSelection(item.select) : "data { ... }";
83
+ lines.push(`
84
+ ${alias}: ${resolver}(slug: "${item.field}") {
85
+ ${subSelection}
86
+ }
87
+ `);
88
+ }
89
+ });
90
+ return lines.join("\n ").trim();
108
91
  }
109
- function useCmsContent({
92
+ function buildCmsQuery({
110
93
  schema_slug,
111
94
  entrySlug,
112
95
  select = [],
@@ -118,35 +101,16 @@ function useCmsContent({
118
101
  search,
119
102
  variables = {}
120
103
  }) {
121
- const isSingle = !!entrySlug;
122
- const buildSelection = (items = []) => {
123
- const lines = [];
124
- items.forEach((item) => {
125
- if (typeof item === "string") {
126
- lines.push(`${item}: dataField(slug: "${item}")`);
127
- } else if ("field" in item && typeof item.field === "string") {
128
- if (!("select" in item)) {
129
- const alias2 = item.as || item.field;
130
- lines.push(`${alias2}: dataField(slug: "${item.field}")`);
131
- return;
132
- }
133
- const alias = item.as || item.field;
134
- const resolver = item.single ? "expandedReferenceObject" : "expandedReference";
135
- const subSelection = item.select?.length ? buildSelection(item.select) : "data { ... }";
136
- lines.push(`
137
- ${alias}: ${resolver}(slug: "${item.field}") {
138
- ${subSelection}
139
- }
140
- `);
141
- }
142
- });
143
- return lines.join("\n ").trim();
144
- };
104
+ const isSingle = Boolean(entrySlug);
145
105
  const selectionParts = [];
146
- if (fullData) selectionParts.push("data");
106
+ if (fullData) {
107
+ selectionParts.push("data");
108
+ }
147
109
  if (select.length > 0) {
148
110
  const userSelection = buildSelection(select);
149
- if (userSelection) selectionParts.push(userSelection);
111
+ if (userSelection) {
112
+ selectionParts.push(userSelection);
113
+ }
150
114
  }
151
115
  const selection = selectionParts.join("\n ").trim() || "id";
152
116
  const queryVariables = {
@@ -165,8 +129,11 @@ function useCmsContent({
165
129
  queryVariables.offset = offset;
166
130
  }
167
131
  if (status) {
168
- fieldArgParts.push("status: $status");
169
- queryVariables.status = status;
132
+ const statuses = status;
133
+ if (statuses.length > 0) {
134
+ fieldArgParts.push("status: $status");
135
+ queryVariables.status = statuses;
136
+ }
170
137
  }
171
138
  const hasSearch = Array.isArray(search) && search.length > 0;
172
139
  const hasFilter = filter && typeof filter === "object" && Object.keys(filter).length > 0;
@@ -207,109 +174,18 @@ function useCmsContent({
207
174
  }
208
175
  }
209
176
  `;
210
- const GET_CONTENT = client.gql(queryStr);
211
- const { loading, error, data, ...rest } = react$1.useQuery(GET_CONTENT, {
212
- variables: queryVariables,
213
- skip: !schema_slug || isSingle && !entrySlug
214
- });
215
- const typed = data;
216
- const result = isSingle ? typed?.entry : typed?.entries;
217
177
  return {
218
- loading,
219
- error,
220
- data: result,
221
- ...rest
178
+ query: client.gql(queryStr),
179
+ variables: queryVariables,
180
+ isSingle
222
181
  };
223
182
  }
224
- function useCmsMutate({
225
- schema_slug,
226
- select = [],
227
- fullData = false,
228
- mutationType = "create",
229
- entryId,
230
- variables: inputVariables = {}
231
- }) {
232
- const buildSelection = (items = []) => {
233
- const lines = [];
234
- for (const item of items) {
235
- if (typeof item === "string") {
236
- lines.push(`${item}: dataField(slug: "${item}")`);
237
- continue;
238
- }
239
- const { field, as, single, select: subSelect } = item;
240
- const alias = as || field;
241
- if (!subSelect?.length) {
242
- lines.push(`${alias}: dataField(slug: "${field}")`);
243
- continue;
244
- }
245
- const resolver = single ? "expandedReferenceObject" : "expandedReference";
246
- const sub = buildSelection(subSelect) || "id slug";
247
- lines.push(`
248
- ${alias}: ${resolver}(slug: "${field}") {
249
- id
250
- slug
251
- ${sub}
252
- }
253
- `);
254
- }
255
- return lines.join("\n ").trim();
256
- };
257
- const userSelection = buildSelection(select);
258
- let selection = fullData ? "data" : "";
259
- if (userSelection) {
260
- selection = selection ? `${selection}
261
- ${userSelection}` : userSelection;
262
- }
263
- if (!selection) {
264
- selection = "id slug status version created_at updated_at";
265
- }
266
- const operation = mutationType;
267
- const mutationName = `${operation}ContentEntry`;
268
- const varDecls = ["$schema_slug: String!"];
269
- const callArgs = ["schema_slug: $schema_slug"];
270
- if (operation === "create" || operation === "update") {
271
- varDecls.unshift("$data: JSONObject!");
272
- callArgs.unshift("data: $data");
273
- }
274
- if (operation === "update" || operation === "delete") {
275
- varDecls.push("$id: ID!");
276
- callArgs.push("id: $id");
277
- }
278
- const returnFields = selection.includes("data") ? selection : `${selection}
279
- data`;
280
- const MUTATION = client.gql`
281
- mutation ${mutationName}(${varDecls.join(", ")}) {
282
- result: ${mutationName}(${callArgs.join(", ")}) {
283
- id
284
- status
285
- version
286
- created_at
287
- updated_at
288
- schema {
289
- id
290
- slug
291
- }
292
- ${returnFields}
293
- }
294
- }
295
- `;
296
- const mutationVariables = {
297
- schema_slug,
298
- ...operation === "update" || operation === "delete" ? { id: entryId } : {},
299
- ...inputVariables
300
- };
301
- if ((operation === "update" || operation === "delete") && !entryId) {
302
- console.warn(`useCmsMutate: entryId is required for ${operation}`);
303
- }
304
- const [mutateFn, mutationResult] = react$1.useMutation(MUTATION, {
305
- variables: mutationVariables
306
- });
307
- const resultData = mutationResult.data?.result;
308
- return {
309
- mutate: mutateFn,
310
- ...mutationResult,
311
- data: resultData
312
- };
183
+
184
+ // src/fetchCmsContent.ts
185
+ async function fetchCmsContent(getClient, opts) {
186
+ const { query, variables, isSingle } = buildCmsQuery(opts);
187
+ const { data } = await getClient().query({ query, variables });
188
+ return isSingle ? data.entry : data.entries;
313
189
  }
314
190
 
315
191
  // src/utils/cmsImage.ts
@@ -319,10 +195,6 @@ function cmsImage(id, options) {
319
195
  const path = (options.mediaPath ?? "/media/canonical").replace(/^\/?/, "/");
320
196
  return `${base}${path}/${id}`;
321
197
  }
322
- function useCmsImage() {
323
- const { cmsUrl, mediaPath } = useAsteroidCMSConfig();
324
- return (id) => cmsImage(id, { cmsUrl, mediaPath });
325
- }
326
198
 
327
199
  // src/utils/getContentReadTime.ts
328
200
  function getContentReadTime(content, options = {}) {
@@ -996,505 +868,12 @@ function sanitizeAndStyle(html, options) {
996
868
  return out.join("");
997
869
  }
998
870
 
999
- // src/components/RichTextContent.tsx
1000
- var DEFAULT_CLASS_MAP = {
1001
- variants: {
1002
- "figure:pullquote": "relative my-8",
1003
- "blockquote:pullquote": "relative italic text-lg leading-snug tracking-[-0.01em] sm:text-xl",
1004
- "figcaption:pullquote": "mt-4 pt-3 border-t border-current/15 not-italic text-xs uppercase tracking-[0.14em] opacity-80",
1005
- "span:quote-open": "mr-1 font-serif text-[1.4em] leading-none align-[-0.15em] opacity-60 select-none",
1006
- "span:quote-close": "ml-1 font-serif text-[1.4em] leading-none align-[-0.15em] opacity-60 select-none",
1007
- "span:author": "ml-1 font-semibold not-italic tracking-[0.16em] text-current"
1008
- }
1009
- };
1010
- function mergeClassMap(defaults, user) {
1011
- if (!user) return defaults;
1012
- return {
1013
- ...defaults,
1014
- ...user,
1015
- variants: { ...defaults.variants, ...user.variants }
1016
- };
1017
- }
1018
- var COPY_ICON_SVG = `<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>`;
1019
- var CHECK_ICON_SVG = `<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="20 6 9 17 4 12"></polyline></svg>`;
1020
- var ATTRIBUTION_RE = /^(?:[—–-]+|--)\s+\S/;
1021
- function isAttributionEl(el) {
1022
- if (!el) return false;
1023
- if (el.getAttribute("data-variant") === "attribution") return true;
1024
- return ATTRIBUTION_RE.test((el.textContent ?? "").trim());
1025
- }
1026
- function findQuoteBody(bq) {
1027
- const children = Array.from(bq.children);
1028
- if (children.length === 0) return { first: null, last: null };
1029
- let lastIdx = children.length - 1;
1030
- while (lastIdx >= 0 && isAttributionEl(children[lastIdx])) lastIdx--;
1031
- if (lastIdx < 0) return { first: null, last: null };
1032
- return { first: children[0], last: children[lastIdx] };
1033
- }
1034
- function enhanceBlockquotes(root) {
1035
- const quotes = root.querySelectorAll("blockquote");
1036
- quotes.forEach((bq) => {
1037
- if (bq.dataset.rtQuoted === "1") return;
1038
- if (bq.closest('figure[data-variant="pullquote"]')) return;
1039
- bq.dataset.rtQuoted = "1";
1040
- const { first, last } = findQuoteBody(bq);
1041
- if (!first || !last) return;
1042
- const open = document.createElement("span");
1043
- open.className = "rt-quote-open";
1044
- open.setAttribute("aria-hidden", "true");
1045
- open.textContent = "\u201C";
1046
- const close = document.createElement("span");
1047
- close.className = "rt-quote-close";
1048
- close.setAttribute("aria-hidden", "true");
1049
- close.textContent = "\u201D";
1050
- first.prepend(open);
1051
- last.append(close);
1052
- });
1053
- }
1054
- function escapeHtml2(s) {
1055
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
1056
- }
1057
- function preserveSpaces(html) {
1058
- return html.replace(/ {2,}/g, (m) => "&nbsp;".repeat(m.length));
1059
- }
1060
- function highlightSource(src, lang) {
1061
- if (lang && hljs__default.default.getLanguage(lang)) {
1062
- try {
1063
- return hljs__default.default.highlight(src, { language: lang, ignoreIllegals: true }).value;
1064
- } catch {
1065
- }
1066
- }
1067
- return escapeHtml2(src);
1068
- }
1069
- function highlightLine(line, lang) {
1070
- if (!line) return "";
1071
- return preserveSpaces(highlightSource(line, lang));
1072
- }
1073
- function highlightCodeBlock(pre) {
1074
- const lang = pre.dataset.language;
1075
- if (!lang) return;
1076
- const code = pre.querySelector("code");
1077
- if (!code) return;
1078
- if (code.dataset.rtHighlighted === "1") return;
1079
- const source = code.textContent ?? "";
1080
- code.innerHTML = highlightSource(source, lang);
1081
- code.classList.add("hljs");
1082
- code.dataset.rtHighlighted = "1";
1083
- }
1084
- var DIFF_SEPARATOR_RE = /\n?@@---@@\n?/;
1085
- function diffLines(a, b) {
1086
- const n = a.length;
1087
- const m = b.length;
1088
- const dp = Array.from(
1089
- { length: n + 1 },
1090
- () => new Array(m + 1).fill(0)
1091
- );
1092
- for (let i2 = 1; i2 <= n; i2++) {
1093
- for (let j2 = 1; j2 <= m; j2++) {
1094
- dp[i2][j2] = a[i2 - 1] === b[j2 - 1] ? dp[i2 - 1][j2 - 1] + 1 : Math.max(dp[i2 - 1][j2], dp[i2][j2 - 1]);
1095
- }
1096
- }
1097
- const ops = [];
1098
- let i = n;
1099
- let j = m;
1100
- while (i > 0 && j > 0) {
1101
- if (a[i - 1] === b[j - 1]) {
1102
- ops.unshift({ t: "eq", line: a[i - 1] });
1103
- i--;
1104
- j--;
1105
- } else if (dp[i - 1][j] >= dp[i][j - 1]) {
1106
- ops.unshift({ t: "rem", line: a[i - 1] });
1107
- i--;
1108
- } else {
1109
- ops.unshift({ t: "add", line: b[j - 1] });
1110
- j--;
1111
- }
1112
- }
1113
- while (i > 0) ops.unshift({ t: "rem", line: a[--i] });
1114
- while (j > 0) ops.unshift({ t: "add", line: b[--j] });
1115
- return ops;
1116
- }
1117
- function renderDiff(before, after, lang) {
1118
- const ops = diffLines(before.split("\n"), after.split("\n"));
1119
- const rows = [];
1120
- let aNo = 0;
1121
- let bNo = 0;
1122
- let k = 0;
1123
- while (k < ops.length) {
1124
- const op = ops[k];
1125
- if (op.t === "eq") {
1126
- aNo++;
1127
- bNo++;
1128
- rows.push({
1129
- left: { n: aNo, line: op.line, cls: "" },
1130
- right: { n: bNo, line: op.line, cls: "" }
1131
- });
1132
- k++;
1133
- continue;
1134
- }
1135
- const rems = [];
1136
- while (k < ops.length && ops[k].t === "rem") {
1137
- rems.push(ops[k].line);
1138
- k++;
1139
- }
1140
- const adds = [];
1141
- while (k < ops.length && ops[k].t === "add") {
1142
- adds.push(ops[k].line);
1143
- k++;
1144
- }
1145
- const len = Math.max(rems.length, adds.length);
1146
- for (let x = 0; x < len; x++) {
1147
- const remLine = x < rems.length ? rems[x] : null;
1148
- const addLine = x < adds.length ? adds[x] : null;
1149
- rows.push({
1150
- left: {
1151
- n: remLine !== null ? ++aNo : null,
1152
- line: remLine,
1153
- cls: remLine !== null ? "rt-diff-rem" : "rt-diff-empty"
1154
- },
1155
- right: {
1156
- n: addLine !== null ? ++bNo : null,
1157
- line: addLine,
1158
- cls: addLine !== null ? "rt-diff-add" : "rt-diff-empty"
1159
- }
1160
- });
1161
- }
1162
- }
1163
- const cell = (c, side) => {
1164
- const sign = side === "l" ? "-" : "+";
1165
- const showSign = c.cls === "rt-diff-rem" || c.cls === "rt-diff-add";
1166
- return `<td class="rt-diff-num">${c.n ?? ""}</td><td class="rt-diff-sign">${showSign ? sign : ""}</td><td class="rt-diff-line ${c.cls}">${c.line === null ? "" : highlightLine(c.line, lang) || "&nbsp;"}</td>`;
1167
- };
1168
- const body = rows.map((r) => `<tr>${cell(r.left, "l")}${cell(r.right, "r")}</tr>`).join("");
1169
- return `<table class="rt-diff-table"><tbody>${body}</tbody></table>`;
1170
- }
1171
- function makeCopyButton(getText, opts = {}) {
1172
- const btn = document.createElement("button");
1173
- btn.type = "button";
1174
- btn.className = opts.className ?? "rt-codeblock__copy";
1175
- btn.setAttribute("aria-label", opts.label ?? "Copy code");
1176
- btn.innerHTML = COPY_ICON_SVG;
1177
- btn.addEventListener("click", async () => {
1178
- try {
1179
- await navigator.clipboard.writeText(getText());
1180
- btn.innerHTML = CHECK_ICON_SVG;
1181
- btn.classList.add("is-copied");
1182
- window.setTimeout(() => {
1183
- btn.innerHTML = COPY_ICON_SVG;
1184
- btn.classList.remove("is-copied");
1185
- }, 1500);
1186
- } catch {
1187
- }
1188
- });
1189
- return btn;
1190
- }
1191
- function buildCodeBlockLabel(pre) {
1192
- const filename = pre.dataset.filename;
1193
- if (!filename) return null;
1194
- const tag = document.createElement("span");
1195
- tag.className = "rt-codeblock__label";
1196
- const file = document.createElement("span");
1197
- file.className = "rt-codeblock__filename rt-codeblock__language";
1198
- file.textContent = filename;
1199
- tag.appendChild(file);
1200
- return tag;
1201
- }
1202
- function enhanceCodeBlocks(root) {
1203
- const blocks = root.querySelectorAll("pre");
1204
- blocks.forEach((pre) => {
1205
- if (pre.dataset.rtEnhanced === "1") return;
1206
- pre.dataset.rtEnhanced = "1";
1207
- pre.classList.add("rt-codeblock");
1208
- const variant = pre.dataset.variant;
1209
- if (variant === "diff") {
1210
- const codeEl = pre.querySelector("code");
1211
- const src = codeEl?.textContent ?? "";
1212
- const [beforeSrc = "", afterSrc = ""] = src.split(DIFF_SEPARATOR_RE);
1213
- pre.innerHTML = renderDiff(beforeSrc, afterSrc, pre.dataset.language);
1214
- const bar = document.createElement("div");
1215
- bar.className = "rt-diff-copy-bar";
1216
- const leftHalf = document.createElement("div");
1217
- leftHalf.className = "rt-diff-copy-half";
1218
- leftHalf.appendChild(
1219
- makeCopyButton(() => beforeSrc, {
1220
- className: "rt-diff-copy",
1221
- label: "Copy before"
1222
- })
1223
- );
1224
- const rightHalf = document.createElement("div");
1225
- rightHalf.className = "rt-diff-copy-half";
1226
- rightHalf.appendChild(
1227
- makeCopyButton(() => afterSrc, {
1228
- className: "rt-diff-copy",
1229
- label: "Copy after"
1230
- })
1231
- );
1232
- bar.appendChild(leftHalf);
1233
- bar.appendChild(rightHalf);
1234
- pre.prepend(bar);
1235
- const label2 = buildCodeBlockLabel(pre);
1236
- if (label2) pre.prepend(label2);
1237
- return;
1238
- }
1239
- if (variant === "terminal") {
1240
- pre.classList.add("rt-terminal");
1241
- const codeEl = pre.querySelector("code");
1242
- const source = codeEl?.textContent ?? "";
1243
- if (codeEl) {
1244
- const lang = pre.dataset.language || "sh";
1245
- const lines = source.split("\n");
1246
- codeEl.innerHTML = lines.map(
1247
- (line) => `<span class="rt-term-line"><span class="rt-term-prompt" aria-hidden="true">$</span> ${highlightLine(line, lang) || "&nbsp;"}</span>`
1248
- ).join("");
1249
- }
1250
- pre.appendChild(makeCopyButton(() => source, { label: "Copy commands" }));
1251
- return;
1252
- }
1253
- const label = buildCodeBlockLabel(pre);
1254
- if (label) pre.prepend(label);
1255
- pre.appendChild(
1256
- makeCopyButton(
1257
- () => pre.querySelector("code")?.textContent ?? pre.innerText
1258
- )
1259
- );
1260
- highlightCodeBlock(pre);
1261
- });
1262
- }
1263
- var CODEBLOCK_STYLE = `
1264
- .rt-codeblock { position: relative; }
1265
- .rt-codeblock[data-filename]:not([data-filename=""]) { padding-top: 2rem; }
1266
- .rt-codeblock__label {
1267
- position: absolute; top: 0.45rem; left: 0.85rem;
1268
- display: inline-flex; align-items: center; gap: 0.5rem;
1269
- font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
1270
- pointer-events: none;
1271
- }
1272
- .rt-codeblock__filename {
1273
- font-size: 0.72rem; letter-spacing: 0.02em;
1274
- color: #d1d5db;
1275
- }
1276
- .rt-codeblock__sep {
1277
- color: #6b7280;
1278
- font-size: 0.72rem;
1279
- }
1280
- .rt-codeblock__language {
1281
- font-size: 0.6rem; letter-spacing: 0.08em;
1282
- text-transform: lowercase;
1283
- color: #9ca3af;
1284
- padding: 0.05rem 0.35rem;
1285
- border: 1px solid rgba(255,255,255,0.12);
1286
- border-radius: 0.25rem;
1287
- }
1288
- .rt-codeblock__copy {
1289
- position: absolute; top: 0.4rem; right: 0.4rem;
1290
- display: inline-flex; align-items: center; justify-content: center;
1291
- width: 1.75rem; height: 1.75rem; padding: 0;
1292
- border: 1px solid rgba(255,255,255,0.08);
1293
- border-radius: 0.375rem;
1294
- background: rgba(255,255,255,0.04);
1295
- color: #d1d5db;
1296
- cursor: pointer;
1297
- opacity: 0; transition: opacity 120ms ease, background 120ms ease, color 120ms ease;
1298
- }
1299
- .rt-codeblock:hover .rt-codeblock__copy,
1300
- .rt-codeblock:focus-within .rt-codeblock__copy { opacity: 1; }
1301
- .rt-codeblock__copy:hover { background: rgba(255,255,255,0.1); color: #fff; }
1302
- .rt-codeblock__copy.is-copied { color: #34d399; opacity: 1; }
1303
- @media (hover: none) { .rt-codeblock__copy { opacity: 1; } }
1304
- .rt-quote-open, .rt-quote-close {
1305
- font-family: Georgia, "Times New Roman", serif;
1306
- font-size: 1.4em;
1307
- line-height: 0;
1308
- vertical-align: -0.15em;
1309
- opacity: 0.6;
1310
- user-select: none;
1311
- }
1312
- .rt-quote-open { margin-right: 0.15em; }
1313
- .rt-quote-close { margin-left: 0.15em; }
1314
- /* highlight.js theme handles .hljs-* color classes; we only override the
1315
- default .hljs background so the per-block chrome (dark bg, terminal,
1316
- diff red/green rows) wins. */
1317
- .rt-codeblock .hljs,
1318
- .rt-codeblock code.hljs { background: transparent; padding: 0; }
1319
-
1320
- /* Terminal variant ------------------------------------------------------- */
1321
- .rt-codeblock.rt-terminal,
1322
- .rt-codeblock[data-variant="terminal"] {
1323
- position: relative;
1324
- padding-top: 2.25rem;
1325
- background: #0b0b0d;
1326
- border: 1px solid rgba(255,255,255,0.08);
1327
- border-radius: 0.65rem;
1328
- box-shadow: 0 1px 0 rgba(255,255,255,0.04) inset,
1329
- 0 10px 30px -10px rgba(0,0,0,0.6);
1330
- }
1331
- .rt-codeblock.rt-terminal::before,
1332
- .rt-codeblock[data-variant="terminal"]::before {
1333
- content: "";
1334
- position: absolute; top: 0; left: 0; right: 0; height: 1.75rem;
1335
- background: linear-gradient(#1a1a1d, #141417);
1336
- border-bottom: 1px solid rgba(255,255,255,0.06);
1337
- border-radius: 0.65rem 0.65rem 0 0;
1338
- }
1339
- .rt-codeblock.rt-terminal::after,
1340
- .rt-codeblock[data-variant="terminal"]::after {
1341
- content: "";
1342
- position: absolute; top: 0.55rem; left: 0.75rem;
1343
- width: 0.65rem; height: 0.65rem; border-radius: 50%;
1344
- background: #ff5f57;
1345
- box-shadow:
1346
- 1.1rem 0 0 0 #febc2e,
1347
- 2.2rem 0 0 0 #28c840;
1348
- }
1349
- .rt-codeblock.rt-terminal code,
1350
- .rt-codeblock[data-variant="terminal"] code {
1351
- color: #d4d4d8;
1352
- display: block;
1353
- }
1354
- .rt-term-line { display: block; white-space: pre-wrap; }
1355
- .rt-term-prompt {
1356
- color: #28c840;
1357
- font-weight: 600;
1358
- margin-right: 0.35em;
1359
- user-select: none;
1360
- }
1361
-
1362
- /* Diff variant ----------------------------------------------------------- */
1363
- .rt-codeblock[data-variant="diff"] {
1364
- padding: 0;
1365
- overflow: hidden;
1366
- background: #0b0b0d;
1367
- border: 1px solid rgba(255,255,255,0.08);
1368
- }
1369
- .rt-codeblock[data-variant="diff"][data-filename]:not([data-filename=""]) {
1370
- padding-top: 2rem;
1371
- }
1372
- .rt-diff-table {
1373
- width: 100%;
1374
- border-collapse: collapse;
1375
- font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
1376
- font-size: 0.78rem;
1377
- line-height: 1.55;
1378
- color: #e5e7eb;
1379
- table-layout: fixed;
1380
- }
1381
- .rt-diff-table colgroup { display: none; }
1382
- .rt-diff-table td {
1383
- padding: 0 0.5rem;
1384
- vertical-align: top;
1385
- white-space: pre-wrap;
1386
- word-break: break-word;
1387
- }
1388
- .rt-diff-table td.rt-diff-num {
1389
- width: 2.25rem;
1390
- text-align: right;
1391
- color: rgba(156,163,175,0.55);
1392
- user-select: none;
1393
- background: rgba(255,255,255,0.02);
1394
- }
1395
- .rt-diff-table td.rt-diff-sign {
1396
- width: 0.85rem;
1397
- text-align: center;
1398
- user-select: none;
1399
- color: rgba(255,255,255,0.45);
1400
- }
1401
- .rt-diff-table td.rt-diff-line.rt-diff-rem {
1402
- background: rgba(248,113,113,0.12);
1403
- color: #fecaca;
1404
- }
1405
- .rt-diff-table tr:has(td.rt-diff-rem) td.rt-diff-sign:first-of-type {
1406
- color: #f87171;
1407
- }
1408
- .rt-diff-table td.rt-diff-line.rt-diff-add {
1409
- background: rgba(74,222,128,0.12);
1410
- color: #bbf7d0;
1411
- }
1412
- .rt-diff-table tr:has(td.rt-diff-add) td.rt-diff-sign + td + td + td.rt-diff-sign {
1413
- color: #4ade80;
1414
- }
1415
- .rt-diff-table td.rt-diff-line.rt-diff-empty {
1416
- background: rgba(255,255,255,0.025);
1417
- }
1418
- .rt-diff-table tr td:nth-child(4) { border-left: 1px solid rgba(255,255,255,0.06); }
1419
- .rt-diff-copy-bar {
1420
- position: absolute; top: 0.4rem; left: 0; right: 0; z-index: 2;
1421
- display: grid; grid-template-columns: 1fr 1fr;
1422
- pointer-events: none;
1423
- }
1424
- .rt-diff-copy-half {
1425
- display: flex;
1426
- justify-content: flex-end;
1427
- padding-right: 0.4rem;
1428
- }
1429
- .rt-diff-copy {
1430
- pointer-events: auto;
1431
- display: inline-flex; align-items: center; justify-content: center;
1432
- width: 1.6rem; height: 1.6rem; padding: 0;
1433
- border: 1px solid rgba(255,255,255,0.1);
1434
- border-radius: 0.375rem;
1435
- background: rgba(20,20,23,0.85);
1436
- color: #d1d5db;
1437
- cursor: pointer;
1438
- opacity: 0; transition: opacity 120ms ease, background 120ms ease, color 120ms ease;
1439
- }
1440
- .rt-codeblock[data-variant="diff"]:hover .rt-diff-copy,
1441
- .rt-codeblock[data-variant="diff"]:focus-within .rt-diff-copy { opacity: 1; }
1442
- .rt-diff-copy:hover { background: rgba(0,0,0,0.92); color: #fff; }
1443
- .rt-diff-copy.is-copied { color: #34d399; opacity: 1; }
1444
- @media (hover: none) { .rt-diff-copy { opacity: 1; } }
1445
- `;
1446
- var styleInjected = false;
1447
- function ensureCodeBlockStyles() {
1448
- if (styleInjected || typeof document === "undefined") return;
1449
- if (document.getElementById("rt-codeblock-style")) {
1450
- styleInjected = true;
1451
- return;
1452
- }
1453
- const tag = document.createElement("style");
1454
- tag.id = "rt-codeblock-style";
1455
- tag.textContent = CODEBLOCK_STYLE;
1456
- document.head.appendChild(tag);
1457
- styleInjected = true;
1458
- }
1459
- function RichTextContent({
1460
- html,
1461
- classMap,
1462
- as = "div",
1463
- className
1464
- }) {
1465
- const merged = react.useMemo(
1466
- () => mergeClassMap(DEFAULT_CLASS_MAP, classMap),
1467
- [classMap]
1468
- );
1469
- const safe = react.useMemo(
1470
- () => parseRichText(html, { classMap: merged }),
1471
- [html, merged]
1472
- );
1473
- const ref = react.useRef(null);
1474
- react.useEffect(() => {
1475
- ensureCodeBlockStyles();
1476
- if (ref.current) {
1477
- enhanceCodeBlocks(ref.current);
1478
- enhanceBlockquotes(ref.current);
1479
- }
1480
- }, [safe]);
1481
- return react.createElement(as, {
1482
- ref,
1483
- className,
1484
- dangerouslySetInnerHTML: { __html: safe }
1485
- });
1486
- }
1487
-
1488
- exports.AsteroidCMSProvider = AsteroidCMSProvider;
1489
- exports.RichTextContent = RichTextContent;
871
+ exports.buildCmsQuery = buildCmsQuery;
1490
872
  exports.cmsImage = cmsImage;
1491
873
  exports.createApolloClient = createApolloClient;
874
+ exports.fetchCmsContent = fetchCmsContent;
1492
875
  exports.getContentReadTime = getContentReadTime;
1493
876
  exports.parseRichText = parseRichText;
1494
877
  exports.removeEmptyParagraphs = removeEmptyParagraphs;
1495
- exports.useAsteroidCMSConfig = useAsteroidCMSConfig;
1496
- exports.useCmsContent = useCmsContent;
1497
- exports.useCmsImage = useCmsImage;
1498
- exports.useCmsMutate = useCmsMutate;
1499
878
  //# sourceMappingURL=index.cjs.map
1500
879
  //# sourceMappingURL=index.cjs.map