@tinycloud/cli 0.7.7 → 0.7.8

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.js CHANGED
@@ -5357,6 +5357,9 @@ var ErrorCodes = {
5357
5357
  // KV-specific errors
5358
5358
  KV_NOT_FOUND: "KV_NOT_FOUND",
5359
5359
  KV_WRITE_FAILED: "KV_WRITE_FAILED",
5360
+ KV_PRECONDITION_FAILED: "KV_PRECONDITION_FAILED",
5361
+ KV_CONFLICT: "KV_CONFLICT",
5362
+ KV_RESPONSE_TOO_LARGE: "KV_RESPONSE_TOO_LARGE",
5360
5363
  // SQL-specific errors
5361
5364
  SQL_ERROR: "SQL_ERROR",
5362
5365
  SQL_PERMISSION_DENIED: "SQL_PERMISSION_DENIED",
@@ -6303,7 +6306,7 @@ var KVService = class extends BaseService {
6303
6306
  * @param signal - Optional abort signal
6304
6307
  * @returns Fetch response
6305
6308
  */
6306
- async invokeOperation(path, action, body, signal) {
6309
+ async invokeOperation(path, action, body, signal, extraHeaders) {
6307
6310
  const session = this.context.session;
6308
6311
  const headers = this.context.invoke(
6309
6312
  session,
@@ -6311,9 +6314,10 @@ var KVService = class extends BaseService {
6311
6314
  path,
6312
6315
  action
6313
6316
  );
6317
+ const requestHeaders = Array.isArray(headers) ? [...headers, ...Object.entries(extraHeaders ?? {})] : { ...headers, ...extraHeaders };
6314
6318
  return this.context.fetch(`${this.host}/invoke`, {
6315
6319
  method: "POST",
6316
- headers,
6320
+ headers: requestHeaders,
6317
6321
  body,
6318
6322
  signal: this.combineSignals(signal)
6319
6323
  });
@@ -6495,13 +6499,21 @@ var KVService = class extends BaseService {
6495
6499
  if (!this.requireAuth()) {
6496
6500
  return err(authRequiredError("kv"));
6497
6501
  }
6502
+ if (options?.maxResponseBytes !== void 0 && (!Number.isSafeInteger(options.maxResponseBytes) || options.maxResponseBytes <= 0)) {
6503
+ return err(serviceError(
6504
+ ErrorCodes.INVALID_INPUT,
6505
+ "KV maxResponseBytes must be a positive safe integer",
6506
+ "kv"
6507
+ ));
6508
+ }
6498
6509
  const path = this.getFullPath(key, options?.prefix);
6499
6510
  try {
6500
6511
  const response = await this.invokeOperation(
6501
6512
  path,
6502
6513
  KVAction.GET,
6503
6514
  void 0,
6504
- options?.signal
6515
+ options?.signal,
6516
+ options?.maxResponseBytes === void 0 ? void 0 : { "x-tinycloud-max-response-bytes": String(options.maxResponseBytes) }
6505
6517
  );
6506
6518
  if (!response.ok) {
6507
6519
  if (response.status === 401 || response.status === 403) {
@@ -6519,6 +6531,14 @@ var KVService = class extends BaseService {
6519
6531
  return this.classifyNotFound(response, key);
6520
6532
  }
6521
6533
  const errorText = await response.text();
6534
+ if (response.status === 413) {
6535
+ return err(serviceError(
6536
+ ErrorCodes.KV_RESPONSE_TOO_LARGE,
6537
+ `KV value at key "${key}" exceeds the requested response limit`,
6538
+ "kv",
6539
+ { meta: { status: response.status, statusText: response.statusText } }
6540
+ ));
6541
+ }
6522
6542
  return err(
6523
6543
  serviceError(
6524
6544
  ErrorCodes.NETWORK_ERROR,
@@ -6550,6 +6570,13 @@ var KVService = class extends BaseService {
6550
6570
  if (!this.requireAuth()) {
6551
6571
  return err(authRequiredError("kv"));
6552
6572
  }
6573
+ if (options?.ifMatch !== void 0 && options.ifNoneMatch !== void 0) {
6574
+ return err(serviceError(
6575
+ ErrorCodes.INVALID_INPUT,
6576
+ "KV put cannot combine ifMatch and ifNoneMatch",
6577
+ "kv"
6578
+ ));
6579
+ }
6553
6580
  const path = this.getFullPath(key, options?.prefix);
6554
6581
  const body = this.serializePutValue(value, options?.contentType);
6555
6582
  try {
@@ -6557,7 +6584,11 @@ var KVService = class extends BaseService {
6557
6584
  path,
6558
6585
  KVAction.PUT,
6559
6586
  body,
6560
- options?.signal
6587
+ options?.signal,
6588
+ {
6589
+ ...options?.ifMatch === void 0 ? {} : { "if-match": options.ifMatch },
6590
+ ...options?.ifNoneMatch === void 0 ? {} : { "if-none-match": options.ifNoneMatch }
6591
+ }
6561
6592
  );
6562
6593
  if (!response.ok) {
6563
6594
  if (response.status === 401) {
@@ -6570,6 +6601,22 @@ var KVService = class extends BaseService {
6570
6601
  }));
6571
6602
  }
6572
6603
  const errorText = await response.text();
6604
+ if (response.status === 412) {
6605
+ return err(serviceError(
6606
+ ErrorCodes.KV_PRECONDITION_FAILED,
6607
+ `KV precondition failed for key "${key}"`,
6608
+ "kv",
6609
+ { meta: { status: response.status, statusText: response.statusText } }
6610
+ ));
6611
+ }
6612
+ if (response.status === 503 && (options?.ifMatch !== void 0 || options?.ifNoneMatch !== void 0)) {
6613
+ return err(serviceError(
6614
+ ErrorCodes.KV_CONFLICT,
6615
+ `Concurrent KV update conflicted for key "${key}"`,
6616
+ "kv",
6617
+ { meta: { status: response.status, statusText: response.statusText } }
6618
+ ));
6619
+ }
6573
6620
  const quotaError = this.handleQuotaErrorResponse(
6574
6621
  response,
6575
6622
  errorText,
@@ -6705,6 +6752,13 @@ var KVService = class extends BaseService {
6705
6752
  if (!this.requireAuth()) {
6706
6753
  return err(authRequiredError("kv"));
6707
6754
  }
6755
+ if (options?.limit !== void 0 && (!Number.isInteger(options.limit) || options.limit < 1 || options.limit > 1e3)) {
6756
+ return err(serviceError(
6757
+ ErrorCodes.INVALID_INPUT,
6758
+ "KV list limit must be an integer from 1 through 1000",
6759
+ "kv"
6760
+ ));
6761
+ }
6708
6762
  let listPath = options?.prefix ?? this._config.prefix ?? "";
6709
6763
  if (options?.path) {
6710
6764
  listPath = listPath ? `${listPath}/${options.path}` : options.path;
@@ -6714,7 +6768,8 @@ var KVService = class extends BaseService {
6714
6768
  listPath,
6715
6769
  KVAction.LIST,
6716
6770
  void 0,
6717
- options?.signal
6771
+ options?.signal,
6772
+ options?.limit === void 0 ? void 0 : { "x-tinycloud-limit": String(options.limit) }
6718
6773
  );
6719
6774
  if (!response.ok) {
6720
6775
  if (response.status === 401) {
@@ -6744,7 +6799,10 @@ var KVService = class extends BaseService {
6744
6799
  (key) => key.startsWith(prefixWithSlash) ? key.slice(prefixWithSlash.length) : key
6745
6800
  );
6746
6801
  }
6747
- return ok({ keys });
6802
+ return ok({
6803
+ keys,
6804
+ ...response.headers.get("x-tinycloud-truncated") === null ? {} : { truncated: response.headers.get("x-tinycloud-truncated") === "true" }
6805
+ });
6748
6806
  } catch (error) {
6749
6807
  return err(wrapError2("kv", error));
6750
6808
  }
@@ -6764,7 +6822,8 @@ var KVService = class extends BaseService {
6764
6822
  path,
6765
6823
  KVAction.DELETE,
6766
6824
  void 0,
6767
- options?.signal
6825
+ options?.signal,
6826
+ options?.ifMatch === void 0 ? void 0 : { "if-match": options.ifMatch }
6768
6827
  );
6769
6828
  if (!response.ok) {
6770
6829
  if (response.status === 401) {
@@ -6780,6 +6839,22 @@ var KVService = class extends BaseService {
6780
6839
  return this.classifyNotFound(response, key);
6781
6840
  }
6782
6841
  const errorText = await response.text();
6842
+ if (response.status === 412) {
6843
+ return err(serviceError(
6844
+ ErrorCodes.KV_PRECONDITION_FAILED,
6845
+ `KV precondition failed for key "${key}"`,
6846
+ "kv",
6847
+ { meta: { status: response.status, statusText: response.statusText } }
6848
+ ));
6849
+ }
6850
+ if (response.status === 503 && options?.ifMatch !== void 0) {
6851
+ return err(serviceError(
6852
+ ErrorCodes.KV_CONFLICT,
6853
+ `Concurrent KV delete conflicted for key "${key}"`,
6854
+ "kv",
6855
+ { meta: { status: response.status, statusText: response.statusText } }
6856
+ ));
6857
+ }
6783
6858
  return err(
6784
6859
  serviceError(
6785
6860
  ErrorCodes.NETWORK_ERROR,
@@ -6789,7 +6864,10 @@ var KVService = class extends BaseService {
6789
6864
  )
6790
6865
  );
6791
6866
  }
6792
- return ok(void 0);
6867
+ return ok({
6868
+ data: void 0,
6869
+ headers: this.createResponseHeaders(response.headers)
6870
+ });
6793
6871
  } catch (error) {
6794
6872
  return err(wrapError2("kv", error));
6795
6873
  }
@@ -7095,10 +7173,17 @@ var SQLService = class extends BaseService {
7095
7173
  return err(authRequiredError("sql"));
7096
7174
  }
7097
7175
  try {
7176
+ const body = {
7177
+ action: "query",
7178
+ sql,
7179
+ params: serializeSqlValues(params ?? [])
7180
+ };
7181
+ if (options?.maxRows !== void 0) body.maxRows = options.maxRows;
7182
+ if (options?.maxBytes !== void 0) body.maxBytes = options.maxBytes;
7098
7183
  const response = await this.invokeSQL(
7099
7184
  dbName,
7100
7185
  this.actionForSql(sql, SQLAction.READ),
7101
- { action: "query", sql, params: params ?? [] },
7186
+ body,
7102
7187
  options?.signal
7103
7188
  );
7104
7189
  if (!response.ok) {
@@ -7120,7 +7205,7 @@ var SQLService = class extends BaseService {
7120
7205
  const body = {
7121
7206
  action: "execute",
7122
7207
  sql,
7123
- params: params ?? []
7208
+ params: serializeSqlValues(params ?? [])
7124
7209
  };
7125
7210
  if (options?.schema) {
7126
7211
  body.schema = options.schema;
@@ -7445,6 +7530,11 @@ function validateMigrationOptions(options) {
7445
7530
  }
7446
7531
  return null;
7447
7532
  }
7533
+ function serializeSqlValues(values) {
7534
+ return values.map(
7535
+ (value) => value instanceof Uint8Array ? Array.from(value) : value
7536
+ );
7537
+ }
7448
7538
  function migrationKey(namespace, id) {
7449
7539
  return `${encodeURIComponent(namespace)}:${encodeURIComponent(id)}`;
7450
7540
  }