@emulates/acm 0.1.1 → 1.0.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 CHANGED
@@ -1,9 +1,19 @@
1
1
  # Changelog — @emulates/acm
2
2
 
3
- ## 0.1.1 (2026-10-06)
3
+ ## 1.0.0 (2026-10-07)
4
4
 
5
- Initial release.
5
+ ### ⚠️ Breaking changes
6
+
7
+ - point the repo at crvouga/emulates ([cdb5e53](https://github.com/crvouga/emulates/commit/cdb5e536ed8c1f52345e3984f089001c25fdb08a))
8
+
9
+ ### Fixes and improvements
10
+
11
+ - format the emulates records query ([8698872](https://github.com/crvouga/emulates/commit/8698872509d06002be5a8fcdc85d79f8462320c3))
6
12
 
7
13
  ### Dependencies
8
14
 
9
15
  - `@emulates/sqlite`
16
+
17
+ ## 0.1.1 (2026-10-06)
18
+
19
+ Initial release.
package/DISCOVERY.md CHANGED
@@ -47,7 +47,7 @@ designed for assertions and diagnosis by consuming test suites.
47
47
 
48
48
  ## Report a mismatch or missing capability
49
49
 
50
- Follow the [agent reporting contract](https://github.com/crvouga/emulators/blob/main/docs/REPORTING_ISSUES.md). Include package version,
50
+ Follow the [agent reporting contract](https://github.com/crvouga/emulates/blob/main/docs/REPORTING_ISSUES.md). Include package version,
51
51
  operation/command, a minimal redacted request, actual emulator result, expected oracle result or vendor
52
52
  documentation, and whether the mismatch appears in the matrix. Never include keys, tokens,
53
53
  customer data, prompts, PHI, card data, or unredacted recordings.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @emulates/acm
2
2
 
3
- > Part of [Emulates](https://github.com/crvouga/emulators): high-fidelity, in-process emulators for APIs and databases.
3
+ > Part of [Emulates](https://github.com/crvouga/emulates): high-fidelity, in-process emulators for APIs and databases.
4
4
 
5
5
  Stateful local emulator of Amazon Certificate Manager. ESM; Node 22+ or Bun 1.2+.
6
6
 
@@ -83,7 +83,7 @@ var CORE_MIGRATIONS = [
83
83
  {
84
84
  id: "20260322_core_records_sequences",
85
85
  sql: `
86
- CREATE TABLE IF NOT EXISTS emulators_records (
86
+ CREATE TABLE IF NOT EXISTS emulates_records (
87
87
  namespace TEXT NOT NULL,
88
88
  collection TEXT NOT NULL,
89
89
  id TEXT NOT NULL,
@@ -91,9 +91,9 @@ var CORE_MIGRATIONS = [
91
91
  value TEXT NOT NULL,
92
92
  PRIMARY KEY (namespace, collection, id)
93
93
  );
94
- CREATE INDEX IF NOT EXISTS emulators_records_seq
95
- ON emulators_records (namespace, collection, seq);
96
- CREATE TABLE IF NOT EXISTS emulators_sequences (
94
+ CREATE INDEX IF NOT EXISTS emulates_records_seq
95
+ ON emulates_records (namespace, collection, seq);
96
+ CREATE TABLE IF NOT EXISTS emulates_sequences (
97
97
  namespace TEXT NOT NULL,
98
98
  name TEXT NOT NULL,
99
99
  kind TEXT NOT NULL,
@@ -103,13 +103,33 @@ var CORE_MIGRATIONS = [
103
103
  `
104
104
  }
105
105
  ];
106
+ var LEGACY_TABLES = [
107
+ ["emulators_records", "emulates_records"],
108
+ ["emulators_sequences", "emulates_sequences"]
109
+ ];
110
+ var LEGACY_INDEXES = [["emulators_records_seq", "emulates_records_seq"]];
111
+ var namesOf = (sqlite, type) => new Set(sqlite.prepare("SELECT name FROM sqlite_master WHERE type = ?").all(type).map((row) => row.name));
106
112
  var migrateCore = (sqlite) => {
107
113
  migrate(sqlite, CORE_MIGRATIONS);
114
+ const tables = namesOf(sqlite, "table");
115
+ const indexes = namesOf(sqlite, "index");
116
+ sqlite.transaction(() => {
117
+ for (const [from, to] of LEGACY_TABLES) {
118
+ if (tables.has(from) && !tables.has(to))
119
+ sqlite.exec(`ALTER TABLE ${from} RENAME TO ${to}`);
120
+ }
121
+ for (const [from, to] of LEGACY_INDEXES) {
122
+ if (!indexes.has(from) || indexes.has(to))
123
+ continue;
124
+ sqlite.exec(`DROP INDEX ${from}`);
125
+ sqlite.exec(`CREATE INDEX ${to} ON emulates_records (namespace, collection, seq)`);
126
+ }
127
+ });
108
128
  };
109
129
  var clearNamespace = (sqlite, namespace) => {
110
130
  sqlite.transaction(() => {
111
- sqlite.prepare("DELETE FROM emulators_records WHERE namespace = ?").run(namespace);
112
- sqlite.prepare("DELETE FROM emulators_sequences WHERE namespace = ?").run(namespace);
131
+ sqlite.prepare("DELETE FROM emulates_records WHERE namespace = ?").run(namespace);
132
+ sqlite.prepare("DELETE FROM emulates_sequences WHERE namespace = ?").run(namespace);
113
133
  });
114
134
  };
115
135
 
@@ -4270,9 +4290,9 @@ var Collection = class {
4270
4290
  this.collectionName = collectionName;
4271
4291
  }
4272
4292
  bumpCollectionSeq() {
4273
- const row = this.sqlite.prepare("SELECT value FROM emulators_sequences WHERE namespace = ? AND name = ? AND kind = 'collection'").get(this.namespace, this.collectionName);
4293
+ const row = this.sqlite.prepare("SELECT value FROM emulates_sequences WHERE namespace = ? AND name = ? AND kind = 'collection'").get(this.namespace, this.collectionName);
4274
4294
  const next = (row?.value ?? 0) + 1;
4275
- this.sqlite.prepare(`INSERT INTO emulators_sequences (namespace, name, kind, value) VALUES (?, ?, 'collection', ?)
4295
+ this.sqlite.prepare(`INSERT INTO emulates_sequences (namespace, name, kind, value) VALUES (?, ?, 'collection', ?)
4276
4296
  ON CONFLICT(namespace, name, kind) DO UPDATE SET value = excluded.value`).run(this.namespace, this.collectionName, next);
4277
4297
  return next;
4278
4298
  }
@@ -4280,13 +4300,13 @@ var Collection = class {
4280
4300
  return this.sqlite.transaction(() => this.bumpCollectionSeq());
4281
4301
  }
4282
4302
  get(id) {
4283
- const row = this.sqlite.prepare("SELECT value FROM emulators_records WHERE namespace = ? AND collection = ? AND id = ?").get(this.namespace, this.collectionName, id);
4303
+ const row = this.sqlite.prepare("SELECT value FROM emulates_records WHERE namespace = ? AND collection = ? AND id = ?").get(this.namespace, this.collectionName, id);
4284
4304
  if (!row)
4285
4305
  return void 0;
4286
4306
  return JSON.parse(row.value).value;
4287
4307
  }
4288
4308
  has(id) {
4289
- const row = this.sqlite.prepare("SELECT 1 AS ok FROM emulators_records WHERE namespace = ? AND collection = ? AND id = ?").get(this.namespace, this.collectionName, id);
4309
+ const row = this.sqlite.prepare("SELECT 1 AS ok FROM emulates_records WHERE namespace = ? AND collection = ? AND id = ?").get(this.namespace, this.collectionName, id);
4290
4310
  return row !== void 0;
4291
4311
  }
4292
4312
  /** Insert a new record, assigning it the next sequence number. */
@@ -4294,7 +4314,7 @@ var Collection = class {
4294
4314
  return this.sqlite.transaction(() => {
4295
4315
  const seq = this.bumpCollectionSeq();
4296
4316
  const stored = { seq, value };
4297
- this.sqlite.prepare(`INSERT INTO emulators_records (namespace, collection, id, seq, value)
4317
+ this.sqlite.prepare(`INSERT INTO emulates_records (namespace, collection, id, seq, value)
4298
4318
  VALUES (?, ?, ?, ?, ?)
4299
4319
  ON CONFLICT(namespace, collection, id) DO UPDATE SET seq = excluded.seq, value = excluded.value`).run(this.namespace, this.collectionName, id, seq, JSON.stringify(stored));
4300
4320
  return stored;
@@ -4303,25 +4323,25 @@ var Collection = class {
4303
4323
  /** Replace an existing record's value, keeping its position. */
4304
4324
  update(id, value) {
4305
4325
  return this.sqlite.transaction(() => {
4306
- const row = this.sqlite.prepare("SELECT seq, value FROM emulators_records WHERE namespace = ? AND collection = ? AND id = ?").get(this.namespace, this.collectionName, id);
4326
+ const row = this.sqlite.prepare("SELECT seq, value FROM emulates_records WHERE namespace = ? AND collection = ? AND id = ?").get(this.namespace, this.collectionName, id);
4307
4327
  if (!row)
4308
4328
  return void 0;
4309
4329
  const stored = { seq: row.seq, value };
4310
- this.sqlite.prepare("UPDATE emulators_records SET value = ? WHERE namespace = ? AND collection = ? AND id = ?").run(JSON.stringify(stored), this.namespace, this.collectionName, id);
4330
+ this.sqlite.prepare("UPDATE emulates_records SET value = ? WHERE namespace = ? AND collection = ? AND id = ?").run(JSON.stringify(stored), this.namespace, this.collectionName, id);
4311
4331
  return stored;
4312
4332
  });
4313
4333
  }
4314
4334
  delete(id) {
4315
- const result = this.sqlite.prepare("DELETE FROM emulators_records WHERE namespace = ? AND collection = ? AND id = ?").run(this.namespace, this.collectionName, id);
4335
+ const result = this.sqlite.prepare("DELETE FROM emulates_records WHERE namespace = ? AND collection = ? AND id = ?").run(this.namespace, this.collectionName, id);
4316
4336
  return result.changes > 0;
4317
4337
  }
4318
4338
  /** How many records the collection holds, without reading them. */
4319
4339
  count() {
4320
- const row = this.sqlite.prepare("SELECT COUNT(*) AS n FROM emulators_records WHERE namespace = ? AND collection = ?").get(this.namespace, this.collectionName);
4340
+ const row = this.sqlite.prepare("SELECT COUNT(*) AS n FROM emulates_records WHERE namespace = ? AND collection = ?").get(this.namespace, this.collectionName);
4321
4341
  return Number(row?.n ?? 0);
4322
4342
  }
4323
4343
  list(options = {}) {
4324
- const rows = this.sqlite.prepare("SELECT id, seq, value FROM emulators_records WHERE namespace = ? AND collection = ?").all(this.namespace, this.collectionName);
4344
+ const rows = this.sqlite.prepare("SELECT id, seq, value FROM emulates_records WHERE namespace = ? AND collection = ?").all(this.namespace, this.collectionName);
4325
4345
  const out = [];
4326
4346
  for (const row of rows) {
4327
4347
  const stored = JSON.parse(row.value);
@@ -4370,9 +4390,9 @@ var IdSequence = class {
4370
4390
  }
4371
4391
  next(prefix, length = 14) {
4372
4392
  return this.sqlite.transaction(() => {
4373
- const row = this.sqlite.prepare("SELECT value FROM emulators_sequences WHERE namespace = ? AND name = ? AND kind = 'id'").get(this.namespace, prefix);
4393
+ const row = this.sqlite.prepare("SELECT value FROM emulates_sequences WHERE namespace = ? AND name = ? AND kind = 'id'").get(this.namespace, prefix);
4374
4394
  const value = (row?.value ?? 0) + 1;
4375
- this.sqlite.prepare(`INSERT INTO emulators_sequences (namespace, name, kind, value) VALUES (?, ?, 'id', ?)
4395
+ this.sqlite.prepare(`INSERT INTO emulates_sequences (namespace, name, kind, value) VALUES (?, ?, 'id', ?)
4376
4396
  ON CONFLICT(namespace, name, kind) DO UPDATE SET value = excluded.value`).run(this.namespace, prefix, value);
4377
4397
  return `${prefix}${opaqueToken(`${this.salt}:${prefix}:${value}`, length)}`;
4378
4398
  });
@@ -5215,7 +5235,7 @@ var json = (status, body) => new Response(JSON.stringify(body), {
5215
5235
  status,
5216
5236
  headers: { "content-type": "application/json; charset=utf-8" }
5217
5237
  });
5218
- var adminError = (status, message) => json(status, { error: { type: "emulators_admin", message } });
5238
+ var adminError = (status, message) => json(status, { error: { type: "emulates_admin", message } });
5219
5239
  var UNITS = {
5220
5240
  ms: 1,
5221
5241
  s: 1e3,
@@ -6087,18 +6107,18 @@ var adminUiRoutes = (service, ui, adminPrefix = ADMIN_PREFIX) => {
6087
6107
  // ../core/dist/snapshot.js
6088
6108
  var snapshotNamespace = (sqlite, namespace) => ({
6089
6109
  namespace,
6090
- records: sqlite.prepare("SELECT collection, id, seq, value FROM emulators_records WHERE namespace = ? ORDER BY collection, seq").all(namespace),
6091
- sequences: sqlite.prepare("SELECT name, kind, value FROM emulators_sequences WHERE namespace = ? ORDER BY name, kind").all(namespace)
6110
+ records: sqlite.prepare("SELECT collection, id, seq, value FROM emulates_records WHERE namespace = ? ORDER BY collection, seq").all(namespace),
6111
+ sequences: sqlite.prepare("SELECT name, kind, value FROM emulates_sequences WHERE namespace = ? ORDER BY name, kind").all(namespace)
6092
6112
  });
6093
6113
  var restoreNamespace = (sqlite, namespace, snapshot) => {
6094
6114
  sqlite.transaction(() => {
6095
- sqlite.prepare("DELETE FROM emulators_records WHERE namespace = ?").run(namespace);
6096
- sqlite.prepare("DELETE FROM emulators_sequences WHERE namespace = ?").run(namespace);
6097
- const record = sqlite.prepare("INSERT INTO emulators_records (namespace, collection, id, seq, value) VALUES (?, ?, ?, ?, ?)");
6115
+ sqlite.prepare("DELETE FROM emulates_records WHERE namespace = ?").run(namespace);
6116
+ sqlite.prepare("DELETE FROM emulates_sequences WHERE namespace = ?").run(namespace);
6117
+ const record = sqlite.prepare("INSERT INTO emulates_records (namespace, collection, id, seq, value) VALUES (?, ?, ?, ?, ?)");
6098
6118
  for (const row of snapshot.records) {
6099
6119
  record.run(namespace, row.collection, row.id, row.seq, row.value);
6100
6120
  }
6101
- const sequence = sqlite.prepare("INSERT INTO emulators_sequences (namespace, name, kind, value) VALUES (?, ?, ?, ?)");
6121
+ const sequence = sqlite.prepare("INSERT INTO emulates_sequences (namespace, name, kind, value) VALUES (?, ?, ?, ?)");
6102
6122
  for (const row of snapshot.sequences) {
6103
6123
  sequence.run(namespace, row.name, row.kind, row.value);
6104
6124
  }
@@ -6197,8 +6217,8 @@ var discoverCollections = (root) => {
6197
6217
  return found;
6198
6218
  };
6199
6219
  var storedNames = (sqlite, namespace) => {
6200
- const records = sqlite.prepare("SELECT DISTINCT collection AS name FROM emulators_records WHERE namespace = ?").all(namespace);
6201
- const sequences = sqlite.prepare("SELECT DISTINCT name FROM emulators_sequences WHERE namespace = ? AND kind = 'collection'").all(namespace);
6220
+ const records = sqlite.prepare("SELECT DISTINCT collection AS name FROM emulates_records WHERE namespace = ?").all(namespace);
6221
+ const sequences = sqlite.prepare("SELECT DISTINCT name FROM emulates_sequences WHERE namespace = ? AND kind = 'collection'").all(namespace);
6202
6222
  return [...records, ...sequences].map((row) => row.name);
6203
6223
  };
6204
6224
  var blankAccum = (name) => ({
@@ -6439,7 +6459,7 @@ var json3 = (status, body) => new Response(JSON.stringify(body), {
6439
6459
  status,
6440
6460
  headers: { "content-type": "application/json; charset=utf-8" }
6441
6461
  });
6442
- var adminError2 = (status, message) => json3(status, { error: { type: "emulators_admin", message } });
6462
+ var adminError2 = (status, message) => json3(status, { error: { type: "emulates_admin", message } });
6443
6463
  var fromResult = (result, status) => result.ok ? json3(status, result.value) : adminError2(result.status, result.message);
6444
6464
  var integerParam = (value) => {
6445
6465
  if (value === null)
@@ -6540,14 +6560,14 @@ var stateAdminRoutes = (routes) => {
6540
6560
  };
6541
6561
 
6542
6562
  // ../core/dist/version.js
6543
- var PACKAGE_VERSION = true ? "0.1.1" : UNRELEASED_VERSION;
6563
+ var PACKAGE_VERSION = true ? "1.0.0" : UNRELEASED_VERSION;
6544
6564
 
6545
6565
  // ../core/dist/webhooks.js
6546
6566
  var json4 = (status, body) => new Response(JSON.stringify(body), {
6547
6567
  status,
6548
6568
  headers: { "content-type": "application/json; charset=utf-8" }
6549
6569
  });
6550
- var adminError3 = (status, message) => json4(status, { error: { type: "emulators_admin", message } });
6570
+ var adminError3 = (status, message) => json4(status, { error: { type: "emulates_admin", message } });
6551
6571
  var isRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
6552
6572
  var parseEndpoint = (value) => {
6553
6573
  if (!isRecord4(value) || typeof value.url !== "string")
@@ -7149,7 +7169,7 @@ var createRuntime = (options) => {
7149
7169
  log(400);
7150
7170
  return stamp(new Response(JSON.stringify({
7151
7171
  error: {
7152
- type: "emulators_admin",
7172
+ type: "emulates_admin",
7153
7173
  message: `${NAMESPACE_HEADER} must match ${NAMESPACE_PATTERN}`
7154
7174
  }
7155
7175
  }), { status: 400, headers: { "content-type": "application/json; charset=utf-8" } }));
@@ -7315,7 +7335,7 @@ var adminJson = (status, body) => new Response(JSON.stringify(body), {
7315
7335
  status,
7316
7336
  headers: { "content-type": "application/json; charset=utf-8" }
7317
7337
  });
7318
- var adminFail = (status, message) => adminJson(status, { error: { type: "emulators_admin", message } });
7338
+ var adminFail = (status, message) => adminJson(status, { error: { type: "emulates_admin", message } });
7319
7339
  var isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
7320
7340
  var credentialRoutes = (registry) => ({
7321
7341
  "GET /credentials": () => adminJson(200, {
@@ -7517,4 +7537,4 @@ export {
7517
7537
  createRuntime2 as createRuntime,
7518
7538
  AcmAPI
7519
7539
  };
7520
- //# sourceMappingURL=chunk-H5GNI4YR.js.map
7540
+ //# sourceMappingURL=chunk-E5LEFT72.js.map