Skip to content

Commit

Permalink
Prepare v9.0.0 (Catnip) release (#98)
Browse files Browse the repository at this point in the history
* Improve naming (rename apiKey to sdkKey)

* Remove deprecated type (ClientReadyState)

* Format code & clean up imports

* Bump version

* Exclude non-source files so they don't pollute autocompletion/intellisense

* Improve word choice in intellisense docs

* Sync intellisense docs with SDK reference
  • Loading branch information
adams85 authored Nov 24, 2023
1 parent d85b948 commit 988dbc3
Show file tree
Hide file tree
Showing 14 changed files with 73 additions and 92 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "configcat-common",
"version": "8.2.0",
"version": "9.0.0",
"description": "ConfigCat is a configuration as a service that lets you manage your features and configurations without actually deploying new code.",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down
8 changes: 4 additions & 4 deletions src/ConfigCatClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ export class ConfigCatClientCache {
getOrCreate(options: ConfigCatClientOptions, configCatKernel: IConfigCatKernel): [ConfigCatClient, boolean] {
let instance: ConfigCatClient | undefined;

const cachedInstance = this.instances[options.apiKey];
const cachedInstance = this.instances[options.sdkKey];
if (cachedInstance) {
const [weakRef] = cachedInstance;
instance = weakRef.deref();
Expand All @@ -196,7 +196,7 @@ export class ConfigCatClientCache {
const token = {};
instance = new ConfigCatClient(options, configCatKernel, token);
const weakRefCtor = isWeakRefAvailable() ? WeakRef : getWeakRefStub();
this.instances[options.apiKey] = [new weakRefCtor(instance), token];
this.instances[options.sdkKey] = [new weakRefCtor(instance), token];
return [instance, false];
}

Expand Down Expand Up @@ -310,7 +310,7 @@ export class ConfigCatClient implements IConfigCatClient {
this.hooks.emit("clientReady", ClientCacheState.HasLocalOverrideFlagDataOnly);
}

this.suppressFinalize = registerForFinalization(this, { sdkKey: options.apiKey, cacheToken, configService: this.configService, logger: options.logger });
this.suppressFinalize = registerForFinalization(this, { sdkKey: options.sdkKey, cacheToken, configService: this.configService, logger: options.logger });
}

private static finalize(data: IFinalizationData) {
Expand All @@ -337,7 +337,7 @@ export class ConfigCatClient implements IConfigCatClient {
options.logger.debug("dispose() called");

if (this.cacheToken) {
clientInstanceCache.remove(options.apiKey, this.cacheToken);
clientInstanceCache.remove(options.sdkKey, this.cacheToken);
}

ConfigCatClient.close(this.configService, options.logger, this.hooks);
Expand Down
26 changes: 13 additions & 13 deletions src/ConfigCatClientOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export abstract class OptionsBase {

logger: LoggerWrapper;

apiKey: string;
sdkKey: string;

clientVersion: string;

Expand All @@ -158,15 +158,15 @@ export abstract class OptionsBase {

hooks: SafeHooksWrapper;

constructor(apiKey: string, clientVersion: string, options?: IOptions | null,
constructor(sdkKey: string, clientVersion: string, options?: IOptions | null,
defaultCacheFactory?: ((options: OptionsBase) => IConfigCache) | null,
eventEmitterFactory?: (() => IEventEmitter) | null) {

if (!apiKey) {
throw new Error("Invalid 'apiKey' value");
if (!sdkKey) {
throw new Error("Invalid 'sdkKey' value");
}

this.apiKey = apiKey;
this.sdkKey = sdkKey;
this.clientVersion = clientVersion;
this.dataGovernance = options?.dataGovernance ?? DataGovernance.Global;

Expand Down Expand Up @@ -244,11 +244,11 @@ export abstract class OptionsBase {
}

getUrl(): string {
return this.baseUrl + "/configuration-files/" + this.apiKey + "/" + OptionsBase.configFileName + "?sdk=" + this.clientVersion;
return this.baseUrl + "/configuration-files/" + this.sdkKey + "/" + OptionsBase.configFileName + "?sdk=" + this.clientVersion;
}

getCacheKey(): string {
return sha1(`${this.apiKey}_${OptionsBase.configFileName}_${ProjectConfig.serializationFormatVersion}`);
return sha1(`${this.sdkKey}_${OptionsBase.configFileName}_${ProjectConfig.serializationFormatVersion}`);
}
}

Expand All @@ -258,11 +258,11 @@ export class AutoPollOptions extends OptionsBase {

maxInitWaitTimeSeconds: number = 5;

constructor(apiKey: string, sdkType: string, sdkVersion: string, options?: IAutoPollOptions | null,
constructor(sdkKey: string, sdkType: string, sdkVersion: string, options?: IAutoPollOptions | null,
defaultCacheFactory?: ((options: OptionsBase) => IConfigCache) | null,
eventEmitterFactory?: (() => IEventEmitter) | null) {

super(apiKey, sdkType + "/a-" + sdkVersion, options, defaultCacheFactory, eventEmitterFactory);
super(sdkKey, sdkType + "/a-" + sdkVersion, options, defaultCacheFactory, eventEmitterFactory);

if (options) {

Expand Down Expand Up @@ -290,23 +290,23 @@ export class AutoPollOptions extends OptionsBase {
}

export class ManualPollOptions extends OptionsBase {
constructor(apiKey: string, sdkType: string, sdkVersion: string, options?: IManualPollOptions | null,
constructor(sdkKey: string, sdkType: string, sdkVersion: string, options?: IManualPollOptions | null,
defaultCacheFactory?: ((options: OptionsBase) => IConfigCache) | null,
eventEmitterFactory?: (() => IEventEmitter) | null) {

super(apiKey, sdkType + "/m-" + sdkVersion, options, defaultCacheFactory, eventEmitterFactory);
super(sdkKey, sdkType + "/m-" + sdkVersion, options, defaultCacheFactory, eventEmitterFactory);
}
}

export class LazyLoadOptions extends OptionsBase {

cacheTimeToLiveSeconds: number = 60;

constructor(apiKey: string, sdkType: string, sdkVersion: string, options?: ILazyLoadingOptions | null,
constructor(sdkKey: string, sdkType: string, sdkVersion: string, options?: ILazyLoadingOptions | null,
defaultCacheFactory?: ((options: OptionsBase) => IConfigCache) | null,
eventEmitterFactory?: (() => IEventEmitter) | null) {

super(apiKey, sdkType + "/l-" + sdkVersion, options, defaultCacheFactory, eventEmitterFactory);
super(sdkKey, sdkType + "/l-" + sdkVersion, options, defaultCacheFactory, eventEmitterFactory);

if (options) {
if (options.cacheTimeToLiveSeconds != null) {
Expand Down
14 changes: 1 addition & 13 deletions src/Hooks.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
import { ClientCacheState } from "./ConfigServiceBase";
import type { ClientCacheState } from "./ConfigServiceBase";
import type { IEventEmitter, IEventProvider } from "./EventEmitter";
import { NullEventEmitter } from "./EventEmitter";
import type { IConfig } from "./ProjectConfig";
import type { IEvaluationDetails } from "./RolloutEvaluator";

/**
* Contains the initialization state of `ConfigCatClient`.
* @deprecated This type is obsolete and will be removed from the public API in a future major version. Please use `ClientCacheState` instead.
*/
export type ClientReadyState = ClientCacheState;

/**
* @deprecated This type is obsolete and will be removed from the public API in a future major version. Please use `ClientCacheState` instead.
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
export const ClientReadyState = ClientCacheState;

/** Hooks (events) that can be emitted by `ConfigCatClient`. */
export type HookEvents = {
/** Occurs when the client is ready to provide the actual value of feature flags or settings. */
Expand Down
4 changes: 2 additions & 2 deletions src/RolloutEvaluator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -833,10 +833,10 @@ export interface IEvaluationDetails<TValue = SettingValue> {
/** The exception object related to the error in case evaluation failed (if any). */
errorException?: any;

/** The targeting rule which was used to select the evaluated value (if any). */
/** The targeting rule (if any) that matched during the evaluation and was used to return the evaluated value. */
matchedTargetingRule?: ITargetingRule;

/** The percentage option which was used to select the evaluated value (if any). */
/** The percentage option (if any) that was used to select the evaluated value. */
matchedPercentageOption?: IPercentageOption;
}

Expand Down
38 changes: 17 additions & 21 deletions src/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,32 @@ export class User {
/**
* Custom attributes of the user for advanced targeting rule definitions (e.g. user role, subscription type, etc.)
* @remarks
* The set of allowed attribute values depends on the comparison type of the condition which references the User Object attribute.
* `string` values are supported by all comparison types (in some cases they need to be provided in a specific format though).
* Some of the comparison types work with other types of values, as described below.
* All comparators support `string` values as User Object attribute (in some cases they need to be provided in a specific format though, see below),
* but some of them also support other types of values. It depends on the comparator how the values will be handled. The following rules apply:
*
* Text-based comparisons (EQUALS, IS ONE OF, etc.)<br/>
* * accept `string` values,<br/>
* * all other values are automatically converted to string (a warning will be logged but evaluation will continue as normal).
* **Text-based comparators** (EQUALS, IS ONE OF, etc.)
* * accept `string` values,
* * all other values are automatically converted to `string` (a warning will be logged but evaluation will continue as normal).
*
* SemVer-based comparisons (IS ONE OF, &lt;, &gt;=, etc.)<br/>
* * accept `string` values containing a properly formatted, valid semver value,<br/>
* **SemVer-based comparators** (IS ONE OF, &lt;, &gt;=, etc.)
* * accept `string` values containing a properly formatted, valid semver value,
* * all other values are considered invalid (a warning will be logged and the currently evaluated targeting rule will be skipped).
*
* Number-based comparisons (=, &lt;, &gt;=, etc.)<br/>
* * accept `number` values,<br/>
* * accept `string` values containing a properly formatted, valid `number` value,<br/>
* **Number-based comparators** (=, &lt;, &gt;=, etc.)
* * accept `number` values,
* * accept `string` values containing a properly formatted, valid `number` value,
* * all other values are considered invalid (a warning will be logged and the currently evaluated targeting rule will be skipped).
*
* Date time-based comparisons (BEFORE / AFTER)<br/>
* * accept `Date` values, which are automatically converted to a second-based Unix timestamp,<br/>
* * accept `number` values representing a second-based Unix timestamp,<br/>
* * accept `string` values containing a properly formatted, valid `number` value,<br/>
* **Date time-based comparators** (BEFORE / AFTER)
* * accept `Date` values, which are automatically converted to a second-based Unix timestamp,
* * accept `number` values representing a second-based Unix timestamp,
* * accept `string` values containing a properly formatted, valid `number` value,
* * all other values are considered invalid (a warning will be logged and the currently evaluated targeting rule will be skipped).
*
* String array-based comparisons (ARRAY CONTAINS ANY OF / ARRAY NOT CONTAINS ANY OF)<br/>
* * accept arrays of `string`,<br/>
* * accept `string` values containing a valid JSON string which can be deserialized to an array of `string`,<br/>
* **String array-based comparators** (ARRAY CONTAINS ANY OF / ARRAY NOT CONTAINS ANY OF)
* * accept arrays of `string`,
* * accept `string` values containing a valid JSON string which can be deserialized to an array of `string`,
* * all other values are considered invalid (a warning will be logged and the currently evaluated targeting rule will be skipped).
*
* In case a non-string attribute value needs to be converted to `string` during evaluation, it will always be done using the same format
* which is accepted by the comparisons.
**/
public custom: { [key: string]: UserAttributeValue } = {}
) {
Expand Down
2 changes: 0 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,3 @@ export { OverrideBehaviour } from "./FlagOverrides";
export { ClientCacheState, RefreshResult } from "./ConfigServiceBase";

export type { IProvidesHooks, HookEvents } from "./Hooks";

export { ClientReadyState } from "./Hooks";
18 changes: 9 additions & 9 deletions test/ConfigCatClientOptionsTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ describe("Options", () => {
assert.instanceOf(options.cache, InMemoryConfigCache);
});

it("ManualPollOptions initialization With 'apiKey' Should create an instance, defaults OK", () => {
it("ManualPollOptions initialization With 'sdkKey' Should create an instance, defaults OK", () => {
const options: ManualPollOptions = new ManualPollOptions("APIKEY", "common", "1.0.0", null, null);
assert.isDefined(options);

assert.equal("APIKEY", options.apiKey);
assert.equal("APIKEY", options.sdkKey);
assert.equal(30000, options.requestTimeoutMs);
assert.equal("https://cdn-global.configcat.com/configuration-files/APIKEY/config_v6.json?sdk=common/m-1.0.0", options.getUrl());
});
Expand All @@ -44,7 +44,7 @@ describe("Options", () => {

assert.isDefined(options);
assert.equal(fakeLogger, options.logger["logger"]);
assert.equal("APIKEY", options.apiKey);
assert.equal("APIKEY", options.sdkKey);
assert.equal(10, options.requestTimeoutMs);
assert.equal("https://cdn-global.configcat.com/configuration-files/APIKEY/config_v6.json?sdk=common/m-1.0.0", options.getUrl());
assert.equal("http://fake-proxy.com:8080", options.proxy);
Expand All @@ -65,12 +65,12 @@ describe("Options", () => {
}).to.throw("Invalid 'requestTimeoutMs' value");
});

it("AutoPollOptions initialization With 'apiKey' Should create an instance, defaults OK", () => {
it("AutoPollOptions initialization With 'sdkKey' Should create an instance, defaults OK", () => {
const options: AutoPollOptions = new AutoPollOptions("APIKEY", "common", "1.0.0", null, null);
assert.isDefined(options);
assert.isTrue(options.logger instanceof LoggerWrapper);
assert.isTrue(options.logger["logger"] instanceof ConfigCatConsoleLogger);
assert.equal("APIKEY", options.apiKey);
assert.equal("APIKEY", options.sdkKey);
assert.equal("https://cdn-global.configcat.com/configuration-files/APIKEY/config_v6.json?sdk=common/a-1.0.0", options.getUrl());
assert.equal(60, options.pollIntervalSeconds);
assert.equal(30000, options.requestTimeoutMs);
Expand All @@ -92,7 +92,7 @@ describe("Options", () => {

assert.isDefined(options);
assert.equal(fakeLogger, options.logger["logger"]);
assert.equal("APIKEY", options.apiKey);
assert.equal("APIKEY", options.sdkKey);
assert.equal("https://cdn-global.configcat.com/configuration-files/APIKEY/config_v6.json?sdk=common/a-1.0.0", options.getUrl());
assert.equal(59, options.pollIntervalSeconds);
assert.equal(20, options.requestTimeoutMs);
Expand Down Expand Up @@ -208,10 +208,10 @@ describe("Options", () => {
assert.equal(options.maxInitWaitTimeSeconds, 5);
});

it("LazyLoadOptions initialization With 'apiKey' Should create an instance, defaults OK", () => {
it("LazyLoadOptions initialization With 'sdkKey' Should create an instance, defaults OK", () => {
const options: LazyLoadOptions = new LazyLoadOptions("APIKEY", "common", "1.0.0", null, null);
assert.isDefined(options);
assert.equal("APIKEY", options.apiKey);
assert.equal("APIKEY", options.sdkKey);
assert.equal("https://cdn-global.configcat.com/configuration-files/APIKEY/config_v6.json?sdk=common/l-1.0.0", options.getUrl());
assert.equal(60, options.cacheTimeToLiveSeconds);
assert.equal(30000, options.requestTimeoutMs);
Expand All @@ -231,7 +231,7 @@ describe("Options", () => {

assert.isDefined(options);
assert.equal(fakeLogger, options.logger["logger"]);
assert.equal("APIKEY", options.apiKey);
assert.equal("APIKEY", options.sdkKey);
assert.equal("https://cdn-global.configcat.com/configuration-files/APIKEY/config_v6.json?sdk=common/l-1.0.0", options.getUrl());
assert.equal(59, options.cacheTimeToLiveSeconds);
assert.equal(20, options.requestTimeoutMs);
Expand Down
Loading

0 comments on commit 988dbc3

Please sign in to comment.