Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
@kiwicom/darwin
Advanced tools
Our shiny new AB testing tool! :monkey:
yarn add @kiwicom/darwin
Download the test configuration file. On a request take:
config
objectuserAgent
xx-XX
The configuration object is either a JSON file or a JS object with the following structure:
// A single AB test
export type Test = {
name: string; // The test's name
value: string; // The value string
};
// One of AB test's treatment group configurations
export type Value = {
value: string; // The treatment group name
weight: number; // The relative traffic size of the treatment group
};
// Traffic group configuration
export type Traffic = {
userAgent?: string | null; // Pattern against which to compare the user-agent
languages?: string[] | null; // List of accpeted languages
affiliates?: string[] | null; // List of accepted affiliates
};
// Configuration of an AB test
export type TestConfig = {
name: string; // The AB test name
values: Value[]; // List of treatment group configurations
};
// Population group with an assigned AB test, or `null` for placeholder slot
export type Group = {
traffic?: Traffic; // The group's traffic configuration
tests: TestConfig[]; // The test configurations for this population group
};
// Feature configuration
export type Feature = {
traffic?: Traffic; // The feature's traffic configuration
name: string; // The feature's name
enabled: boolean; // Flag indicating whether the feature is enabled or not
};
// A record of enabled/disabled features
export type Features = Record<string, boolean>;
// The root configuration object
export type Config = {
features?: Feature[]; // The feature configuration
groups?: Group[]; // Population group configurations
winners?: Test[]; // Winning tests and their values
};
An example Traffic
object containing the English and Russian language, and is iPhone only, for
shrek
and donkey
affiliates:
{
"languages": ["en-US", "ru-RU"],
"userAgent": "iPhone",
"affiliates": ["shrek", "donkey"]
}
The language list is the 639-1
column here
.
Be sure to include the -XX
country postfix, as Kiwi.com recognizes different countries'
language variants.
For user agents, see this website. Pick a chunk of
the user agent you want and put it in the userAgent
field in the traffic object, like in the
example.
getTests
Feed the config
object function together with the userAgent
, language, affiliate and the salt:
import { Config, Test, getTest } from "@kiwicom/darwin";
import { Cookies } from "@kiwicom/cookies";
const config: Config = {
/* ... */
};
// Returns the group's name and the `Test` array, or
// `null` group name and empty array for no active test
const { group, tests } = getTests({
config,
userAgent: req.headers["User-Agent"], // optional
language: "en-GB", // optional
affiliate: "shrek", // optional
salt: "some-user-id-string", // length at least 10 for optimal results
savedGroup: req.cookies[Cookies.DARWIN_GROUP], // optional, saved group for the user
});
// optionally, save/remove test name from storage
if (group === null) {
// remove `group` from e.g. cookies
} else {
// save `group` to e.g. cookies
}
This object has no functions and thus is serializable — send it to the client encoded as JSON.
getFeatures
Feed the config
object function, optionally together with the userAgent
, language and affiliate:
import { Config, Features, getFeatures } from "@kiwicom/darwin";
const config: Config = {
/* ... */
};
const features: Features = getFeatures({
config,
userAgent: req.headers["User-Agent"], // optional
language: "en-GB", // optional
affiliate: "shrek", // optional
});
This object has no functions and thus is serializable — send it to the client encoded as JSON.
DarwinProvider
Server:
Use the tests
array in your provider:
import { DarwinProvider } from "@kiwicom/darwin";
// ...
return ReactDOMServer.renderToString(
<DarwinProvider tests={tests} features={features} winners={winners}>
<Root />
</DarwinProvider>,
);
Client:
Take the tests
and features
sent from the server and feed it to the provider.
Avoid sending the whole downloaded configuration file to the client to save bundle size and avoid leaking test information.
import { DarwinProvider } from "@kiwicom/darwin";
import { handleLogDarwin } from "src/logger";
const { tests, features, winners } = window.__DARWIN__;
// ...
ReactDOM.hydrate(
<DarwinProvider tests={tests} features={features} winners={winners} onTest={handleLogDarwin}>
<Root />
</DarwinProvider>,
document.getElementById("root"),
);
useTest
hookChecks if the queried test is running and returns its value, null
for reference group.
It also saves the queried test to session data if it returned a non-null
result.
import { useTest } from "@kiwicom/darwin";
const version = useTest("valdoge");
if (version === "g") {
// ...
}
You can then retrieve the session data with loadSession
;
useFeature
hookTells you if a feature is on / off.
import { useFeature } from "@kiwicom/darwin";
const hasNavbar = useFeature("navbar");
context
If you cannot use React's hook API, you can also access the context directly:
import { context as contextDarwin } from "@kiwicom/darwin";
class MyComponent extends Component {
static contextType = contextDarwin;
handleDarwin() {
// call these as you'd call the `useTest` and `useFeature` hooks
const { onTest, onFeature } = this.context;
}
}
loadSession
Loads the session test data, a Record<string, string>
of active
record names and values.
Only use on the client!
Useful mainly for logging.
import { loadSession } from "@kiwicom/darwin";
logger.log("Stuff has happened", {
abTests: loadSession(),
});
Use the @kiwicom/darwin/mock
module for testing purposes.
mockFormat
Appends the URL with specified testing parameters and returns the formatted URL search:
import { mockFormat } from "@kiwicom/darwin/mock";
window.location.search = mockFormat([{ name: "yolotest", value: "B" }]);
Takes an optional third parameter as the current URL search that defaults
to window.location.search
.
mockRetrieve
Retrieves mock tests from the URL search.
import { mockRetrieve } from "@kiwicom/darwin/mock";
const mockTests = mockRetrieve(url.search);
const { tests } = getTests({
/* ... */
});
const allTests = [...mockTests, ...tests];
mockFeatureFormat
Appends the URL with specified features and returns the formatted URL search:
import { mockFeatureFormat } from "@kiwicom/darwin/mock";
window.location.search = mockFeatureFormat({ navbar: true, footer: false });
Takes an optional second parameter as the current URL search that defaults
to window.location.search
.
mockFeatureRetrieve
Retrieves the mock features from the URL search. Merge the mock feature set with features from the config object:
import { mockFeatureRetrieve } from "@kiwicom/darwin/mock";
const features = {
...getFeatures({
/* ... */
}),
...mockFeatureRetrieve(url.search),
};
mockWinnersFormat
Appends the URL with specified test winners and returns the formatted URL search:
import { mockWinnersFormat } from "@kiwicom/darwin/mock";
window.location.search = mockWinnersFormat([{ name: "test", value: "off" }]);
Note that the function uses
__
for grouping test name and value. Please avoid using double-underscore in test names or values!
Takes an optional second parameter as the current URL search that defaults
to window.location.search
.
mockWinnersRetrieve
Retrieves the mock test winners from the URL search. Merge the test winners set with winners from the config object:
import { mockWinnersRetrieve } from "@kiwicom/darwin/mock";
const winners = [...config.winners, ...mockWinnersRetrieve(url.search)];
Clone and yarn
.
Follow @commitlint/conventional
with a mandatory scope of:
dev
for non-production things like CI or teststypes
for adjusting .js.flow
files or type signaturessrc
for library changes, features, patches...Examples:
docs(dev): document commits
feat(src): add new hook
chore(types): new spread syntax
yarn release
yarn publish
MIT
FAQs
AB testing tool 2.0. :monkey:
The npm package @kiwicom/darwin receives a total of 0 weekly downloads. As such, @kiwicom/darwin popularity was classified as not popular.
We found that @kiwicom/darwin demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 6 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.