domma-cms 0.34.0 → 0.34.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-cms",
3
- "version": "0.34.0",
3
+ "version": "0.34.1",
4
4
  "description": "File-based CMS powered by Domma and Fastify. Run npx domma-cms my-site to create a new project.",
5
5
  "type": "module",
6
6
  "main": "server/server.js",
@@ -198,6 +198,27 @@ export class MongoAdapter {
198
198
  await col.deleteMany({});
199
199
  }
200
200
 
201
+ /**
202
+ * Drop the backing MongoDB collection entirely (documents, indexes and
203
+ * the namespace). Used when the CMS collection itself is deleted —
204
+ * clear() only removes documents and would leave `cms_<slug>` behind.
205
+ *
206
+ * Deliberately bypasses _col(): that helper ensures the unique index,
207
+ * which would recreate the very collection being removed.
208
+ *
209
+ * @param {string} slug
210
+ * @returns {Promise<void>}
211
+ */
212
+ async drop(slug) {
213
+ try {
214
+ await this._db.collection(`${PREFIX}${slug}`).drop();
215
+ } catch (err) {
216
+ // Already absent — nothing to drop.
217
+ if (err.codeName !== 'NamespaceNotFound') throw err;
218
+ }
219
+ this._ensured.delete(slug);
220
+ }
221
+
201
222
  /**
202
223
  * Return all entries (used for export).
203
224
  *
@@ -92,7 +92,10 @@ export async function listCollections() {
92
92
  return results
93
93
  .filter(r => r.status === 'fulfilled')
94
94
  .map(r => r.value)
95
- .sort((a, b) => a.title.localeCompare(b.title));
95
+ // Hand-rolled schemas can lack `title` — fall back to slug rather
96
+ // than crashing the whole listing (seen in the wild: a schema with
97
+ // `name` instead of `title` 500'd /api/collections permanently).
98
+ .sort((a, b) => String(a.title || a.slug || '').localeCompare(String(b.title || b.slug || '')));
96
99
  }
97
100
 
98
101
  /**
@@ -210,11 +213,18 @@ export async function deleteCollection(slug) {
210
213
  const schema = await getCollection(slug);
211
214
  if (!schema) throw new Error(`Collection "${slug}" not found`);
212
215
 
213
- // Clear adapter data first (handles MongoDB collections on non-file adapters).
216
+ // Remove adapter-side data first (handles MongoDB collections on
217
+ // non-file adapters). Prefer drop() — clear() only deletes documents
218
+ // and leaves the backing Mongo collection + its unique index behind
219
+ // forever.
214
220
  try {
215
221
  const adapter = await getAdapter(slug);
216
222
  if (adapter.constructor.name !== 'FileAdapter') {
217
- await adapter.clear(slug);
223
+ if (typeof adapter.drop === 'function') {
224
+ await adapter.drop(slug);
225
+ } else {
226
+ await adapter.clear(slug);
227
+ }
218
228
  }
219
229
  } catch {
220
230
  // Ignore errors — directory removal handles file-backed data.