@emulates/cloudcontrol 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/cloudcontrol
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/cloudcontrol
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
  Transport scaffold for Amazon Cloud Control API. ESM; Node 22+ or Bun 1.2+.
6
6
 
@@ -33,7 +33,7 @@ var CORE_MIGRATIONS = [
33
33
  {
34
34
  id: "20260322_core_records_sequences",
35
35
  sql: `
36
- CREATE TABLE IF NOT EXISTS emulators_records (
36
+ CREATE TABLE IF NOT EXISTS emulates_records (
37
37
  namespace TEXT NOT NULL,
38
38
  collection TEXT NOT NULL,
39
39
  id TEXT NOT NULL,
@@ -41,9 +41,9 @@ var CORE_MIGRATIONS = [
41
41
  value TEXT NOT NULL,
42
42
  PRIMARY KEY (namespace, collection, id)
43
43
  );
44
- CREATE INDEX IF NOT EXISTS emulators_records_seq
45
- ON emulators_records (namespace, collection, seq);
46
- CREATE TABLE IF NOT EXISTS emulators_sequences (
44
+ CREATE INDEX IF NOT EXISTS emulates_records_seq
45
+ ON emulates_records (namespace, collection, seq);
46
+ CREATE TABLE IF NOT EXISTS emulates_sequences (
47
47
  namespace TEXT NOT NULL,
48
48
  name TEXT NOT NULL,
49
49
  kind TEXT NOT NULL,
@@ -53,13 +53,33 @@ var CORE_MIGRATIONS = [
53
53
  `
54
54
  }
55
55
  ];
56
+ var LEGACY_TABLES = [
57
+ ["emulators_records", "emulates_records"],
58
+ ["emulators_sequences", "emulates_sequences"]
59
+ ];
60
+ var LEGACY_INDEXES = [["emulators_records_seq", "emulates_records_seq"]];
61
+ var namesOf = (sqlite, type) => new Set(sqlite.prepare("SELECT name FROM sqlite_master WHERE type = ?").all(type).map((row) => row.name));
56
62
  var migrateCore = (sqlite) => {
57
63
  migrate(sqlite, CORE_MIGRATIONS);
64
+ const tables = namesOf(sqlite, "table");
65
+ const indexes = namesOf(sqlite, "index");
66
+ sqlite.transaction(() => {
67
+ for (const [from, to] of LEGACY_TABLES) {
68
+ if (tables.has(from) && !tables.has(to))
69
+ sqlite.exec(`ALTER TABLE ${from} RENAME TO ${to}`);
70
+ }
71
+ for (const [from, to] of LEGACY_INDEXES) {
72
+ if (!indexes.has(from) || indexes.has(to))
73
+ continue;
74
+ sqlite.exec(`DROP INDEX ${from}`);
75
+ sqlite.exec(`CREATE INDEX ${to} ON emulates_records (namespace, collection, seq)`);
76
+ }
77
+ });
58
78
  };
59
79
  var clearNamespace = (sqlite, namespace) => {
60
80
  sqlite.transaction(() => {
61
- sqlite.prepare("DELETE FROM emulators_records WHERE namespace = ?").run(namespace);
62
- sqlite.prepare("DELETE FROM emulators_sequences WHERE namespace = ?").run(namespace);
81
+ sqlite.prepare("DELETE FROM emulates_records WHERE namespace = ?").run(namespace);
82
+ sqlite.prepare("DELETE FROM emulates_sequences WHERE namespace = ?").run(namespace);
63
83
  });
64
84
  };
65
85
 
@@ -4220,9 +4240,9 @@ var Collection = class {
4220
4240
  this.collectionName = collectionName;
4221
4241
  }
