Skip to content

guest-types generates invalid code for non js-identifiers #624

Open
@mschuwalow

Description

@mschuwalow

This code generates a declare when the code is not a valid js identifier
https://github.com/bytecodealliance/jco/blob/main/crates/js-component-bindgen/src/ts_bindgen.rs#L859-L873

This is problematic for guest-types, as they already generate an enclosing declare module ... block. Using declare inside declare is not allowed by typescript.

An example output for wasi:keyvalue:

wit:

/// A keyvalue interface that provides eventually consistent CRUD operations.
/// 
/// A CRUD operation is an operation that acts on a single key-value pair.
/// 
/// The value in the key-value pair is defined as a `u8` byte array and the intention
/// is that it is the common denominator for all data types defined by different
/// key-value stores to handle data, ensuring compatibility between different
/// key-value stores. Note: the clients will be expecting serialization/deserialization overhead
/// to be handled by the key-value store. The value could be a serialized object from
/// JSON, HTML or vendor-specific data types like AWS S3 objects.
/// 
/// Data consistency in a key value store refers to the gaurantee that once a 
/// write operation completes, all subsequent read operations will return the
/// value that was written.
/// 
/// The level of consistency in readwrite interfaces is **eventual consistency**,
/// which means that if a write operation completes successfully, all subsequent
/// read operations will eventually return the value that was written. In other words,
/// if we pause the updates to the system, the system eventually will return 
/// the last updated value for read.
interface eventual {
	/// A keyvalue interface that provides simple read and write operations.
	use types.{bucket, error, incoming-value, key, outgoing-value};
	
	/// Get the value associated with the key in the bucket.
	/// 
	/// The value is returned as an option. If the key-value pair exists in the
	/// bucket, it returns `Ok(value)`. If the key does not exist in the
	/// bucket, it returns `Ok(none)`. 
	///
	/// If any other error occurs, it returns an `Err(error)`.
	get: func(bucket: borrow<bucket>, key: key) -> result<option<incoming-value>, error>;

	/// Set the value associated with the key in the bucket. If the key already
	/// exists in the bucket, it overwrites the value.
	///
	/// If the key does not exist in the bucket, it creates a new key-value pair.
	/// 
	/// If any other error occurs, it returns an `Err(error)`.
	set: func(bucket: borrow<bucket>, key: key, outgoing-value: borrow<outgoing-value>) -> result<_, error>;

	/// Delete the key-value pair associated with the key in the bucket.
	/// 
	/// If the key does not exist in the bucket, it does nothing.
	///
	/// If any other error occurs, it returns an `Err(error)`.
	delete: func(bucket: borrow<bucket>, key: key) -> result<_, error>;

	/// Check if the key exists in the bucket.
	/// 
	/// If the key exists in the bucket, it returns `Ok(true)`. If the key does
	/// not exist in the bucket, it returns `Ok(false)`.
	/// 
	/// If any other error occurs, it returns an `Err(error)`.
	exists: func(bucket: borrow<bucket>, key: key) -> result<bool, error>;
}

generated types

/// <reference path="./wasi-keyvalue-types.d.ts" />
declare module 'wasi:keyvalue/eventual@0.1.0' {
  /**
   * Get the value associated with the key in the bucket.
   * 
   * The value is returned as an option. If the key-value pair exists in the
   * bucket, it returns `Ok(value)`. If the key does not exist in the
   * bucket, it returns `Ok(none)`.
   * 
   * If any other error occurs, it returns an `Err(error)`.
   */
  export function get(bucket: Bucket, key: Key): IncomingValue | undefined;
  /**
   * Set the value associated with the key in the bucket. If the key already
   * exists in the bucket, it overwrites the value.
   * 
   * If the key does not exist in the bucket, it creates a new key-value pair.
   * 
   * If any other error occurs, it returns an `Err(error)`.
   */
  export function set(bucket: Bucket, key: Key, outgoingValue: OutgoingValue): void;
  /**
   * Delete the key-value pair associated with the key in the bucket.
   * 
   * If the key does not exist in the bucket, it does nothing.
   * 
   * If any other error occurs, it returns an `Err(error)`.
   */
  export { _delete as delete };
  declare function _delete(bucket: Bucket, key: Key): void; // this line is invalid
  /**
   * Check if the key exists in the bucket.
   * 
   * If the key exists in the bucket, it returns `Ok(true)`. If the key does
   * not exist in the bucket, it returns `Ok(false)`.
   * 
   * If any other error occurs, it returns an `Err(error)`.
   */
  export function exists(bucket: Bucket, key: Key): boolean;
  export type Bucket = import('wasi:keyvalue/types@0.1.0').Bucket;
  export type Error = import('wasi:keyvalue/types@0.1.0').Error;
  export type IncomingValue = import('wasi:keyvalue/types@0.1.0').IncomingValue;
  export type Key = import('wasi:keyvalue/types@0.1.0').Key;
  export type OutgoingValue = import('wasi:keyvalue/types@0.1.0').OutgoingValue;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    TypeScriptTypescript code/ecosystembugSomething isn't workinggenerated-typesRelated to generated types (Typescript)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions