Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,15 @@ export class {{ service.name }}Client {
}
{%- endif %}

{%- if api.enableTelemetryTracing %}
opts.internalTelemetryInfo = {
gcpClientService: '{{ api.loggingName }}',
gcpClientVersion: '{{ api.naming.version }}',
gcpRepo: 'googleapis/google-cloud-node',
gcpArtifact: '{{ api.publishName }}',
}
{%- endif %}
Comment on lines +200 to +207

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Directly mutating the opts object passed to the constructor is unsafe and can lead to unexpected side-effects if the user reuses the options object across multiple clients. Additionally, since opts is optional (opts?: ClientOptions), attempting to set properties on it directly will throw a TypeError at runtime if the client is instantiated without options.

To prevent both issues, create a shallow copy of opts using Object.assign({}, opts) before assigning the telemetry info. This safely handles undefined (resulting in an empty object {}) and protects the user's original configuration from mutation.

    {%- if api.enableTelemetryTracing %}
      opts = Object.assign({}, opts);
      opts.internalTelemetryInfo = {
        gcpClientService: '{{ api.loggingName }}',
        gcpClientVersion: '{{ api.naming.version }}',
        gcpRepo: 'googleapis/google-cloud-node',
        gcpArtifact: '{{ api.publishName }}',
      };
    {%- endif %}


// Choose either gRPC or proto-over-HTTP implementation of google-gax.
this._gaxModule = {% if not api.legacyProtoLoad %}opts.fallback ? gaxInstance.fallback : gaxInstance{% else %}gax{% endif %};

Expand Down Expand Up @@ -398,6 +407,15 @@ export class {{ service.name }}Client {
, 'x-goog-api-version': '{{ service.apiVersion }}'
{%- endif -%}});

{%- if api.enableTelemetryTracing %}
if (opts.enableTelemetryTracing) {
for (const methodName of Object.keys(this._defaults)) {
this._defaults[methodName].enableTelemetryTracing = opts.enableTelemetryTracing;
this._defaults[methodName].internalTelemetryInfo = opts.internalTelemetryInfo;
}
}
{%- endif %}

// Set up a dictionary of "inner API calls"; the core implementation
// of calling the API is handled in `google-gax`, with this code
// merely providing the destination and request information.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,15 @@ export class {{ service.name }}Client {
gaxInstance = gax as typeof gax;
}
{%- endif %}

{%- if api.enableTelemetryTracing %}
opts.internalTelemetryInfo = {
gcpClientService: '{{ api.loggingName }}',
gcpClientVersion: '{{ api.naming.version }}',
gcpRepo: 'googleapis/google-cloud-node',
gcpArtifact: '{{ api.publishName }}',
}
{%- endif %}
Comment on lines +207 to +214

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Directly mutating the opts object passed to the constructor is unsafe and can lead to unexpected side-effects if the user reuses the options object across multiple clients. Additionally, since opts is optional (opts?: ClientOptions), attempting to set properties on it directly will throw a TypeError at runtime if the client is instantiated without options.

To prevent both issues, create a shallow copy of opts using Object.assign({}, opts) before assigning the telemetry info. This safely handles undefined (resulting in an empty object {}) and protects the user's original configuration from mutation.

    {%- if api.enableTelemetryTracing %}
      opts = Object.assign({}, opts);
      opts.internalTelemetryInfo = {
        gcpClientService: '{{ api.loggingName }}',
        gcpClientVersion: '{{ api.naming.version }}',
        gcpRepo: 'googleapis/google-cloud-node',
        gcpArtifact: '{{ api.publishName }}',
      };
    {%- endif %}


// Choose either gRPC or proto-over-HTTP implementation of google-gax.
this._gaxModule = {% if not api.legacyProtoLoad %}opts.fallback ? gaxInstance.fallback : gaxInstance{% else %}gax{% endif %};
Expand Down Expand Up @@ -409,6 +418,15 @@ export class {{ service.name }}Client {
, 'x-goog-api-version': '{{ service.apiVersion }}'
{%- endif %}});

{%- if api.enableTelemetryTracing %}
if (opts.enableTelemetryTracing) {
for (const methodName of Object.keys(this._defaults)) {
this._defaults[methodName].enableTelemetryTracing = opts.enableTelemetryTracing;
this._defaults[methodName].internalTelemetryInfo = opts.internalTelemetryInfo;
}
}
{%- endif %}

// Set up a dictionary of "inner API calls"; the core implementation
// of calling the API is handled in `google-gax`, with this code
// merely providing the destination and request information.
Expand Down
Loading