Skip to content

Conversation

@akashrpo
Copy link
Contributor

🔒 Scanned for secrets using gitleaks 8.28.0

🔒 Scanned for secrets using gitleaks 8.28.0
@codecov
Copy link

codecov bot commented Dec 11, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 46.21%. Comparing base (6bf74c3) to head (0132715).
⚠️ Report is 9 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #317      +/-   ##
==========================================
+ Coverage   45.50%   46.21%   +0.71%     
==========================================
  Files         179      179              
  Lines       12881    12960      +79     
==========================================
+ Hits         5862     5990     +128     
+ Misses       6483     6432      -51     
- Partials      536      538       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

🔒 Scanned for secrets using gitleaks 8.28.0
@sonarqubecloud
Copy link

@akashrpo akashrpo changed the title chore: TypeScript Generation Specification chore: typeScript generation specification Dec 11, 2025
Comment on lines 820 to 829
**Screen Event:**

```typescript
export function screen(
name?: string,
properties?: ScreenProperties,
options?: ApiOptions,
callback?: apiCallback,
): void { ... }
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screen events are not supported by JS SDK. Instead, we support page events.

* The analytics instance should be available via window.rudderanalytics.
* You can install it by following instructions at: https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/installation/
*/
declare global {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's see if we can avoid global here and instead use the RudderAnalytics object exposed by the javascript SDK. That would probably require the Typer Analytics object to be defined with as a class with a constructor, and instantiated with new TyperAnalytics (or similar) after the new RudderAnalytics for the actual SDK.

What is the need for RudderAnalyticsPreloader?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@saikumarrs any idea what this RudderAnalyticsPreloader is about?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For CDN installations, the SDK loading snippet creates function stubs for tracking calls like track, page etc. where window.rudderanalytics just acts as a buffer for collecting all such function invocations until the SDK loads.
Once the SDK is loaded, it'll process all these buffered calls.

RudderAnalyticsPreloader represents the type of window.rudderanalytics when the SDK is not loaded yet.


| Source | Target | Convention | Example |
| ------------------ | -------------- | ------------------ | --------------------------------------- |
| Event `name` | Function name | camelCase | `"Some Track Event"` → `someTrackEvent` |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we stick to the Kotlin convention, where we start with the event type, followed by the event name in case of tracks. e.g:

identify(...)
trackSomeTrackEvent(...)

| Source | Target | Convention | Example |
| ------------------ | -------------- | ------------------ | --------------------------------------- |
| Event `name` | Function name | camelCase | `"Some Track Event"` → `someTrackEvent` |
| Event `name` | Interface name | PascalCase | `"Some Track Event"` → `SomeTrackEvent` |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For event rule types, let's also stick to the same convention as in Kotin. Interfaces start with the event type, followed by name in case of tracks, then followed by the identity section of that rule e.g:

IdentifyProperties
TrackSomeTrackEventProperties

**Output (index.ts):**

```typescript
export interface SomeTrackEvent {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a general guideline, for every property let's generate an interface or type for each property. e.g:

type PropertySomeString = string;

Then use that type in every place (rule of custom type) that property is used, e.g:

interface TrackSomeTrackEventProperties {
  someString?: PropertySomeString;
}

**Output (index.ts):**

```typescript
export enum Somestringwithenum_String {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specifically for enums, in order to avoid to S_ and N_ prefixes, can we considering listing the exact values in the type, e.g:

type Foo = 'GET' | 'POST' | '200' | 200;

**Output (index.ts):**

```typescript
export interface CustomTypeDefs {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's skip the wrapping CustomTypeDefs interface, as it doesn't represent any actual type. Let's instead generate interfaces (or types) with a CustomType prefix, e.g:

type CustomTypeSomeStringType = string;

the property using that would look like:

type PropertyCustomString = CustomTypeSomeStringType;

**Output (index.ts):**

```typescript
export interface SomeTrackEventSomeNestedLevel2 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, following Kotlin conventions, let's create a single type for objects with nested properties, e.g:

interface TrackSomeTrackEventProperties { // this is the type for the entire event rule
...
  someNestedObject: {
    someNestedLevel1?: {
      someNestedLevel2?: {
        someString?: string;
        someInteger?: number;
      }
    }
  }
...
}

This avoids name conflicts for any nested object, without overly complicated interface names. It also makes the type definition local to the event rule type definition, which is what is expected.


// Default case: any other someString value
export interface SomeVariantTypeDefault {
someString: string; // any string (catches all other values)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a good suggestion out of the box, but it would be nice to see if we can define a type for the discriminator in the default case, where it accepts everything but the values defined in the cases.

🔒 Scanned for secrets using gitleaks 8.28.0
🔒 Scanned for secrets using gitleaks 8.28.0
🔒 Scanned for secrets using gitleaks 8.28.0
🔒 Scanned for secrets using gitleaks 8.28.0
🔒 Scanned for secrets using gitleaks 8.28.0
@akashrpo akashrpo force-pushed the chore/rudder-typer-doc branch from 162cab1 to 83b1c54 Compare December 19, 2025 10:41
🔒 Scanned for secrets using gitleaks 8.28.0
@akashrpo akashrpo force-pushed the chore/rudder-typer-doc branch from 83b1c54 to 3425217 Compare December 19, 2025 10:43
🔒 Scanned for secrets using gitleaks 8.28.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants