@cancia/astro 0.8.0 → 0.9.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.
@@ -67,6 +67,52 @@ function hashRev(value) {
67
67
  import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync2, mkdirSync as mkdirSync2, readdirSync, rmSync } from "fs";
68
68
  import { dirname as dirname2, join } from "path";
69
69
  import { randomUUID } from "crypto";
70
+
71
+ // src/storage/order.ts
72
+ function applyOrder(order, ids) {
73
+ const result = [];
74
+ const seen = /* @__PURE__ */ new Set();
75
+ for (const id of order) {
76
+ if (ids.has(id)) {
77
+ result.push(id);
78
+ seen.add(id);
79
+ }
80
+ }
81
+ const extras = [...ids].filter((id) => !seen.has(id)).sort();
82
+ return [...result, ...extras];
83
+ }
84
+ function orderAfterCreate(order, id) {
85
+ return order.includes(id) ? order : [...order, id];
86
+ }
87
+ function orderAfterDelete(order, id, stillExistsElsewhere) {
88
+ if (stillExistsElsewhere) return order;
89
+ const next = order.filter((existingId) => existingId !== id);
90
+ return next.length === order.length ? order : next;
91
+ }
92
+ var UnknownEntryError = class extends Error {
93
+ constructor(id, listName) {
94
+ super(`Cannot reorder: entry "${id}" not found in "${listName}"`);
95
+ this.id = id;
96
+ this.listName = listName;
97
+ this.name = "UnknownEntryError";
98
+ }
99
+ };
100
+ function planReorder(ids, allIds, listName) {
101
+ for (const id of ids) {
102
+ if (!allIds.has(id)) throw new UnknownEntryError(id, listName);
103
+ }
104
+ const keep = new Set(ids);
105
+ const dropped = [...allIds].filter((id) => !keep.has(id));
106
+ return { order: ids, dropped };
107
+ }
108
+ function entryExistsMessage(id, listName, locale) {
109
+ return `List entry "${id}" already exists in "${listName}" (${locale})`;
110
+ }
111
+ function entryNotFoundMessage(id, listName, locale) {
112
+ return `List entry "${id}" not found in "${listName}" (${locale})`;
113
+ }
114
+
115
+ // src/storage/json-file-v2.ts
70
116
  function readJsonFile(filePath, fallback) {
71
117
  if (!existsSync2(filePath)) return fallback;
72
118
  try {
@@ -168,18 +214,6 @@ function makeListStore(listsDir) {
168
214
  function writeEntry(site, listName, locale, entry) {
169
215
  writeJsonFile(entryPath(listsDir, listName, site, locale, entry.id), entry);
170
216
  }
171
- function applyOrder(order, ids) {
172
- const result = [];
173
- const seen = /* @__PURE__ */ new Set();
174
- for (const id of order) {
175
- if (ids.has(id)) {
176
- result.push(id);
177
- seen.add(id);
178
- }
179
- }
180
- const extras = [...ids].filter((id) => !seen.has(id)).sort();
181
- return [...result, ...extras];
182
- }
183
217
  return {
184
218
  async list(site, listName, locale) {
185
219
  const order = readOrder(listsDir, listName, site);
@@ -218,7 +252,7 @@ function makeListStore(listsDir) {
218
252
  const finalId = id ?? randomUUID();
219
253
  const existing = readEntry(site, listName, finalId, locale);
220
254
  if (existing) {
221
- throw new Error(`List entry "${finalId}" already exists in "${listName}" (${locale})`);
255
+ throw new Error(entryExistsMessage(finalId, listName, locale));
222
256
  }
223
257
  const now = (/* @__PURE__ */ new Date()).toISOString();
224
258
  const entry = {
@@ -230,15 +264,14 @@ function makeListStore(listsDir) {
230
264
  };
231
265
  writeEntry(site, listName, locale, entry);
232
266
  const order = readOrder(listsDir, listName, site);
233
- if (!order.includes(finalId)) {
234
- writeOrder(listsDir, listName, site, [...order, finalId]);
235
- }
267
+ const nextOrder = orderAfterCreate(order, finalId);
268
+ if (nextOrder !== order) writeOrder(listsDir, listName, site, nextOrder);
236
269
  return toEntry(entry);
237
270
  },
238
271
  async update(site, listName, id, locale, data, rev) {
239
272
  const existing = readEntry(site, listName, id, locale);
240
273
  if (!existing) {
241
- throw new Error(`List entry "${id}" not found in "${listName}" (${locale})`);
274
+ throw new Error(entryNotFoundMessage(id, listName, locale));
242
275
  }
243
276
  if (hashRev(existing.data) !== rev) throw new RevConflictError();
244
277
  const updated = {
@@ -254,13 +287,9 @@ function makeListStore(listsDir) {
254
287
  if (!existsSync2(path)) return;
255
288
  rmSync(path);
256
289
  const stillExists = listLocales(listsDir, listName, site).some((loc) => existsSync2(entryPath(listsDir, listName, site, loc, id)));
257
- if (!stillExists) {
258
- const order = readOrder(listsDir, listName, site);
259
- const next = order.filter((existingId) => existingId !== id);
260
- if (next.length !== order.length) {
261
- writeOrder(listsDir, listName, site, next);
262
- }
263
- }
290
+ const order = readOrder(listsDir, listName, site);
291
+ const next = orderAfterDelete(order, id, stillExists);
292
+ if (next !== order) writeOrder(listsDir, listName, site, next);
264
293
  },
265
294
  async reorder(site, listName, ids) {
266
295
  const locales = listLocales(listsDir, listName, site);
@@ -270,20 +299,14 @@ function makeListStore(listsDir) {
270
299
  allIds.add(id);
271
300
  }
272
301
  }
273
- for (const id of ids) {
274
- if (!allIds.has(id)) {
275
- throw new Error(`Cannot reorder: entry "${id}" not found in "${listName}"`);
276
- }
277
- }
278
- const supplied = new Set(ids);
279
- for (const id of allIds) {
280
- if (supplied.has(id)) continue;
302
+ const { order, dropped } = planReorder(ids, allIds, listName);
303
+ for (const id of dropped) {
281
304
  for (const loc of locales) {
282
305
  const path = entryPath(listsDir, listName, site, loc, id);
283
306
  if (existsSync2(path)) rmSync(path);
284
307
  }
285
308
  }
286
- writeOrder(listsDir, listName, site, ids);
309
+ writeOrder(listsDir, listName, site, order);
287
310
  },
288
311
  async translations(site, listName) {
289
312
  const locales = listLocales(listsDir, listName, site);
@@ -320,5 +343,11 @@ export {
320
343
  createJsonFileAdapter,
321
344
  canonicalize,
322
345
  hashRev,
346
+ applyOrder,
347
+ orderAfterCreate,
348
+ orderAfterDelete,
349
+ planReorder,
350
+ entryExistsMessage,
351
+ entryNotFoundMessage,
323
352
  createJsonFileAdapterV2
324
353
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createJsonFileAdapterV2
3
- } from "./chunk-L2VKQJPY.js";
3
+ } from "./chunk-2NVZWZPE.js";
4
4
  import {
5
5
  isDraft
6
6
  } from "./chunk-WVHTCFE6.js";
@@ -0,0 +1,55 @@
1
+ // src/auth-core.ts
2
+ var MAX_FAILURES = 5;
3
+ var WINDOW_MS = 6e4;
4
+ function createRateLimiter() {
5
+ return /* @__PURE__ */ new Map();
6
+ }
7
+ function getIp(req) {
8
+ return req.headers.get("x-forwarded-for")?.split(",")[0].trim() ?? req.headers.get("x-real-ip") ?? "unknown";
9
+ }
10
+ function isRateLimited(limiter, ip, now = Date.now()) {
11
+ const bucket = limiter.get(ip);
12
+ if (!bucket || now > bucket.resetAt) return false;
13
+ return bucket.failures >= MAX_FAILURES;
14
+ }
15
+ function recordFailure(limiter, ip, now = Date.now()) {
16
+ const bucket = limiter.get(ip);
17
+ if (!bucket || now > bucket.resetAt) {
18
+ limiter.set(ip, { failures: 1, resetAt: now + WINDOW_MS });
19
+ } else {
20
+ bucket.failures += 1;
21
+ }
22
+ }
23
+ function clearFailures(limiter, ip) {
24
+ limiter.delete(ip);
25
+ }
26
+ var json = (body, status) => new Response(JSON.stringify(body), {
27
+ status,
28
+ headers: { "Content-Type": "application/json" }
29
+ });
30
+ async function runAuth(cfg) {
31
+ const { request, secret, limiter } = cfg;
32
+ const now = cfg.now ?? Date.now();
33
+ const ip = getIp(request);
34
+ if (isRateLimited(limiter, ip, now)) {
35
+ return json({ error: "Too many attempts. Try again in a minute." }, 429);
36
+ }
37
+ let token;
38
+ try {
39
+ const body = await request.json();
40
+ token = body?.token;
41
+ } catch {
42
+ return json({ error: "Invalid request body" }, 400);
43
+ }
44
+ if (!token || !secret || token !== secret) {
45
+ recordFailure(limiter, ip, now);
46
+ return json({ error: "Invalid token" }, 401);
47
+ }
48
+ clearFailures(limiter, ip);
49
+ return json({ ok: true }, 200);
50
+ }
51
+
52
+ export {
53
+ createRateLimiter,
54
+ runAuth
55
+ };
@@ -5,11 +5,11 @@ import {
5
5
  import {
6
6
  createGitBackedAdapter,
7
7
  createSqliteAdapterV2
8
- } from "./chunk-GNWD7EL2.js";
8
+ } from "./chunk-MXVOJRAM.js";
9
9
  import {
10
10
  createJsonFileAdapter,
11
11
  createJsonFileAdapterV2
12
- } from "./chunk-L2VKQJPY.js";
12
+ } from "./chunk-2NVZWZPE.js";
13
13
 
14
14
  // src/routes/upload.ts
15
15
  import { writeFile, mkdir } from "fs/promises";
@@ -2,8 +2,14 @@ import {
2
2
  createGitHubClient
3
3
  } from "./chunk-U7V53JX7.js";
4
4
  import {
5
- hashRev
6
- } from "./chunk-L2VKQJPY.js";
5
+ applyOrder,
6
+ entryExistsMessage,
7
+ entryNotFoundMessage,
8
+ hashRev,
9
+ orderAfterCreate,
10
+ orderAfterDelete,
11
+ planReorder
12
+ } from "./chunk-2NVZWZPE.js";
7
13
  import {
8
14
  RevConflictError
9
15
  } from "./chunk-7IA5B5CF.js";
@@ -119,18 +125,6 @@ function rowToEntry(row) {
119
125
  _rev: hashRev(data)
120
126
  };
121
127
  }
122
- function applyOrder(order, ids) {
123
- const result = [];
124
- const seen = /* @__PURE__ */ new Set();
125
- for (const id of order) {
126
- if (ids.has(id)) {
127
- result.push(id);
128
- seen.add(id);
129
- }
130
- }
131
- const extras = [...ids].filter((id) => !seen.has(id)).sort();
132
- return [...result, ...extras];
133
- }
134
128
  function makeListStore(db) {
135
129
  const getOrderStmt = db.prepare("SELECT ids FROM list_order WHERE site=? AND list=?");
136
130
  const upsertOrderStmt = db.prepare(
@@ -178,32 +172,25 @@ function makeListStore(db) {
178
172
  (site, listName, id, locale, dataJson, now) => {
179
173
  insertEntryStmt.run(site, listName, id, locale, dataJson, now, now);
180
174
  const order = readOrder(site, listName);
181
- if (!order.includes(id)) {
182
- writeOrder(site, listName, [...order, id]);
183
- }
175
+ const next = orderAfterCreate(order, id);
176
+ if (next !== order) writeOrder(site, listName, next);
184
177
  }
185
178
  );
186
179
  const deleteTx = db.transaction((site, listName, id, locale) => {
187
180
  deleteEntryStmt.run(site, listName, id, locale);
188
181
  const stillExists = distinctIds(site, listName).has(id);
189
- if (!stillExists) {
190
- const order = readOrder(site, listName);
191
- const next = order.filter((existingId) => existingId !== id);
192
- if (next.length !== order.length) {
193
- writeOrder(site, listName, next);
194
- }
195
- }
182
+ const order = readOrder(site, listName);
183
+ const next = orderAfterDelete(order, id, stillExists);
184
+ if (next !== order) writeOrder(site, listName, next);
196
185
  });
197
- const reorderTx = db.transaction((site, listName, ids) => {
198
- const all = distinctIds(site, listName);
199
- const supplied = new Set(ids);
200
- for (const id of all) {
201
- if (!supplied.has(id)) {
186
+ const reorderTx = db.transaction(
187
+ (site, listName, order, dropped) => {
188
+ for (const id of dropped) {
202
189
  deleteEntryAllLocalesStmt.run(site, listName, id);
203
190
  }
191
+ writeOrder(site, listName, order);
204
192
  }
205
- writeOrder(site, listName, ids);
206
- });
193
+ );
207
194
  return {
208
195
  async list(site, listName, locale) {
209
196
  const order = readOrder(site, listName);
@@ -244,7 +231,7 @@ function makeListStore(db) {
244
231
  const finalId = id ?? randomUUID();
245
232
  const existing = getEntryStmt.get(site, listName, finalId, locale);
246
233
  if (existing) {
247
- throw new Error(`List entry "${finalId}" already exists in "${listName}" (${locale})`);
234
+ throw new Error(entryExistsMessage(finalId, listName, locale));
248
235
  }
249
236
  const now = (/* @__PURE__ */ new Date()).toISOString();
250
237
  createTx(site, listName, finalId, locale, JSON.stringify(data), now);
@@ -260,7 +247,7 @@ function makeListStore(db) {
260
247
  async update(site, listName, id, locale, data, rev) {
261
248
  const existing = getEntryStmt.get(site, listName, id, locale);
262
249
  if (!existing) {
263
- throw new Error(`List entry "${id}" not found in "${listName}" (${locale})`);
250
+ throw new Error(entryNotFoundMessage(id, listName, locale));
264
251
  }
265
252
  const existingData = JSON.parse(existing.data);
266
253
  if (hashRev(existingData) !== rev) throw new RevConflictError();
@@ -282,12 +269,8 @@ function makeListStore(db) {
282
269
  },
283
270
  async reorder(site, listName, ids) {
284
271
  const all = distinctIds(site, listName);
285
- for (const id of ids) {
286
- if (!all.has(id)) {
287
- throw new Error(`Cannot reorder: entry "${id}" not found in "${listName}"`);
288
- }
289
- }
290
- reorderTx(site, listName, ids);
272
+ const { order, dropped } = planReorder(ids, all, listName);
273
+ reorderTx(site, listName, order, dropped);
291
274
  },
292
275
  async translations(site, listName) {
293
276
  const rows = allEntriesStmt.all(site, listName);
package/dist/content.js CHANGED
@@ -2,9 +2,9 @@ import "./chunk-FOSOWSXV.js";
2
2
  import "./chunk-CJDIVWO3.js";
3
3
  import {
4
4
  createSqliteAdapterV2
5
- } from "./chunk-GNWD7EL2.js";
5
+ } from "./chunk-MXVOJRAM.js";
6
6
  import "./chunk-U7V53JX7.js";
7
- import "./chunk-L2VKQJPY.js";
7
+ import "./chunk-2NVZWZPE.js";
8
8
  import "./chunk-7IA5B5CF.js";
9
9
 
10
10
  // src/content.ts
@@ -1,55 +1,14 @@
1
+ import {
2
+ createRateLimiter,
3
+ runAuth
4
+ } from "../chunk-GJIX7MWC.js";
5
+
1
6
  // src/endpoints/auth.ts
2
7
  import { getCanciaRuntime } from "virtual:cancia/runtime";
3
- var buckets = /* @__PURE__ */ new Map();
4
- var MAX_FAILURES = 5;
5
- var WINDOW_MS = 6e4;
6
- function getIp(req) {
7
- return req.headers.get("x-forwarded-for")?.split(",")[0].trim() ?? req.headers.get("x-real-ip") ?? "unknown";
8
- }
9
- function isRateLimited(ip) {
10
- const bucket = buckets.get(ip);
11
- if (!bucket || Date.now() > bucket.resetAt) return false;
12
- return bucket.failures >= MAX_FAILURES;
13
- }
14
- function recordFailure(ip) {
15
- const now = Date.now();
16
- const bucket = buckets.get(ip);
17
- if (!bucket || now > bucket.resetAt) {
18
- buckets.set(ip, { failures: 1, resetAt: now + WINDOW_MS });
19
- } else {
20
- bucket.failures += 1;
21
- }
22
- }
8
+ var limiter = createRateLimiter();
23
9
  async function POST({ request }) {
24
10
  const { secret } = getCanciaRuntime();
25
- const ip = getIp(request);
26
- if (isRateLimited(ip))
27
- return new Response(
28
- JSON.stringify({ error: "Too many attempts. Try again in a minute." }),
29
- { status: 429, headers: { "Content-Type": "application/json" } }
30
- );
31
- let token;
32
- try {
33
- const body = await request.json();
34
- token = body?.token;
35
- } catch {
36
- return new Response(
37
- JSON.stringify({ error: "Invalid request body" }),
38
- { status: 400, headers: { "Content-Type": "application/json" } }
39
- );
40
- }
41
- if (!token || token !== secret) {
42
- recordFailure(ip);
43
- return new Response(
44
- JSON.stringify({ error: "Invalid token" }),
45
- { status: 401, headers: { "Content-Type": "application/json" } }
46
- );
47
- }
48
- buckets.delete(ip);
49
- return new Response(
50
- JSON.stringify({ ok: true }),
51
- { status: 200, headers: { "Content-Type": "application/json" } }
52
- );
11
+ return runAuth({ request, secret, limiter });
53
12
  }
54
13
  export {
55
14
  POST
package/dist/index.js CHANGED
@@ -4,6 +4,10 @@ import {
4
4
  import {
5
5
  runPublish
6
6
  } from "./chunk-5RCLBWRH.js";
7
+ import {
8
+ createRateLimiter,
9
+ runAuth
10
+ } from "./chunk-GJIX7MWC.js";
7
11
  import {
8
12
  makeListsRoutes
9
13
  } from "./chunk-DIV2FFYX.js";
@@ -12,7 +16,7 @@ import {
12
16
  makeR2UploadHandler,
13
17
  makeUploadRoute,
14
18
  setCanciaRuntime
15
- } from "./chunk-AGNPUTKS.js";
19
+ } from "./chunk-LJSSPOSW.js";
16
20
  import "./chunk-5IPHDIC6.js";
17
21
  import {
18
22
  createSQLiteAdapter
@@ -21,16 +25,16 @@ import {
21
25
  closeSqliteAdapterV2,
22
26
  createGitBackedAdapter,
23
27
  createSqliteAdapterV2
24
- } from "./chunk-GNWD7EL2.js";
28
+ } from "./chunk-MXVOJRAM.js";
25
29
  import "./chunk-U7V53JX7.js";
26
30
  import "./chunk-VL6FO446.js";
27
31
  import {
28
32
  canciaLoader
29
- } from "./chunk-3B3CXOMK.js";
33
+ } from "./chunk-GBTFXQEA.js";
30
34
  import {
31
35
  createJsonFileAdapter,
32
36
  createJsonFileAdapterV2
33
- } from "./chunk-L2VKQJPY.js";
37
+ } from "./chunk-2NVZWZPE.js";
34
38
  import {
35
39
  RevConflictError
36
40
  } from "./chunk-7IA5B5CF.js";
@@ -115,61 +119,10 @@ function makePublishRoute(deployHook, secret, hookOptions, dispatch, mode) {
115
119
  }
116
120
 
117
121
  // src/routes/auth.ts
118
- var buckets = /* @__PURE__ */ new Map();
119
- var MAX_FAILURES = 5;
120
- var WINDOW_MS = 6e4;
121
- function getIp(req) {
122
- return req.headers.get("x-forwarded-for")?.split(",")[0].trim() ?? req.headers.get("x-real-ip") ?? "unknown";
123
- }
124
- function isRateLimited(ip) {
125
- const now = Date.now();
126
- const bucket = buckets.get(ip);
127
- if (!bucket || now > bucket.resetAt) return false;
128
- return bucket.failures >= MAX_FAILURES;
129
- }
130
- function recordFailure(ip) {
131
- const now = Date.now();
132
- const bucket = buckets.get(ip);
133
- if (!bucket || now > bucket.resetAt) {
134
- buckets.set(ip, { failures: 1, resetAt: now + WINDOW_MS });
135
- } else {
136
- bucket.failures += 1;
137
- }
138
- }
139
- function clearFailures(ip) {
140
- buckets.delete(ip);
141
- }
142
122
  function makeAuthRoute(secret) {
123
+ const limiter = createRateLimiter();
143
124
  return async function authRoute(req) {
144
- const ip = getIp(req);
145
- if (isRateLimited(ip)) {
146
- return new Response(
147
- JSON.stringify({ error: "Too many attempts. Try again in a minute." }),
148
- { status: 429, headers: { "Content-Type": "application/json" } }
149
- );
150
- }
151
- let token;
152
- try {
153
- const body = await req.json();
154
- token = body?.token;
155
- } catch {
156
- return new Response(
157
- JSON.stringify({ error: "Invalid request body" }),
158
- { status: 400, headers: { "Content-Type": "application/json" } }
159
- );
160
- }
161
- if (!token || token !== secret) {
162
- recordFailure(ip);
163
- return new Response(
164
- JSON.stringify({ error: "Invalid token" }),
165
- { status: 401, headers: { "Content-Type": "application/json" } }
166
- );
167
- }
168
- clearFailures(ip);
169
- return new Response(
170
- JSON.stringify({ ok: true }),
171
- { status: 200, headers: { "Content-Type": "application/json" } }
172
- );
125
+ return runAuth({ request: req, secret, limiter });
173
126
  };
174
127
  }
175
128
 
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  canciaLoader
3
- } from "../chunk-3B3CXOMK.js";
4
- import "../chunk-L2VKQJPY.js";
3
+ } from "../chunk-GBTFXQEA.js";
4
+ import "../chunk-2NVZWZPE.js";
5
5
  import "../chunk-7IA5B5CF.js";
6
6
  import "../chunk-WVHTCFE6.js";
7
7
  import "../chunk-KHCFVVYV.js";
package/dist/runtime.js CHANGED
@@ -3,11 +3,11 @@ import {
3
3
  getCanciaRuntime,
4
4
  setBakedConfig,
5
5
  setCanciaRuntime
6
- } from "./chunk-AGNPUTKS.js";
6
+ } from "./chunk-LJSSPOSW.js";
7
7
  import "./chunk-5IPHDIC6.js";
8
- import "./chunk-GNWD7EL2.js";
8
+ import "./chunk-MXVOJRAM.js";
9
9
  import "./chunk-U7V53JX7.js";
10
- import "./chunk-L2VKQJPY.js";
10
+ import "./chunk-2NVZWZPE.js";
11
11
  import "./chunk-7IA5B5CF.js";
12
12
  export {
13
13
  __resetRuntimeForTests,
@@ -123,7 +123,9 @@ interface ListSchema<TFields extends Record<string, z.ZodTypeAny> = Record<strin
123
123
  * to "published", matching the field's own default and keeping entries that
124
124
  * predate the draftField visible.
125
125
  */
126
- declare function isDraft(schema: Pick<ListSchema, "draftField">, data: Record<string, unknown>): boolean;
126
+ declare function isDraft(schema: {
127
+ draftField?: string;
128
+ }, data: Record<string, unknown>): boolean;
127
129
  declare function defineList<TFields extends Record<string, z.ZodTypeAny>>(opts: ListSchemaOptions<TFields>): ListSchema<TFields>;
128
130
  /**
129
131
  * One field as seen by the modal form. Plain JSON, no Zod refs.
@@ -6,7 +6,7 @@ import {
6
6
  closeSqliteAdapterV2,
7
7
  createGitBackedAdapter,
8
8
  createSqliteAdapterV2
9
- } from "../chunk-GNWD7EL2.js";
9
+ } from "../chunk-MXVOJRAM.js";
10
10
  import {
11
11
  createGitHubClient
12
12
  } from "../chunk-U7V53JX7.js";
@@ -15,7 +15,7 @@ import {
15
15
  createJsonFileAdapter,
16
16
  createJsonFileAdapterV2,
17
17
  hashRev
18
- } from "../chunk-L2VKQJPY.js";
18
+ } from "../chunk-2NVZWZPE.js";
19
19
  import {
20
20
  RevConflictError
21
21
  } from "../chunk-7IA5B5CF.js";
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@cancia/astro",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Astro integration for Cancia CMS — inline editing with zero separate server",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "https://github.com/ninuzdellalb/cancia",
8
+ "url": "git+https://github.com/ninuzdellalb/cancia.git",
9
9
  "directory": "packages/astro"
10
10
  },
11
11
  "type": "module",