Turns the li element and its contents into a template, and uses that to instantiate a view for each item in list.
\n"
+ },
+ {
+ "syntax": "Conditionally swaps the contents of the div by selecting one of the embedded templates based on the current value of conditionExpression.
\n"
+ },
+ {
+ "syntax": "",
+ "bold": [
+ "[ng-class]"
+ ],
+ "description": "
Binds the presence of css classes on the element to the truthiness of the associated map values. The right-hand side expression should return {class-name: true/false} map.
\n"
+ }
+ ],
+ "index": 1
+ },
+ {
+ "name": "Forms",
+ "description": "
import {FORM_DIRECTIVES} from 'angular2/angular2';
\n",
+ "items": [
+ {
+ "syntax": "
",
+ "bold": [
+ "[(ng-model)]"
+ ],
+ "description": "
Provides two-way data-binding, parsing and validation for form controls.
\n"
+ }
+ ],
+ "index": 2
+ },
+ {
+ "name": "Class decorators",
+ "description": "
import {Directive, ...} from 'angular2/angular2';
\n",
+ "items": [
+ {
+ "syntax": "@Component({...})\nclass MyComponent() {}",
+ "bold": [
+ "@Component({...})"
+ ],
+ "description": "
Declares that a class is a component and provides metadata about the component.
\n"
+ },
+ {
+ "syntax": "@Pipe({...})\nclass MyPipe() {}",
+ "bold": [
+ "@Pipe({...})"
+ ],
+ "description": "
Declares that a class is a pipe and provides metadata about the pipe.
\n"
+ },
+ {
+ "syntax": "@Injectable()\nclass MyService() {}",
+ "bold": [
+ "@Injectable()"
+ ],
+ "description": "
Declares that a class has dependencies that should be injected into the constructor when the dependency\ninjector is creating an instance of this class.
\n"
+ }
+ ],
+ "index": 3
+ },
+ {
+ "name": "Directive configuration",
+ "description": "
@Directive({ property1: value1, ... }) )
\n",
+ "items": [
+ {
+ "syntax": "selector: '.cool-button:not(a)'",
+ "bold": [
+ "selector:"
+ ],
+ "description": "
Specifies a css selector that identifies this directive within a template. Supported selectors include: element,\n[attribute], .class, and :not().
\n
Does not support parent-child relationship selectors.
\n"
+ },
+ {
+ "syntax": "providers: [MyService, provide(...)]",
+ "bold": [
+ "providers:"
+ ],
+ "description": "
Array of dependency injection providers for this directive and its children.
\n"
+ }
+ ],
+ "index": 4
+ },
+ {
+ "name": "Component configuration",
+ "description": "
@Component extends @Directive,\nso the @Directive configuration applies to components as well
\n",
+ "items": [
+ {
+ "syntax": "viewProviders: [MyService, provide(...)]",
+ "bold": [
+ "viewProviders:"
+ ],
+ "description": "
Array of dependency injection providers scoped to this component's view.
\n"
+ },
+ {
+ "syntax": "template: 'Hello {{name}}'\ntemplateUrl: 'my-component.html'",
+ "bold": [
+ "template:",
+ "templateUrl:"
+ ],
+ "description": "
Inline template / external template url of the component's view.
\n"
+ },
+ {
+ "syntax": "styles: ['.primary {color: red}']\nstyleUrls: ['my-component.css']",
+ "bold": [
+ "styles:",
+ "styleUrls:"
+ ],
+ "description": "
List of inline css styles / external stylesheet urls for styling component’s view.
\n"
+ },
+ {
+ "syntax": "directives: [MyDirective, MyComponent]",
+ "bold": [
+ "directives:"
+ ],
+ "description": "
List of directives used in the the component’s template.
\n"
+ },
+ {
+ "syntax": "pipes: [MyPipe, OtherPipe]",
+ "bold": [
+ "pipes:"
+ ],
+ "description": "
List of pipes used in the component's template.
\n"
+ }
+ ],
+ "index": 5
+ },
+ {
+ "name": "Class field decorators for directives and components",
+ "description": "
import {Input, ...} from 'angular2/angular2';
\n",
+ "items": [
+ {
+ "syntax": "@Input() myProperty;",
+ "bold": [
+ "@Input()"
+ ],
+ "description": "
Declares an input property that we can update via property binding, e.g.\n<my-cmp [my-property]="someExpression">
\n"
+ },
+ {
+ "syntax": "@Output() myEvent = new EventEmitter();",
+ "bold": [
+ "@Output()"
+ ],
+ "description": "
Declares an output property that fires events to which we can subscribe with an event binding, e.g. <my-cmp (my-event)="doSomething()">
\n"
+ },
+ {
+ "syntax": "@HostBinding('[class.valid]') isValid;",
+ "bold": [
+ "@HostBinding('[class.valid]')"
+ ],
+ "description": "
Binds a host element property (e.g. css class valid) to directive/component property (e.g. isValid)
\n"
+ },
+ {
+ "syntax": "@HostListener('click', ['$event']) onClick(e) {...}",
+ "bold": [
+ "@HostListener('click', ['$event'])"
+ ],
+ "description": "
Subscribes to a host element event (e.g. click) with a directive/component method (e.g., onClick), optionally passing an argument ($event)
\n"
+ },
+ {
+ "syntax": "@ContentChild(myPredicate) myChildComponent;",
+ "bold": [
+ "@ContentChild(myPredicate)"
+ ],
+ "description": "
Binds the first result of the component content query (myPredicate) to the myChildComponent property of the class.
\n"
+ },
+ {
+ "syntax": "@ContentChildren(myPredicate) myChildComponents;",
+ "bold": [
+ "@ContentChildren(myPredicate)"
+ ],
+ "description": "
Binds the results of the component content query (myPredicate) to the myChildComponents property of the class.
\n"
+ },
+ {
+ "syntax": "@ViewChild(myPredicate) myChildComponent;",
+ "bold": [
+ "@ViewChild(myPredicate)"
+ ],
+ "description": "
Binds the first result of the component view query (myPredicate) to the myChildComponent property of the class. Not available for directives.
\n"
+ },
+ {
+ "syntax": "@ViewChildren(myPredicate) myChildComponents;",
+ "bold": [
+ "@ViewChildren(myPredicate)"
+ ],
+ "description": "
Binds the results of the component view query (myPredicate) to the myChildComponents property of the class. Not available for directives.
\n"
+ }
+ ],
+ "index": 6
+ },
+ {
+ "name": "Directive and component change detection and lifecycle hooks",
+ "description": "
(implemented as class methods)
\n",
+ "items": [
+ {
+ "syntax": "constructor(myService: MyService, ...) { ... }",
+ "bold": [
+ "constructor(myService: MyService, ...)"
+ ],
+ "description": "
The class constructor is called before any other lifecycle hook. Use it to inject dependencies, but avoid any serious work here.
\n"
+ },
+ {
+ "syntax": "onChanges(changeRecord) { ... }",
+ "bold": [
+ "onChanges(changeRecord)"
+ ],
+ "description": "
Called after every change to input properties and before processing content or child views.
\n"
+ },
+ {
+ "syntax": "onInit() { ... }",
+ "bold": [
+ "onInit()"
+ ],
+ "description": "
Called after the constructor, initializing input properties, and the first call to onChanges.
\n"
+ },
+ {
+ "syntax": "doCheck() { ... }",
+ "bold": [
+ "doCheck()"
+ ],
+ "description": "
Called every time that the input properties of a component or a directive are checked. Use it to extend change detection by performing a custom check.
\n"
+ },
+ {
+ "syntax": "afterContentInit() { ... }",
+ "bold": [
+ "afterContentInit()"
+ ],
+ "description": "
Called after onInit when the component's or directive's content has been initialized.
\n"
+ },
+ {
+ "syntax": "afterContentChecked() { ... }",
+ "bold": [
+ "afterContentChecked()"
+ ],
+ "description": "
Called after every check of the component's or directive's content.
\n"
+ },
+ {
+ "syntax": "afterViewInit() { ... }",
+ "bold": [
+ "afterViewInit()"
+ ],
+ "description": "
Called after onContentInit when the component's view has been initialized. Applies to components only.
\n"
+ },
+ {
+ "syntax": "afterViewChecked() { ... }",
+ "bold": [
+ "afterViewChecked()"
+ ],
+ "description": "
Called after every check of the component's view. Applies to components only.
\n"
+ },
+ {
+ "syntax": "onDestroy() { ... }",
+ "bold": [
+ "onDestroy()"
+ ],
+ "description": "
Called once, before the instance is destroyed.
\n"
+ }
+ ],
+ "index": 6
+ },
+ {
+ "name": "Dependency injection configuration",
+ "description": "
import {provide} from 'angular2/angular2';
\n",
+ "items": [
+ {
+ "syntax": "provide(MyService, {useClass: MyMockService})",
+ "bold": [],
+ "description": "
provide|useClass\nSets or overrides the provider for MyService to the MyMockService class.
\n"
+ },
+ {
+ "syntax": "provide(MyService, {useFactory: myFactory})",
+ "bold": [],
+ "description": "
provide|useFactory\nSets or overrides the provider for MyService to the myFactory factory function.
\n"
+ },
+ {
+ "syntax": "provide(MyValue, {useValue: 41})",
+ "bold": [],
+ "description": "
provide|useValue\nSets or overrides the provider for MyValue to the value 41.
\n"
+ }
+ ],
+ "index": 7
+ },
+ {
+ "name": "Routing and navigation",
+ "description": "
import {RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, ...} from 'angular2/router';
\n",
+ "items": [
+ {
+ "syntax": "@RouteConfig([\n { path: '/:myParam', component: MyComponent, as: 'MyCmp' },\n { path: '/staticPath', component: ..., as: ...},\n { path: '/*wildCardParam', component: ..., as: ...}\n])\nclass MyComponent() {}",
+ "bold": [
+ "@RouteConfig"
+ ],
+ "description": "
Configures routes for the decorated component. Supports static, parameterized and wildcard routes.
\n"
+ },
+ {
+ "syntax": "
",
+ "bold": [
+ "router-outlet"
+ ],
+ "description": "
Marks the location to load the component of the active route.
\n"
+ },
+ {
+ "syntax": "
",
+ "bold": [
+ "[router-link]"
+ ],
+ "description": "Creates a link to a different view based on a route instruction consisting of a route name and optional parameters. The route name matches the as property of a configured route. Add the '/' prefix to navigate to a root route; add the './' prefix for a child route.
\n"
+ },
+ {
+ "syntax": "@CanActivate(() => { ... })class MyComponent() {}",
+ "bold": [
+ "@CanActivate"
+ ],
+ "description": "A component decorator defining a function that the router should call first to determine if it should activate this component. Should return a boolean or a promise.
\n"
+ },
+ {
+ "syntax": "onActivate(nextInstruction, prevInstruction) { ... }",
+ "bold": [
+ "onActivate"
+ ],
+ "description": "After navigating to a component, the router calls component's onActivate method (if defined).
\n"
+ },
+ {
+ "syntax": "canReuse(nextInstruction, prevInstruction) { ... }",
+ "bold": [
+ "canReuse"
+ ],
+ "description": "The router calls a component's canReuse method (if defined) to determine whether to reuse the instance or destroy it and create a new instance. Should return a boolean or a promise.
\n"
+ },
+ {
+ "syntax": "onReuse(nextInstruction, prevInstruction) { ... }",
+ "bold": [
+ "onReuse"
+ ],
+ "description": "The router calls the component's onReuse method (if defined) when it re-uses a component instance.
\n"
+ },
+ {
+ "syntax": "canDeactivate(nextInstruction, prevInstruction) { ... }",
+ "bold": [
+ "canDeactivate"
+ ],
+ "description": "The router calls the canDeactivate methods (if defined) of every component that would be removed after a navigation. The navigation proceeds if and only if all such methods return true or a promise that is resolved.
\n"
+ },
+ {
+ "syntax": "onDeactivate(nextInstruction, prevInstruction) { ... }",
+ "bold": [
+ "onDeactivate"
+ ],
+ "description": "Called before the directive is removed as the result of a route change. May return a promise that pauses removing the directive until the promise resolves.
\n"
+ }
+ ],
+ "index": 8
+ }
+]
\ No newline at end of file
diff --git a/tools/api-builder/angular.io-package/index.js b/tools/api-builder/angular.io-package/index.js
index f3f61d23c4..f3e8eb3529 100644
--- a/tools/api-builder/angular.io-package/index.js
+++ b/tools/api-builder/angular.io-package/index.js
@@ -2,12 +2,15 @@ var path = require('canonical-path');
var Package = require('dgeni').Package;
var basePackage = require('../docs-package');
var targetPackage = require('../target-package');
+var cheatsheetPackage = require('../cheatsheet-package');
var PROJECT_PATH = path.resolve(__dirname, "../../..");
var PUBLIC_PATH = path.resolve(PROJECT_PATH, 'public');
var DOCS_PATH = path.resolve(PUBLIC_PATH, 'docs');
+var ANGULAR2_DOCS_PATH = path.resolve(__dirname, '../../../../angular/modules/angular2/docs');
-module.exports = new Package('angular.io', [basePackage, targetPackage])
+
+module.exports = new Package('angular.io', [basePackage, targetPackage, cheatsheetPackage])
.factory(require('./services/renderMarkdown'))
.processor(require('./processors/addJadeDataDocsProcessor'))
@@ -41,6 +44,11 @@ module.exports = new Package('angular.io', [basePackage, targetPackage])
readTypeScriptModules.hidePrivateMembers = true;
readFilesProcessor.basePath = DOCS_PATH;
+ readFilesProcessor.sourceFiles = [{
+ basePath: ANGULAR2_DOCS_PATH,
+ include: path.resolve(ANGULAR2_DOCS_PATH, 'cheatsheet/*.md')
+ }];
+
writeFilesProcessor.outputFolder = 'js/latest/api';
})
@@ -51,7 +59,6 @@ module.exports = new Package('angular.io', [basePackage, targetPackage])
.config(function(readFilesProcessor, generateNavigationDoc, createOverviewDump) {
// Clear out unwanted processors
- readFilesProcessor.$enabled = false;
generateNavigationDoc.$enabled = false;
createOverviewDump.$enabled = false;
})
diff --git a/tools/api-builder/angular.io-package/templates/cheatsheet.template.html b/tools/api-builder/angular.io-package/templates/cheatsheet.template.html
new file mode 100644
index 0000000000..8a955a2529
--- /dev/null
+++ b/tools/api-builder/angular.io-package/templates/cheatsheet.template.html
@@ -0,0 +1 @@
+{$ doc.sections | json $}
\ No newline at end of file
diff --git a/tools/api-builder/cheatsheet-package/index.js b/tools/api-builder/cheatsheet-package/index.js
new file mode 100644
index 0000000000..ad016ae602
--- /dev/null
+++ b/tools/api-builder/cheatsheet-package/index.js
@@ -0,0 +1,10 @@
+var Package = require('dgeni').Package;
+
+module.exports = new Package('cheatsheet', [require('../content-package')])
+
+.factory(require('./services/cheatsheetItemParser'))
+.processor(require('./processors/createCheatsheetDoc'))
+
+.config(function(parseTagsProcessor, getInjectables) {
+ parseTagsProcessor.tagDefinitions = parseTagsProcessor.tagDefinitions.concat(getInjectables(require('./tag-defs')));
+});
diff --git a/tools/api-builder/cheatsheet-package/mocks/mockPackage.js b/tools/api-builder/cheatsheet-package/mocks/mockPackage.js
new file mode 100644
index 0000000000..016278501a
--- /dev/null
+++ b/tools/api-builder/cheatsheet-package/mocks/mockPackage.js
@@ -0,0 +1,9 @@
+var Package = require('dgeni').Package;
+
+module.exports = function mockPackage() {
+
+ return new Package('mockPackage', [require('../'), require('dgeni-packages/nunjucks')])
+
+ // provide a mock log service
+ .factory('log', function() { return require('dgeni/lib/mocks/log')(false); });
+};
diff --git a/tools/api-builder/cheatsheet-package/processors/createCheatsheetDoc.js b/tools/api-builder/cheatsheet-package/processors/createCheatsheetDoc.js
new file mode 100644
index 0000000000..6a575103a1
--- /dev/null
+++ b/tools/api-builder/cheatsheet-package/processors/createCheatsheetDoc.js
@@ -0,0 +1,41 @@
+var _ = require('lodash');
+
+module.exports = function createCheatsheetDoc(createDocMessage, renderMarkdown) {
+ return {
+ $runAfter: ['processing-docs'],
+ $runBefore: ['docs-processed'],
+ $process: function(docs) {
+
+ var cheatsheetDoc = {
+ id: 'cheatsheet',
+ aliases: ['cheatsheet'],
+ docType: 'json-data',
+ sections: []
+ };
+
+ docs = docs.filter(function(doc) {
+ if (doc.docType === 'cheatsheet-section') {
+ var section = _.pick(doc, ['name', 'description', 'items', 'index']);
+
+ // Let's make sure that the descriptions are rendered as markdown
+ section.description = renderMarkdown(section.description);
+ section.items.forEach(function(item) {
+ item.description = renderMarkdown(item.description);
+ });
+
+
+ cheatsheetDoc.sections.push(section);
+ return false;
+ }
+ return true;
+ });
+
+ // Sort the sections by their index
+ cheatsheetDoc.sections.sort(function(a,b) { return a.index - b.index; });
+
+ docs.push(cheatsheetDoc);
+
+ return docs;
+ }
+ };
+};
\ No newline at end of file
diff --git a/tools/api-builder/cheatsheet-package/services/cheatsheetItemParser.js b/tools/api-builder/cheatsheet-package/services/cheatsheetItemParser.js
new file mode 100644
index 0000000000..76393a8b97
--- /dev/null
+++ b/tools/api-builder/cheatsheet-package/services/cheatsheetItemParser.js
@@ -0,0 +1,85 @@
+/**
+ * @dgService
+ * @description
+ * Parse the text from a cheatsheetItem tag into a cheatsheet item object
+ * The text must contain a syntax block followed by zero or more bold matchers and finally a description
+ * The syntax block and bold matchers must be wrapped in backticks and be separated by pipes.
+ * For example
+ *
+ * ```
+ * `
+ * ...
+ * ...
+ * ...
+ *
`|`[ng-switch]`|`[ng-switch-when]`|`ng-switch-when`|`ng-switch-default`
+ * Conditionally swaps the contents of the div by selecting one of the embedded templates based on the current value of conditionExpression.
+ * ```
+ *
+ * will be parsed into
+ *
+ * ```
+ * {
+ * syntax: '\n'+
+ * ' ...\n'+
+ * ' ...\n'+
+ * ' ...\n'+
+ * '
',
+ * bold: ['[ng-switch]', '[ng-switch-when]', 'ng-switch-when', 'ng-switch-default'],
+ * description: 'Conditionally swaps the contents of the div by selecting one of the embedded templates based on the current value of conditionExpression.'
+ * }
+ * ```
+ */
+module.exports = function cheatsheetItemParser() {
+
+ return function(text) {
+ var index = 0;
+ var item = {
+ syntax: '',
+ bold: [],
+ description: ''
+ };
+
+ var STATES = {
+ inSyntax: function() {
+ if (text.charAt(index) !== '`') throw new Error('item syntax must start with a backtick');
+ index += 1;
+ var syntaxStart = index;
+ while(index < text.length && text.charAt(index) !== '`') index++;
+ if (index === text.length) throw new Error('item syntax must end with a backtick');
+ item.syntax = text.substring(syntaxStart, index);
+ state = STATES.pipe;
+ index++;
+ },
+ pipe: function() {
+ if (text.charAt(index) === '|') {
+ index++;
+ while(index < text.length && /\s/.test(text.charAt(index))) index++;
+ state = STATES.bold;
+ } else {
+ state = STATES.description;
+ }
+ },
+ bold: function() {
+ if (text.charAt(index) !== '`') throw new Error('bold matcher must start with a backtick');
+ index += 1;
+ var boldStart = index;
+ while(index < text.length && text.charAt(index) !== '`') index++;
+ if (index === text.length) throw new Error('bold matcher must end with a backtick');
+ item.bold.push(text.substring(boldStart, index));
+ state = STATES.pipe;
+ index++;
+ },
+ description: function() {
+ item.description = text.substring(index);
+ state = null;
+ }
+ };
+
+ var state = STATES.inSyntax;
+ while(state) {
+ state();
+ }
+
+ return item;
+ };
+}
\ No newline at end of file
diff --git a/tools/api-builder/cheatsheet-package/services/cheatsheetItemParser.spec.js b/tools/api-builder/cheatsheet-package/services/cheatsheetItemParser.spec.js
new file mode 100644
index 0000000000..9b3ec227fe
--- /dev/null
+++ b/tools/api-builder/cheatsheet-package/services/cheatsheetItemParser.spec.js
@@ -0,0 +1,52 @@
+var mockPackage = require('../mocks/mockPackage');
+var Dgeni = require('dgeni');
+
+describe('cheatsheetItemParser', function() {
+ var dgeni, injector, cheatsheetItemParser;
+
+ beforeEach(function() {
+ dgeni = new Dgeni([mockPackage()]);
+ injector = dgeni.configureInjector();
+ cheatsheetItemParser = injector.get('cheatsheetItemParser');
+ });
+
+ it('should extract the syntax', function() {
+ expect(cheatsheetItemParser('`abc`')).toEqual({
+ syntax: 'abc',
+ bold: [],
+ description: ''
+ });
+ });
+
+ it('should extract the bolds', function() {
+ expect(cheatsheetItemParser('`abc`|`bold1`|`bold2`')).toEqual({
+ syntax: 'abc',
+ bold: ['bold1', 'bold2'],
+ description: ''
+ });
+ });
+
+ it('should extract the description', function() {
+ expect(cheatsheetItemParser('`abc`|`bold1`|`bold2`some description')).toEqual({
+ syntax: 'abc',
+ bold: ['bold1', 'bold2'],
+ description: 'some description'
+ });
+ });
+
+ it('should allow bold to be optional', function() {
+ expect(cheatsheetItemParser('`abc`some description')).toEqual({
+ syntax: 'abc',
+ bold: [],
+ description: 'some description'
+ });
+ });
+
+ it('should allow whitespace between the parts', function() {
+ expect(cheatsheetItemParser('`abc`| `bold1`| `bold2`\n\nsome description')).toEqual({
+ syntax: 'abc',
+ bold: ['bold1', 'bold2'],
+ description: '\n\nsome description'
+ });
+ })
+});
\ No newline at end of file
diff --git a/tools/api-builder/cheatsheet-package/tag-defs/cheatsheet-index.js b/tools/api-builder/cheatsheet-package/tag-defs/cheatsheet-index.js
new file mode 100644
index 0000000000..8deebb4905
--- /dev/null
+++ b/tools/api-builder/cheatsheet-package/tag-defs/cheatsheet-index.js
@@ -0,0 +1,13 @@
+module.exports = function(createDocMessage) {
+ return {
+ name: 'cheatsheetIndex',
+ docProperty: 'index',
+ transforms: function(doc, tag, value) {
+ try {
+ return parseInt(value, 10);
+ } catch(x) {
+ throw new Error(createDocMessage('"@'+ tag.tagName +'" must be followed by a number', doc));
+ }
+ }
+ };
+};
\ No newline at end of file
diff --git a/tools/api-builder/cheatsheet-package/tag-defs/cheatsheet-item.js b/tools/api-builder/cheatsheet-package/tag-defs/cheatsheet-item.js
new file mode 100644
index 0000000000..34d9442a8e
--- /dev/null
+++ b/tools/api-builder/cheatsheet-package/tag-defs/cheatsheet-item.js
@@ -0,0 +1,14 @@
+module.exports = function(createDocMessage, cheatsheetItemParser) {
+ return {
+ name: 'cheatsheetItem',
+ multi: true,
+ docProperty: 'items',
+ transforms: function(doc, tag, value) {
+ try {
+ return cheatsheetItemParser(value);
+ } catch(x) {
+ throw new Error(createDocMessage('"@'+ tag.tagName +'" tag has an invalid format - ' + x.message, doc));
+ }
+ }
+ };
+};
\ No newline at end of file
diff --git a/tools/api-builder/cheatsheet-package/tag-defs/cheatsheet-section.js b/tools/api-builder/cheatsheet-package/tag-defs/cheatsheet-section.js
new file mode 100644
index 0000000000..62399a5cca
--- /dev/null
+++ b/tools/api-builder/cheatsheet-package/tag-defs/cheatsheet-section.js
@@ -0,0 +1,10 @@
+module.exports = function() {
+ return {
+ name: 'cheatsheetSection',
+ docProperty: 'docType',
+ transforms: function(doc, tag, value) {
+ doc.name = value ? value.trim() : '';
+ return 'cheatsheet-section';
+ }
+ };
+};
diff --git a/tools/api-builder/cheatsheet-package/tag-defs/index.js b/tools/api-builder/cheatsheet-package/tag-defs/index.js
new file mode 100644
index 0000000000..8ba3c5c6ab
--- /dev/null
+++ b/tools/api-builder/cheatsheet-package/tag-defs/index.js
@@ -0,0 +1,5 @@
+module.exports = [
+ require('./cheatsheet-section'),
+ require('./cheatsheet-index'),
+ require('./cheatsheet-item')
+];
\ No newline at end of file