4222
4242
  bumpCollectionSeq() {
4223
- const row = this.sqlite.prepare("SELECT value FROM emulators_sequences WHERE namespace = ? AND name = ? AND kind = 'collection'").get(this.namespace, this.collectionName);
4243
+ const row = this.sqlite.prepare("SELECT value FROM emulates_sequences WHERE namespace = ? AND name = ? AND kind = 'collection'").get(this.namespace, this.collectionName);
4224
4244
  const next = (row?.value ?? 0) + 1;
4225
- this.sqlite.prepare(`INSERT INTO emulators_sequences (namespace, name, kind, value) VALUES (?, ?, 'collection', ?)
4245
+ this.sqlite.prepare(`INSERT INTO emulates_sequences (namespace, name, kind, value) VALUES (?, ?, 'collection', ?)
4226
4246
  ON CONFLICT(namespace, name, kind) DO UPDATE SET value = excluded.value`).run(this.namespace, this.collectionName, next);
4227
4247
  return next;
4228
4248
  }
@@ -4230,13 +4250,13 @@ var Collection = class {
4230
4250
  return this.sqlite.transaction(() => this.bumpCollectionSeq());
4231
4251
  }
4232
4252
  get(id) {
4233
- const row = this.sqlite.prepare("SELECT value FROM emulators_records WHERE namespace = ? AND collection = ? AND id = ?").get(this.namespace, this.collectionName, id);
4253
+ const row = this.sqlite.prepare("SELECT value FROM emulates_records WHERE namespace = ? AND collection = ? AND id = ?").get(this.namespace, this.collectionName, id);
4234
4254
  if (!row)
4235
4255
  return void 0;
4236
4256
  return JSON.parse(row.value).value;
4237
4257
  }
4238
4258
  has(id) {
4239
- const row = this.sqlite.prepare("SELECT 1 AS ok FROM emulators_records WHERE namespace = ? AND collection = ? AND id = ?").get(this.namespace, this.collectionName, id);
4259
+ const row = this.sqlite.prepare("SELECT 1 AS ok FROM emulates_records WHERE namespace = ? AND collection = ? AND id = ?").get(this.namespace, this.collectionName, id);
4240
4260
  return row !== void 0;
4241
4261
  }
4242
4262
  /** Insert a new record, assigning it the next sequence number. */
@@ -4244,7 +4264,7 @@ var Collection = class {
4244
4264
  return this.sqlite.transaction(() => {
4245
4265
  const seq = this.bumpCollectionSeq();
4246
4266
  const stored = { seq, value };
4247
- this.sqlite.prepare(`INSERT INTO emulators_records (namespace, collection, id, seq, value)
4267
+ this.sqlite.prepare(`INSERT INTO emulates_records (namespace, collection, id, seq, value)
4248
4268
  VALUES (?, ?, ?, ?, ?)
4249
4269
  ON CONFLICT(namespace, collection, id) DO UPDATE SET seq = excluded.seq, value = excluded.value`).run(this.namespace, this.collectionName, id, seq, JSON.stringify(stored));
4250
4270
  return stored;
@@ -4253,25 +4273,25 @@ var Collection = class {
4253
4273
  /** Replace an existing record's value, keeping its position. */
4254
4274
  update(id, value) {
4255
4275
  return this.sqlite.transaction(() => {
4256
- const row = this.sqlite.prepare("SELECT seq, value FROM emulators_records WHERE namespace = ? AND collection = ? AND id = ?").get(this.namespace, this.collectionName, id);
4276
+ const row = this.sqlite.prepare("SELECT seq, value FROM emulates_records WHERE namespace = ? AND collection = ? AND id = ?").get(this.namespace, this.collectionName, id);
4257
4277
  if (!row)
4258
4278
  return void 0;
4259
4279
  const stored = { seq: row.seq, value };
4260
- this.sqlite.prepare("UPDATE emulators_records SET value = ? WHERE namespace = ? AND collection = ? AND id = ?").run(JSON.stringify(stored), this.namespace, this.collectionName, id);
4280
+ this.sqlite.prepare("UPDATE emulates_records SET value = ? WHERE namespace = ? AND collection = ? AND id = ?").run(JSON.stringify(stored), this.namespace, this.collectionName, id);
4261
4281
  return stored;
4262
4282
  });
4263
4283
  }
4264
4284
  delete(id) {
4265
- const result = this.sqlite.prepare("DELETE FROM emulators_records WHERE namespace = ? AND collection = ? AND id = ?").run(this.namespace, this.collectionName, id);
4285
+ const result = this.sqlite.prepare("DELETE FROM emulates_records WHERE namespace = ? AND collection = ? AND id = ?").run(this.namespace, this.collectionName, id);
4266
4286
  return result.changes > 0;
4267
4287
  }
4268
4288
  /** How many records the collection holds, without reading them. */
4269
4289
  count() {
4270
- const row = this.sqlite.prepare("SELECT COUNT(*) AS n FROM emulators_records WHERE namespace = ? AND collection = ?").get(this.namespace, this.collectionName);
4290
+ const row = this.sqlite.prepare("SELECT COUNT(*) AS n FROM emulates_records WHERE namespace = ? AND collection = ?").get(this.namespace, this.collectionName);
4271
4291
  return Number(row?.n ?? 0);
4272
4292
  }
4273
4293
  list(options = {}) {
4274
- const rows = this.sqlite.prepare("SELECT id, seq, value FROM emulators_records WHERE namespace = ? AND collection = ?").all(this.namespace, this.collectionName);
4294
+ const rows = this.sqlite.prepare("SELECT id, seq, value FROM emulates_records WHERE namespace = ? AND collection = ?").all(this.namespace, this.collectionName);
4275
4295
  const out = [];
4276
4296
  for (const row of rows) {
4277
4297
  const stored = JSON.parse(row.value);
@@ -4320,9 +4340,9 @@ var IdSequence = class {
4320
4340
  }
4321
4341
  next(prefix, length = 14) {
4322
4342
  return this.sqlite.transaction(() => {
4323
- const row = this.sqlite.prepare("SELECT value FROM emulators_sequences WHERE namespace = ? AND name = ? AND kind = 'id'").get(this.namespace, prefix);
4343
+ const row = this.sqlite.prepare("SELECT value FROM emulates_sequences WHERE namespace = ? AND name = ? AND kind = 'id'").get(this.namespace, prefix);
4324
4344
  const value = (row?.value ?? 0) + 1;
4325
- this.sqlite.prepare(`INSERT INTO emulators_sequences (namespace, name, kind, value) VALUES (?, ?, 'id', ?)
4345
+ this.sqlite.prepare(`INSERT INTO emulates_sequences (namespace, name, kind, value) VALUES (?, ?, 'id', ?)
4326
4346
  ON CONFLICT(namespace, name, kind) DO UPDATE SET value = excluded.value`).run(this.namespace, prefix, value);
4327
4347
  return `${prefix}${opaqueToken(`${this.salt}:${prefix}:${value}`, length)}`;
4328
4348
  });
@@ -5159,7 +5179,7 @@ var json = (status, body) => new Response(JSON.stringify(body), {
5159
5179
  status,
5160
5180
  headers: { "content-type": "application/json; charset=utf-8" }
5161
5181
  });
5162
- var adminError = (status, message) => json(status, { error: { type: "emulators_admin", message } });
5182
+ var adminError = (status, message) => json(status, { error: { type: "emulates_admin", message } });
5163
5183
  var UNITS = {
5164
5184
  ms: 1,
5165
5185
  s: 1e3,
@@ -6031,18 +6051,18 @@ var adminUiRoutes = (service, ui, adminPrefix = ADMIN_PREFIX) => {
6031
6051
  // ../core/dist/snapshot.js
6032
6052
  var snapshotNamespace = (sqlite, namespace) => ({
6033
6053
  namespace,
6034
- records: sqlite.prepare("SELECT collection, id, seq, value FROM emulators_records WHERE namespace = ? ORDER BY collection, seq").all(namespace),
6035
- sequences: sqlite.prepare("SELECT name, kind, value FROM emulators_sequences WHERE namespace = ? ORDER BY name, kind").all(namespace)
6054
+ records: sqlite.prepare("SELECT collection, id, seq, value FROM emulates_records WHERE namespace = ? ORDER BY collection, seq").all(namespace),
6055
+ sequences: sqlite.prepare("SELECT name, kind, value FROM emulates_sequences WHERE namespace = ? ORDER BY name, kind").all(namespace)
6036
6056
  });
6037
6057
  var restoreNamespace = (sqlite, namespace, snapshot) => {
6038
6058
  sqlite.transaction(() => {
6039
- sqlite.prepare("DELETE FROM emulators_records WHERE namespace = ?").run(namespace);
6040
- sqlite.prepare("DELETE FROM emulators_sequences WHERE namespace = ?").run(namespace);
6041
- const record = sqlite.prepare("INSERT INTO emulators_records (namespace, collection, id, seq, value) VALUES (?, ?, ?, ?, ?)");
6059
+ sqlite.prepare("DELETE FROM emulates_records WHERE namespace = ?").run(namespace);
6060
+ sqlite.prepare("DELETE FROM emulates_sequences WHERE namespace = ?").run(namespace);
6061
+ const record = sqlite.prepare("INSERT INTO emulates_records (namespace, collection, id, seq, value) VALUES (?, ?, ?, ?, ?)");
6042
6062
  for (const row of snapshot.records) {
6043
6063
  record.run(namespace, row.collection, row.id, row.seq, row.value);
6044
6064
  }
6045
- const sequence = sqlite.prepare("INSERT INTO emulators_sequences (namespace, name, kind, value) VALUES (?, ?, ?, ?)");
6065
+ const sequence = sqlite.prepare("INSERT INTO emulates_sequences (namespace, name, kind, value) VALUES (?, ?, ?, ?)");
6046
6066
  for (const row of snapshot.sequences) {
6047
6067
  sequence.run(namespace, row.name, row.kind, row.value);
6048
6068
  }
@@ -6141,8 +6161,8 @@ var discoverCollections = (root) => {
6141
6161
  return found;
6142
6162
  };
6143
6163
  var storedNames = (sqlite, namespace) => {
6144
- const records = sqlite.prepare("SELECT DISTINCT collection AS name FROM emulators_records WHERE namespace = ?").all(namespace);
6145
- const sequences = sqlite.prepare("SELECT DISTINCT name FROM emulators_sequences WHERE namespace = ? AND kind = 'collection'").all(namespace);
6164
+ const records = sqlite.prepare("SELECT DISTINCT collection AS name FROM emulates_records WHERE namespace = ?").all(namespace);
6165
+ const sequences = sqlite.prepare("SELECT DISTINCT name FROM emulates_sequences WHERE namespace = ? AND kind = 'collection'").all(namespace);
6146
6166
  return [...records, ...sequences].map((row) => row.name);
6147
6167
  };
6148
6168
  var blankAccum = (name) => ({
@@ -6383,7 +6403,7 @@ var json3 = (status, body) => new Response(JSON.stringify(body), {
6383
6403
  status,
6384
6404
  headers: { "content-type": "application/json; charset=utf-8" }
6385
6405
  });
6386
- var adminError2 = (status, message) => json3(status, { error: { type: "emulators_admin", message } });
6406
+ var adminError2 = (status, message) => json3(status, { error: { type: "emulates_admin", message } });
6387
6407
  var fromResult = (result, status) => result.ok ? json3(status, result.value) : adminError2(result.status, result.message);
6388
6408
  var integerParam = (value) => {
6389
6409
  if (value === null)
@@ -6484,14 +6504,14 @@ var stateAdminRoutes = (routes) => {
6484
6504
  };
6485
6505
 
6486
6506
  // ../core/dist/version.js
6487
- var PACKAGE_VERSION = true ? "0.1.1" : UNRELEASED_VERSION;
6507
+ var PACKAGE_VERSION = true ? "1.0.0" : UNRELEASED_VERSION;
6488
6508
 
6489
6509
  // ../core/dist/webhooks.js
6490
6510
  var json4 = (status, body) => new Response(JSON.stringify(body), {
6491
6511
  status,
6492
6512
  headers: { "content-type": "application/json; charset=utf-8" }
6493
6513
  });
6494
- var adminError3 = (status, message) => json4(status, { error: { type: "emulators_admin", message } });
6514
+ var adminError3 = (status, message) => json4(status, { error: { type: "emulates_admin", message } });
6495
6515
  var isRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
6496
6516
  var parseEndpoint = (value) => {
6497
6517
  if (!isRecord4(value) || typeof value.url !== "string")
@@ -7093,7 +7113,7 @@ var createRuntime = (options) => {
7093
7113
  log(400);
7094
7114
  return stamp(new Response(JSON.stringify({
7095
7115
  error: {
7096
- type: "emulators_admin",
7116
+ type: "emulates_admin",
7097
7117
  message: `${NAMESPACE_HEADER} must match ${NAMESPACE_PATTERN}`
7098
7118
  }
7099
7119
  }), { status: 400, headers: { "content-type": "application/json; charset=utf-8" } }));
@@ -7259,7 +7279,7 @@ var adminJson = (status, body) => new Response(JSON.stringify(body), {
7259
7279
  status,
7260
7280
  headers: { "content-type": "application/json; charset=utf-8" }
7261
7281
  });
7262
- var adminFail = (status, message) => adminJson(status, { error: { type: "emulators_admin", message } });
7282
+ var adminFail = (status, message) => adminJson(status, { error: { type: "emulates_admin", message } });
7263
7283
  var isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
7264
7284
  var credentialRoutes = (registry) => ({
7265
7285
  "GET /credentials": () => adminJson(200, {
@@ -7371,4 +7391,4 @@ export {
7371
7391
  createRuntime2 as createRuntime,
7372
7392
  CloudcontrolAPI
7373
7393
  };
7374
- //# sourceMappingURL=chunk-NUJZDZXB.js.map
7394
+ //# sourceMappingURL=chunk-3UTVNUF3.js.map