summaryrefslogtreecommitdiffstats
path: root/toolkit/components/normandy/actions/schemas
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--toolkit/components/normandy/actions/schemas/README.md13
-rw-r--r--toolkit/components/normandy/actions/schemas/export_json.js20
-rw-r--r--toolkit/components/normandy/actions/schemas/index.sys.mjs528
-rw-r--r--toolkit/components/normandy/actions/schemas/package.json11
4 files changed, 572 insertions, 0 deletions
diff --git a/toolkit/components/normandy/actions/schemas/README.md b/toolkit/components/normandy/actions/schemas/README.md
new file mode 100644
index 0000000000..06a7dd4b15
--- /dev/null
+++ b/toolkit/components/normandy/actions/schemas/README.md
@@ -0,0 +1,13 @@
+# Normandy Action Argument Schemas
+
+This is a collection of schemas describing the arguments expected by Normandy
+actions. Its primary purpose is to be used in the Normandy server and Delivery
+Console to validate data and provide better user interactions.
+
+# Contributing
+
+Modifications to this package are made as part of mozilla-central following
+standard procedures: push a patch to Phabricator as part of a bug.
+
+To release, bump the package version and land that, as above -- it can be part
+of another patch -- and then `cd` to this directory and `npm publish`.
diff --git a/toolkit/components/normandy/actions/schemas/export_json.js b/toolkit/components/normandy/actions/schemas/export_json.js
new file mode 100644
index 0000000000..940db247aa
--- /dev/null
+++ b/toolkit/components/normandy/actions/schemas/export_json.js
@@ -0,0 +1,20 @@
+#!/usr/bin/env node
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* eslint-env node */
+
+/**
+ * This script exports the schemas from this package in JSON format, for use by
+ * other tools. It is run as a part of the publishing process to NPM.
+ */
+
+const fs = require("fs");
+const schemas = require("./index.js");
+
+fs.writeFile("./schemas.json", JSON.stringify(schemas), err => {
+ if (err) {
+ console.error("error", err);
+ }
+});
diff --git a/toolkit/components/normandy/actions/schemas/index.sys.mjs b/toolkit/components/normandy/actions/schemas/index.sys.mjs
new file mode 100644
index 0000000000..7ef006e905
--- /dev/null
+++ b/toolkit/components/normandy/actions/schemas/index.sys.mjs
@@ -0,0 +1,528 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+export const ActionSchemas = {
+ "console-log": {
+ $schema: "http://json-schema.org/draft-04/schema#",
+ title: "Log a message to the console",
+ type: "object",
+ required: ["message"],
+ properties: {
+ message: {
+ description: "Message to log to the console",
+ type: "string",
+ default: "",
+ },
+ },
+ },
+
+ "messaging-experiment": {
+ $schema: "http://json-schema.org/draft-04/schema#",
+ title: "Messaging Experiment",
+ type: "object",
+ required: ["slug", "branches", "isEnrollmentPaused"],
+ properties: {
+ slug: {
+ description: "Unique identifier for this experiment",
+ type: "string",
+ pattern: "^[A-Za-z0-9\\-_]+$",
+ },
+ isEnrollmentPaused: {
+ description: "If true, new users will not be enrolled in the study.",
+ type: "boolean",
+ default: true,
+ },
+ branches: {
+ description: "List of experimental branches",
+ type: "array",
+ minItems: 1,
+ items: {
+ type: "object",
+ required: ["slug", "value", "ratio", "groups"],
+ properties: {
+ slug: {
+ description:
+ "Unique identifier for this branch of the experiment.",
+ type: "string",
+ pattern: "^[A-Za-z0-9\\-_]+$",
+ },
+ value: {
+ description: "Message content.",
+ type: "object",
+ properties: {},
+ },
+ ratio: {
+ description:
+ "Ratio of users who should be grouped into this branch.",
+ type: "integer",
+ minimum: 1,
+ },
+ groups: {
+ description:
+ "A list of experiment groups that can be used to exclude or select related experiments. May be empty.",
+ type: "array",
+ items: {
+ type: "string",
+ description: "Identifier of the group",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+
+ "preference-rollout": {
+ $schema: "http://json-schema.org/draft-04/schema#",
+ title: "Change preferences permanently",
+ type: "object",
+ required: ["slug", "preferences"],
+ properties: {
+ slug: {
+ description:
+ "Unique identifer for the rollout, used in telemetry and rollbacks",
+ type: "string",
+ pattern: "^[a-z0-9\\-_]+$",
+ },
+ preferences: {
+ description: "The preferences to change, and their values",
+ type: "array",
+ minItems: 1,
+ items: {
+ type: "object",
+ required: ["preferenceName", "value"],
+ properties: {
+ preferenceName: {
+ description: "Full dotted-path of the preference being changed",
+ type: "string",
+ },
+ value: {
+ description: "Value to set the preference to",
+ type: ["string", "integer", "boolean"],
+ },
+ },
+ },
+ },
+ },
+ },
+
+ "preference-rollback": {
+ $schema: "http://json-schema.org/draft-04/schema#",
+ title: "Undo a preference rollout",
+ type: "object",
+ required: ["rolloutSlug"],
+ properties: {
+ rolloutSlug: {
+ description: "Unique identifer for the rollout to undo",
+ type: "string",
+ pattern: "^[a-z0-9\\-_]+$",
+ },
+ },
+ },
+
+ "addon-study": {
+ $schema: "http://json-schema.org/draft-04/schema#",
+ title: "Enroll a user in an opt-out SHIELD study",
+ type: "object",
+ required: [
+ "name",
+ "description",
+ "addonUrl",
+ "extensionApiId",
+ "isEnrollmentPaused",
+ ],
+ properties: {
+ name: {
+ description: "User-facing name of the study",
+ type: "string",
+ minLength: 1,
+ },
+ description: {
+ description: "User-facing description of the study",
+ type: "string",
+ minLength: 1,
+ },
+ addonUrl: {
+ description: "URL of the add-on XPI file",
+ type: "string",
+ format: "uri",
+ minLength: 1,
+ },
+ extensionApiId: {
+ description:
+ "The record ID of the extension used for Normandy API calls.",
+ type: "integer",
+ },
+ isEnrollmentPaused: {
+ description: "If true, new users will not be enrolled in the study.",
+ type: "boolean",
+ default: true,
+ },
+ },
+ },
+
+ "addon-rollout": {
+ $schema: "http://json-schema.org/draft-04/schema#",
+ title: "Install add-on permanently",
+ type: "object",
+ required: ["extensionApiId", "slug"],
+ properties: {
+ extensionApiId: {
+ description:
+ "The record ID of the extension used for Normandy API calls.",
+ type: "integer",
+ },
+ slug: {
+ description:
+ "Unique identifer for the rollout, used in telemetry and rollbacks.",
+ type: "string",
+ pattern: "^[a-z0-9\\-_]+$",
+ },
+ },
+ },
+
+ "addon-rollback": {
+ $schema: "http://json-schema.org/draft-04/schema#",
+ title: "Undo an add-on rollout",
+ type: "object",
+ required: ["rolloutSlug"],
+ properties: {
+ rolloutSlug: {
+ description: "Unique identifer for the rollout to undo.",
+ type: "string",
+ pattern: "^[a-z0-9\\-_]+$",
+ },
+ },
+ },
+
+ "branched-addon-study": {
+ $schema: "http://json-schema.org/draft-04/schema#",
+ title: "Enroll a user in an add-on experiment, with managed branches",
+ type: "object",
+ required: [
+ "slug",
+ "userFacingName",
+ "userFacingDescription",
+ "branches",
+ "isEnrollmentPaused",
+ ],
+ properties: {
+ slug: {
+ description: "Machine-readable identifier",
+ type: "string",
+ minLength: 1,
+ },
+ userFacingName: {
+ description: "User-facing name of the study",
+ type: "string",
+ minLength: 1,
+ },
+ userFacingDescription: {
+ description: "User-facing description of the study",
+ type: "string",
+ minLength: 1,
+ },
+ isEnrollmentPaused: {
+ description: "If true, new users will not be enrolled in the study.",
+ type: "boolean",
+ default: true,
+ },
+ branches: {
+ description: "List of experimental branches",
+ type: "array",
+ minItems: 1,
+ items: {
+ type: "object",
+ required: ["slug", "ratio", "extensionApiId"],
+ properties: {
+ slug: {
+ description:
+ "Unique identifier for this branch of the experiment.",
+ type: "string",
+ pattern: "^[A-Za-z0-9\\-_]+$",
+ },
+ ratio: {
+ description:
+ "Ratio of users who should be grouped into this branch.",
+ type: "integer",
+ minimum: 1,
+ },
+ extensionApiId: {
+ description:
+ "The record ID of the add-on uploaded to the Normandy server. May be null, in which case no add-on will be installed.",
+ type: ["number", "null"],
+ default: null,
+ },
+ },
+ },
+ },
+ },
+ },
+
+ "show-heartbeat": {
+ $schema: "http://json-schema.org/draft-04/schema#",
+ title: "Show a Heartbeat survey.",
+ description: "This action shows a single survey.",
+
+ type: "object",
+ required: [
+ "surveyId",
+ "message",
+ "thanksMessage",
+ "postAnswerUrl",
+ "learnMoreMessage",
+ "learnMoreUrl",
+ ],
+ properties: {
+ repeatOption: {
+ type: "string",
+ enum: ["once", "xdays", "nag"],
+ description: "Determines how often a prompt is shown executes.",
+ default: "once",
+ },
+ repeatEvery: {
+ description:
+ "For repeatOption=xdays, how often (in days) the prompt is displayed.",
+ default: null,
+ type: ["number", "null"],
+ },
+ includeTelemetryUUID: {
+ type: "boolean",
+ description: "Include unique user ID in post-answer-url and Telemetry",
+ default: false,
+ },
+ surveyId: {
+ type: "string",
+ description: "Slug uniquely identifying this survey in telemetry",
+ },
+ message: {
+ description: "Message to show to the user",
+ type: "string",
+ },
+ engagementButtonLabel: {
+ description:
+ "Text for the engagement button. If specified, this button will be shown instead of rating stars.",
+ default: null,
+ type: ["string", "null"],
+ },
+ thanksMessage: {
+ description:
+ "Thanks message to show to the user after they've rated Firefox",
+ type: "string",
+ },
+ postAnswerUrl: {
+ description:
+ "URL to redirect the user to after rating Firefox or clicking the engagement button",
+ default: null,
+ type: ["string", "null"],
+ },
+ learnMoreMessage: {
+ description: "Message to show to the user to learn more",
+ default: null,
+ type: ["string", "null"],
+ },
+ learnMoreUrl: {
+ description: "URL to show to the user when they click Learn More",
+ default: null,
+ type: ["string", "null"],
+ },
+ },
+ },
+
+ "multi-preference-experiment": {
+ $schema: "http://json-schema.org/draft-04/schema#",
+ title: "Run a feature experiment activated by a set of preferences.",
+ type: "object",
+ required: [
+ "slug",
+ "userFacingName",
+ "userFacingDescription",
+ "branches",
+ "isEnrollmentPaused",
+ ],
+ properties: {
+ slug: {
+ description: "Unique identifier for this experiment",
+ type: "string",
+ pattern: "^[A-Za-z0-9\\-_]+$",
+ },
+ userFacingName: {
+ description: "User-facing name of the experiment",
+ type: "string",
+ minLength: 1,
+ },
+ userFacingDescription: {
+ description: "User-facing description of the experiment",
+ type: "string",
+ minLength: 1,
+ },
+ experimentDocumentUrl: {
+ description: "URL of a document describing the experiment",
+ type: "string",
+ format: "uri",
+ default: "",
+ },
+ isHighPopulation: {
+ description:
+ "Marks the preference experiment as a high population experiment, that should be excluded from certain types of telemetry",
+ type: "boolean",
+ default: "false",
+ },
+ isEnrollmentPaused: {
+ description: "If true, new users will not be enrolled in the study.",
+ type: "boolean",
+ default: true,
+ },
+ branches: {
+ description: "List of experimental branches",
+ type: "array",
+ minItems: 1,
+ items: {
+ type: "object",
+ required: ["slug", "ratio", "preferences"],
+ properties: {
+ slug: {
+ description:
+ "Unique identifier for this branch of the experiment",
+ type: "string",
+ pattern: "^[A-Za-z0-9\\-_]+$",
+ },
+ ratio: {
+ description:
+ "Ratio of users who should be grouped into this branch",
+ type: "integer",
+ minimum: 1,
+ },
+ preferences: {
+ description:
+ "The set of preferences to be set if this branch is chosen",
+ type: "object",
+ patternProperties: {
+ ".*": {
+ type: "object",
+ properties: {
+ preferenceType: {
+ description:
+ "Data type of the preference that controls this experiment",
+ type: "string",
+ enum: ["string", "integer", "boolean"],
+ },
+ preferenceBranchType: {
+ description:
+ "Controls whether the default or user value of the preference is modified",
+ type: "string",
+ enum: ["user", "default"],
+ default: "default",
+ },
+ preferenceValue: {
+ description:
+ "Value for this preference when this branch is chosen",
+ type: ["string", "number", "boolean"],
+ },
+ },
+ required: [
+ "preferenceType",
+ "preferenceBranchType",
+ "preferenceValue",
+ ],
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+
+ "single-preference-experiment": {
+ $schema: "http://json-schema.org/draft-04/schema#",
+ title: "Run a feature experiment activated by a preference.",
+ type: "object",
+ required: [
+ "slug",
+ "preferenceName",
+ "preferenceType",
+ "branches",
+ "isEnrollmentPaused",
+ ],
+ properties: {
+ slug: {
+ description: "Unique identifier for this experiment",
+ type: "string",
+ pattern: "^[A-Za-z0-9\\-_]+$",
+ },
+ experimentDocumentUrl: {
+ description: "URL of a document describing the experiment",
+ type: "string",
+ format: "uri",
+ default: "",
+ },
+ preferenceName: {
+ description:
+ "Full dotted-path of the preference that controls this experiment",
+ type: "string",
+ },
+ preferenceType: {
+ description:
+ "Data type of the preference that controls this experiment",
+ type: "string",
+ enum: ["string", "integer", "boolean"],
+ },
+ preferenceBranchType: {
+ description:
+ "Controls whether the default or user value of the preference is modified",
+ type: "string",
+ enum: ["user", "default"],
+ default: "default",
+ },
+ isHighPopulation: {
+ description:
+ "Marks the preference experiment as a high population experiment, that should be excluded from certain types of telemetry",
+ type: "boolean",
+ default: "false",
+ },
+ isEnrollmentPaused: {
+ description: "If true, new users will not be enrolled in the study.",
+ type: "boolean",
+ default: true,
+ },
+ branches: {
+ description: "List of experimental branches",
+ type: "array",
+ minItems: 1,
+ items: {
+ type: "object",
+ required: ["slug", "value", "ratio"],
+ properties: {
+ slug: {
+ description:
+ "Unique identifier for this branch of the experiment",
+ type: "string",
+ pattern: "^[A-Za-z0-9\\-_]+$",
+ },
+ value: {
+ description: "Value to set the preference to for this branch",
+ type: ["string", "number", "boolean"],
+ },
+ ratio: {
+ description:
+ "Ratio of users who should be grouped into this branch",
+ type: "integer",
+ minimum: 1,
+ },
+ },
+ },
+ },
+ },
+ },
+};
+
+// Legacy name used on Normandy server
+ActionSchemas["opt-out-study"] = ActionSchemas["addon-study"];
+
+// If running in Node.js, export the schemas.
+if (typeof module !== "undefined") {
+ /* globals module */
+ module.exports = ActionSchemas;
+}
diff --git a/toolkit/components/normandy/actions/schemas/package.json b/toolkit/components/normandy/actions/schemas/package.json
new file mode 100644
index 0000000000..f09031f88d
--- /dev/null
+++ b/toolkit/components/normandy/actions/schemas/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@mozilla/normandy-action-argument-schemas",
+ "version": "0.11.0",
+ "description": "Schemas for Normandy action arguments",
+ "main": "index.js",
+ "author": "Michael Cooper <mcooper@mozilla.com>",
+ "license": "MPL-2.0",
+ "scripts": {
+ "prepack": "node export_json.js"
+ }
+}