diff --git a/types/chart.js/index.d.ts b/types/chart.js/index.d.ts index 854d4557ed..37f4757460 100644 --- a/types/chart.js/index.d.ts +++ b/types/chart.js/index.d.ts @@ -493,6 +493,7 @@ declare namespace Chart { fontSize?: number; fontStyle?: string; labelOffset?: number; + lineHeight?: number; max?: any; maxRotation?: number; maxTicksLimit?: number; @@ -503,6 +504,8 @@ declare namespace Chart { reverse?: boolean; showLabelBackdrop?: boolean; source?: 'auto' | 'data' | 'labels'; + suggestedMax?: number; + suggestedMin?: number; } interface AngleLineOptions { diff --git a/types/ember-data/adapter.d.ts b/types/ember-data/adapter.d.ts new file mode 100644 index 0000000000..62d133a007 --- /dev/null +++ b/types/ember-data/adapter.d.ts @@ -0,0 +1,3 @@ +import DS from 'ember-data'; +export default DS.Adapter; +export { AdapterRegistry } from 'ember-data'; diff --git a/types/ember-data/adapters/errors.d.ts b/types/ember-data/adapters/errors.d.ts new file mode 100644 index 0000000000..e2e60f7f69 --- /dev/null +++ b/types/ember-data/adapters/errors.d.ts @@ -0,0 +1,13 @@ +import DS from 'ember-data'; + +export const AdapterError: typeof DS.AdapterError; +export const InvalidError: typeof DS.InvalidError; +export const UnauthorizedError: typeof DS.UnauthorizedError; +export const ForbiddenError: typeof DS.ForbiddenError; +export const NotFoundError: typeof DS.NotFoundError; +export const ConflictError: typeof DS.ConflictError; +export const ServerError: typeof DS.ServerError; +export const TimeoutError: typeof DS.TimeoutError; +export const AbortError: typeof DS.AbortError; +export const errorsHashToArray: typeof DS.errorsHashToArray; +export const errorsArrayToHash: typeof DS.errorsArrayToHash; diff --git a/types/ember-data/adapters/json-api.d.ts b/types/ember-data/adapters/json-api.d.ts new file mode 100644 index 0000000000..4296b32eec --- /dev/null +++ b/types/ember-data/adapters/json-api.d.ts @@ -0,0 +1,2 @@ +import DS from 'ember-data'; +export default DS.JSONAPIAdapter; diff --git a/types/ember-data/adapters/rest.d.ts b/types/ember-data/adapters/rest.d.ts new file mode 100644 index 0000000000..c7dd3824ae --- /dev/null +++ b/types/ember-data/adapters/rest.d.ts @@ -0,0 +1,2 @@ +import DS from 'ember-data'; +export default DS.RESTAdapter; diff --git a/types/ember-data/attr.d.ts b/types/ember-data/attr.d.ts new file mode 100644 index 0000000000..2ecdea2d7e --- /dev/null +++ b/types/ember-data/attr.d.ts @@ -0,0 +1,2 @@ +import DS from 'ember-data'; +export default DS.attr; diff --git a/types/ember-data/index.d.ts b/types/ember-data/index.d.ts index cc5bb00efd..32d5d4a4f3 100644 --- a/types/ember-data/index.d.ts +++ b/types/ember-data/index.d.ts @@ -6,2211 +6,2200 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.8 -declare module 'ember-data' { - import Ember from 'ember'; - import Evented from '@ember/object/evented'; - import ObjectProxy from '@ember/object/proxy'; - import PromiseProxyMixin from '@ember/object/promise-proxy-mixin'; - import RSVP from 'rsvp'; +import Ember from 'ember'; +import Evented from '@ember/object/evented'; +import ObjectProxy from '@ember/object/proxy'; +import PromiseProxyMixin from '@ember/object/promise-proxy-mixin'; +import RSVP from 'rsvp'; - export interface ModelRegistry {} - export interface AdapterRegistry {} - export interface SerializerRegistry {} - export interface TransformRegistry { - 'string': string; - 'boolean': boolean; - 'number': number; - 'date': Date; - } - - type AttributesFor = keyof Model; // TODO: filter to attr properties only (TS 2.8) - type RelationshipsFor = keyof Model; // TODO: filter to hasMany/belongsTo properties only (TS 2.8) - - export interface ChangedAttributes { - [key: string]: [any, any] | undefined; - } - interface AttributeMeta { - type: keyof TransformRegistry; - options: object; - name: AttributesFor; - parentType: Model; - isAttribute: true; - } - interface RelationshipMeta { - key: RelationshipsFor; - kind: 'belongsTo' | 'hasMany'; - type: keyof ModelRegistry; - options: object; - name: string; - parentType: Model; - isRelationship: true; - } - - export namespace DS { - /** - * Convert an hash of errors into an array with errors in JSON-API format. - */ - function errorsHashToArray(errors: {}): any[]; - /** - * Convert an array of errors in JSON-API format into an object. - */ - function errorsArrayToHash(errors: any[]): {}; - - interface RelationshipOptions { - async?: boolean; - inverse?: RelationshipsFor | null; - polymorphic?: boolean; - } - - interface Sync { async: false; } - interface Async { async?: true; } - - /** - * `DS.belongsTo` is used to define One-To-One and One-To-Many - * relationships on a [DS.Model](/api/data/classes/DS.Model.html). - */ - function belongsTo( - modelName: K, - options: RelationshipOptions & Sync - ): Ember.ComputedProperty; - function belongsTo( - modelName: K, - options?: RelationshipOptions & Async - ): Ember.ComputedProperty, ModelRegistry[K]>; - /** - * `DS.hasMany` is used to define One-To-Many and Many-To-Many - * relationships on a [DS.Model](/api/data/classes/DS.Model.html). - */ - function hasMany( - type: K, - options: RelationshipOptions & Sync - ): Ember.ComputedProperty>; - function hasMany( - type: K, - options?: RelationshipOptions & Async - ): Ember.ComputedProperty, Ember.Array>; - /** - * This method normalizes a modelName into the format Ember Data uses - * internally. - */ - function normalizeModelName(modelName: K): string; - const VERSION: string; - - interface AttrOptions { - defaultValue?: T | (() => T); - allowNull?: boolean; // TODO: restrict to boolean transform (TS 2.8) - } - - /** - * `DS.attr` defines an attribute on a [DS.Model](/api/data/classes/DS.Model.html). - * By default, attributes are passed through as-is, however you can specify an - * optional type to have the value automatically transformed. - * Ember Data ships with four basic transform types: `string`, `number`, - * `boolean` and `date`. You can define your own transforms by subclassing - * [DS.Transform](/api/data/classes/DS.Transform.html). - */ - function attr( - type: K, - options?: AttrOptions - ): Ember.ComputedProperty; - function attr(options?: AttrOptions): Ember.ComputedProperty; - /** - * WARNING: This interface is likely to change in order to accomodate https://github.com/emberjs/rfcs/pull/4 - * ## Using BuildURLMixin - * To use url building, include the mixin when extending an adapter, and call `buildURL` where needed. - * The default behaviour is designed for RESTAdapter. - * ### Example - * ```javascript - * export default DS.Adapter.extend(BuildURLMixin, { - * findRecord: function(store, type, id, snapshot) { - * var url = this.buildURL(type.modelName, id, snapshot, 'findRecord'); - * return this.ajax(url, 'GET'); - * } - * }); - * ``` - * ### Attributes - * The `host` and `namespace` attributes will be used if defined, and are optional. - */ - class BuildURLMixin { - /** - * Builds a URL for a given type and optional ID. - */ - buildURL( - modelName?: K, - id?: string | any[] | {} | null, - snapshot?: Snapshot | any[] | null, - requestType?: string, - query?: {} - ): string; - /** - * Builds a URL for a `store.findRecord(type, id)` call. - */ - urlForFindRecord( - id: string, - modelName: K, - snapshot: Snapshot - ): string; - /** - * Builds a URL for a `store.findAll(type)` call. - */ - urlForFindAll( - modelName: K, - snapshot: SnapshotRecordArray - ): string; - /** - * Builds a URL for a `store.query(type, query)` call. - */ - urlForQuery(query: {}, modelName: K): string; - /** - * Builds a URL for a `store.queryRecord(type, query)` call. - */ - urlForQueryRecord(query: {}, modelName: K): string; - /** - * Builds a URL for coalesceing multiple `store.findRecord(type, id)` - * records into 1 request when the adapter's `coalesceFindRequests` - * property is true. - */ - urlForFindMany( - ids: any[], - modelName: K, - snapshots: any[] - ): string; - /** - * Builds a URL for fetching a async hasMany relationship when a url - * is not provided by the server. - */ - urlForFindHasMany( - id: string, - modelName: K, - snapshot: Snapshot - ): string; - /** - * Builds a URL for fetching a async belongsTo relationship when a url - * is not provided by the server. - */ - urlForFindBelongsTo( - id: string, - modelName: K, - snapshot: Snapshot - ): string; - /** - * Builds a URL for a `record.save()` call when the record was created - * locally using `store.createRecord()`. - */ - urlForCreateRecord(modelName: K, snapshot: Snapshot): string; - /** - * Builds a URL for a `record.save()` call when the record has been update locally. - */ - urlForUpdateRecord( - id: string, - modelName: K, - snapshot: Snapshot - ): string; - /** - * Builds a URL for a `record.save()` call when the record has been deleted locally. - */ - urlForDeleteRecord( - id: string, - modelName: K, - snapshot: Snapshot - ): string; - /** - * Determines the pathname for a given type. - */ - pathForType(modelName: K): string; - } - /** - * A `DS.AdapterError` is used by an adapter to signal that an error occurred - * during a request to an external API. It indicates a generic error, and - * subclasses are used to indicate specific error states. The following - * subclasses are provided: - */ - class AdapterError extends Ember.Object {} - /** - * A `DS.InvalidError` is used by an adapter to signal the external API - * was unable to process a request because the content was not - * semantically correct or meaningful per the API. Usually this means a - * record failed some form of server side validation. When a promise - * from an adapter is rejected with a `DS.InvalidError` the record will - * transition to the `invalid` state and the errors will be set to the - * `errors` property on the record. - */ - class InvalidError extends AdapterError { - constructor(errors: any[]); - } - /** - * A `DS.TimeoutError` is used by an adapter to signal that a request - * to the external API has timed out. I.e. no response was received from - * the external API within an allowed time period. - */ - class TimeoutError extends AdapterError {} - /** - * A `DS.AbortError` is used by an adapter to signal that a request to - * the external API was aborted. For example, this can occur if the user - * navigates away from the current page after a request to the external API - * has been initiated but before a response has been received. - */ - class AbortError extends AdapterError {} - /** - * A `DS.UnauthorizedError` equates to a HTTP `401 Unauthorized` response - * status. It is used by an adapter to signal that a request to the external - * API was rejected because authorization is required and has failed or has not - * yet been provided. - */ - class UnauthorizedError extends AdapterError {} - /** - * A `DS.ForbiddenError` equates to a HTTP `403 Forbidden` response status. - * It is used by an adapter to signal that a request to the external API was - * valid but the server is refusing to respond to it. If authorization was - * provided and is valid, then the authenticated user does not have the - * necessary permissions for the request. - */ - class ForbiddenError extends AdapterError {} - /** - * A `DS.NotFoundError` equates to a HTTP `404 Not Found` response status. - * It is used by an adapter to signal that a request to the external API - * was rejected because the resource could not be found on the API. - */ - class NotFoundError extends AdapterError {} - /** - * A `DS.ConflictError` equates to a HTTP `409 Conflict` response status. - * It is used by an adapter to indicate that the request could not be processed - * because of a conflict in the request. An example scenario would be when - * creating a record with a client generated id but that id is already known - * to the external API. - */ - class ConflictError extends AdapterError {} - /** - * A `DS.ServerError` equates to a HTTP `500 Internal Server Error` response - * status. It is used by the adapter to indicate that a request has failed - * because of an error in the external API. - */ - class ServerError extends AdapterError {} - /** - * Holds validation errors for a given record, organized by attribute names. - */ - interface Errors extends Ember.Enumerable, Evented {} - class Errors extends Ember.Object { - /** - * DEPRECATED: - * Register with target handler - */ - registerHandlers( - target: {}, - becameInvalid: Function, - becameValid: Function - ): any; - /** - * Returns errors for a given attribute - */ - errorsFor(attribute: string): any[]; - /** - * An array containing all of the error messages for this - * record. This is useful for displaying all errors to the user. - */ - messages: Ember.ComputedProperty; - /** - * Total number of errors. - */ - length: Ember.ComputedProperty; - isEmpty: Ember.ComputedProperty; - /** - * DEPRECATED: - * Adds error messages to a given attribute and sends - * `becameInvalid` event to the record. - */ - add(attribute: string, messages: any[] | string): any; - /** - * DEPRECATED: - * Removes all error messages from the given attribute and sends - * `becameValid` event to the record if there no more errors left. - */ - remove(attribute: string): any; - /** - * DEPRECATED: - * Removes all error messages and sends `becameValid` event - * to the record. - */ - clear(): any; - /** - * Checks if there is error messages for the given attribute. - */ - has(attribute: string): boolean; - } - /** - * The model class that all Ember Data records descend from. - * This is the public API of Ember Data models. If you are using Ember Data - * in your application, this is the class you should use. - * If you are working on Ember Data internals, you most likely want to be dealing - * with `InternalModel` - */ - class Model extends Ember.Object { - /** - * If this property is `true` the record is in the `empty` - * state. Empty is the first state all records enter after they have - * been created. Most records created by the store will quickly - * transition to the `loading` state if data needs to be fetched from - * the server or the `created` state if the record is created on the - * client. A record can also enter the empty state if the adapter is - * unable to locate the record. - */ - isEmpty: Ember.ComputedProperty; - /** - * If this property is `true` the record is in the `loading` state. A - * record enters this state when the store asks the adapter for its - * data. It remains in this state until the adapter provides the - * requested data. - */ - isLoading: Ember.ComputedProperty; - /** - * If this property is `true` the record is in the `loaded` state. A - * record enters this state when its data is populated. Most of a - * record's lifecycle is spent inside substates of the `loaded` - * state. - */ - isLoaded: Ember.ComputedProperty; - /** - * If this property is `true` the record is in the `dirty` state. The - * record has local changes that have not yet been saved by the - * adapter. This includes records that have been created (but not yet - * saved) or deleted. - */ - hasDirtyAttributes: Ember.ComputedProperty; - /** - * If this property is `true` the record is in the `saving` state. A - * record enters the saving state when `save` is called, but the - * adapter has not yet acknowledged that the changes have been - * persisted to the backend. - */ - isSaving: Ember.ComputedProperty; - /** - * If this property is `true` the record is in the `deleted` state - * and has been marked for deletion. When `isDeleted` is true and - * `hasDirtyAttributes` is true, the record is deleted locally but the deletion - * was not yet persisted. When `isSaving` is true, the change is - * in-flight. When both `hasDirtyAttributes` and `isSaving` are false, the - * change has persisted. - */ - isDeleted: Ember.ComputedProperty; - /** - * If this property is `true` the record is in the `new` state. A - * record will be in the `new` state when it has been created on the - * client and the adapter has not yet report that it was successfully - * saved. - */ - isNew: Ember.ComputedProperty; - /** - * If this property is `true` the record is in the `valid` state. - */ - isValid: Ember.ComputedProperty; - /** - * If the record is in the dirty state this property will report what - * kind of change has caused it to move into the dirty - * state. Possible values are: - */ - dirtyType: Ember.ComputedProperty; - /** - * If `true` the adapter reported that it was unable to save local - * changes to the backend for any reason other than a server-side - * validation error. - */ - isError: boolean; - /** - * If `true` the store is attempting to reload the record from the adapter. - */ - isReloading: boolean; - /** - * All ember models have an id property. This is an identifier - * managed by an external source. These are always coerced to be - * strings before being used internally. Note when declaring the - * attributes for a model it is an error to declare an id - * attribute. - */ - id: string; - /** - * When the record is in the `invalid` state this object will contain - * any errors returned by the adapter. When present the errors hash - * contains keys corresponding to the invalid property names - * and values which are arrays of Javascript objects with two keys: - */ - errors: Ember.ComputedProperty; - /** - * This property holds the `DS.AdapterError` object with which - * last adapter operation was rejected. - */ - adapterError: AdapterError; - /** - * Create a JSON representation of the record, using the serialization - * strategy of the store's adapter. - */ - serialize(options?: { includeId?: boolean }): {}; - /** - * Use [DS.JSONSerializer](DS.JSONSerializer.html) to - * get the JSON representation of a record. - */ - toJSON(options: {}): {}; - /** - * Fired when the record is ready to be interacted with, - * that is either loaded from the server or created locally. - */ - ready(): void; - /** - * Fired when the record is loaded from the server. - */ - didLoad(): void; - /** - * Fired when the record is updated. - */ - didUpdate(): void; - /** - * Fired when a new record is commited to the server. - */ - didCreate(): void; - /** - * Fired when the record is deleted. - */ - didDelete(): void; - /** - * Fired when the record becomes invalid. - */ - becameInvalid(): void; - /** - * Fired when the record enters the error state. - */ - becameError(): void; - /** - * Fired when the record is rolled back. - */ - rolledBack(): void; - /** - * Marks the record as deleted but does not save it. You must call - * `save` afterwards if you want to persist it. You might use this - * method if you want to allow the user to still `rollbackAttributes()` - * after a delete was made. - */ - deleteRecord(): any; - /** - * Same as `deleteRecord`, but saves the record immediately. - */ - destroyRecord(options?: {}): RSVP.Promise; - /** - * Unloads the record from the store. This will cause the record to be destroyed and freed up for garbage collection. - */ - unloadRecord(): any; - /** - * Returns an object, whose keys are changed properties, and value is - * an [oldProp, newProp] array. - */ - changedAttributes(): ChangedAttributes; - /** - * If the model `hasDirtyAttributes` this function will discard any unsaved - * changes. If the model `isNew` it will be removed from the store. - */ - rollbackAttributes(): any; - /** - * Save the record and persist any changes to the record to an - * external source via the adapter. - */ - save(options?: {}): RSVP.Promise; - /** - * Reload the record from the adapter. - */ - reload(): RSVP.Promise; - /** - * Get the reference for the specified belongsTo relationship. - */ - belongsTo(name: RelationshipsFor): BelongsToReference; - /** - * Get the reference for the specified hasMany relationship. - */ - hasMany(name: RelationshipsFor): HasManyReference; - /** - * Given a callback, iterates over each of the relationships in the model, - * invoking the callback with the name of each relationship and its relationship - * descriptor. - */ - eachRelationship(callback: (name: string, details: RelationshipMeta) => void, binding?: any): any; - /** - * Represents the model's class name as a string. This can be used to look up the model's class name through - * `DS.Store`'s modelFor method. - */ - static modelName: keyof ModelRegistry; - /** - * For a given relationship name, returns the model type of the relationship. - */ - static typeForRelationship(name: K, store: Store): ModelRegistry[K]; - /** - * Find the relationship which is the inverse of the one asked for. - */ - static inverseFor(name: K, store: Store): {}; - /** - * The model's relationships as a map, keyed on the type of the - * relationship. The value of each entry is an array containing a descriptor - * for each relationship with that type, describing the name of the relationship - * as well as the type. - */ - static relationships: Ember.ComputedProperty; - /** - * A hash containing lists of the model's relationships, grouped - * by the relationship kind. For example, given a model with this - * definition: - */ - static relationshipNames: Ember.ComputedProperty<{}>; - /** - * An array of types directly related to a model. Each type will be - * included once, regardless of the number of relationships it has with - * the model. - */ - static relatedTypes: Ember.ComputedProperty< - Ember.NativeArray - >; - /** - * A map whose keys are the relationships of a model and whose values are - * relationship descriptors. - */ - static relationshipsByName: Ember.ComputedProperty; - /** - * A map whose keys are the fields of the model and whose values are strings - * describing the kind of the field. A model's fields are the union of all of its - * attributes and relationships. - */ - static fields: Ember.ComputedProperty; - /** - * Given a callback, iterates over each of the relationships in the model, - * invoking the callback with the name of each relationship and its relationship - * descriptor. - */ - static eachRelationship(callback: (name: string, details: RelationshipMeta) => void, binding?: any): any; - /** - * Given a callback, iterates over each of the types related to a model, - * invoking the callback with the related type's class. Each type will be - * returned just once, regardless of how many different relationships it has - * with a model. - */ - static eachRelatedType(callback: Function, binding: any): any; - /** - * A map whose keys are the attributes of the model (properties - * described by DS.attr) and whose values are the meta object for the - * property. - */ - static attributes: Ember.ComputedProperty; - /** - * A map whose keys are the attributes of the model (properties - * described by DS.attr) and whose values are type of transformation - * applied to each attribute. This map does not include any - * attributes that do not have an transformation type. - */ - static transformedAttributes: Ember.ComputedProperty; - /** - * Iterates through the attributes of the model, calling the passed function on each - * attribute. - */ - static eachAttribute(callback: Function, binding: {}): any; - /** - * Iterates through the transformedAttributes of the model, calling - * the passed function on each attribute. Note the callback will not be - * called for any attributes that do not have an transformation type. - */ - static eachTransformedAttribute( - callback: Function, - binding: {} - ): any; - /** - * Discards any unsaved changes to the given attribute. This feature is not enabled by default. You must enable `ds-rollback-attribute` and be running a canary build. - */ - rollbackAttribute(): any; - /** - * This Ember.js hook allows an object to be notified when a property - * is defined. - */ - didDefineProperty( - proto: {}, - key: string, - value: Ember.ComputedProperty - ): any; - } - /** - * ### State - */ - class RootState {} - /** - * Represents an ordered list of records whose order and membership is - * determined by the adapter. For example, a query sent to the adapter - * may trigger a search on the server, whose results would be loaded - * into an instance of the `AdapterPopulatedRecordArray`. - */ - class AdapterPopulatedRecordArray extends RecordArray {} - /** - * Represents a list of records whose membership is determined by the - * store. As records are created, loaded, or modified, the store - * evaluates them to determine if they should be part of the record - * array. - */ - class FilteredRecordArray extends RecordArray { - /** - * The filterFunction is a function used to test records from the store to - * determine if they should be part of the record array. - */ - filterFunction(record: Model): boolean; - } - /** - * A record array is an array that contains records of a certain modelName. The record - * array materializes records as needed when they are retrieved for the first - * time. You should not create record arrays yourself. Instead, an instance of - * `DS.RecordArray` or its subclasses will be returned by your application's store - * in response to queries. - */ - interface RecordArray extends Ember.ArrayProxy, Evented {} - class RecordArray { - /** - * The flag to signal a `RecordArray` is finished loading data. - */ - isLoaded: boolean; - /** - * The flag to signal a `RecordArray` is currently loading data. - */ - isUpdating: boolean; - /** - * The modelClass represented by this record array. - */ - type: Ember.ComputedProperty; - /** - * Used to get the latest version of all of the records in this array - * from the adapter. - */ - update(): any; - /** - * Saves all of the records in the `RecordArray`. - */ - save(): PromiseArray; - } - /** - * A BelongsToReference is a low level API that allows users and - * addon author to perform meta-operations on a belongs-to - * relationship. - */ - class BelongsToReference { - /** - * This returns a string that represents how the reference will be - * looked up when it is loaded. If the relationship has a link it will - * use the "link" otherwise it defaults to "id". - */ - remoteType(): string; - /** - * The `id` of the record that this reference refers to. Together, the - * `type()` and `id()` methods form a composite key for the identity - * map. This can be used to access the id of an async relationship - * without triggering a fetch that would normally happen if you - * attempted to use `record.get('relationship.id')`. - */ - id(): string; - /** - * The link Ember Data will use to fetch or reload this belongs-to - * relationship. - */ - link(): string; - /** - * The meta data for the belongs-to relationship. - */ - meta(): {}; - /** - * `push` can be used to update the data in the relationship and Ember - * Data will treat the new data as the conanical value of this - * relationship on the backend. - */ - push(objectOrPromise: {} | RSVP.Promise): RSVP.Promise; - /** - * `value()` synchronously returns the current value of the belongs-to - * relationship. Unlike `record.get('relationshipName')`, calling - * `value()` on a reference does not trigger a fetch if the async - * relationship is not yet loaded. If the relationship is not loaded - * it will always return `null`. - */ - value(objectOrPromise: {} | RSVP.Promise): Model; - /** - * Loads a record in a belongs to relationship if it is not already - * loaded. If the relationship is already loaded this method does not - * trigger a new load. - */ - load(): RSVP.Promise; - /** - * Triggers a reload of the value in this relationship. If the - * remoteType is `"link"` Ember Data will use the relationship link to - * reload the relationship. Otherwise it will reload the record by its - * id. - */ - reload(): RSVP.Promise; - } - /** - * A HasManyReference is a low level API that allows users and addon - * author to perform meta-operations on a has-many relationship. - */ - class HasManyReference { - /** - * This returns a string that represents how the reference will be - * looked up when it is loaded. If the relationship has a link it will - * use the "link" otherwise it defaults to "id". - */ - remoteType(): string; - /** - * The link Ember Data will use to fetch or reload this has-many - * relationship. - */ - link(): string; - /** - * `ids()` returns an array of the record ids in this relationship. - */ - ids(): any[]; - /** - * The meta data for the has-many relationship. - */ - meta(): {}; - /** - * `push` can be used to update the data in the relationship and Ember - * Data will treat the new data as the canonical value of this - * relationship on the backend. - */ - push(objectOrPromise: T[] | RSVP.Promise): ManyArray; - /** - * `value()` synchronously returns the current value of the has-many - * relationship. Unlike `record.get('relationshipName')`, calling - * `value()` on a reference does not trigger a fetch if the async - * relationship is not yet loaded. If the relationship is not loaded - * it will always return `null`. - */ - value(): ManyArray; - /** - * Loads the relationship if it is not already loaded. If the - * relationship is already loaded this method does not trigger a new - * load. - */ - load(): RSVP.Promise; - /** - * Reloads this has-many relationship. - */ - reload(): RSVP.Promise; - } - /** - * An RecordReference is a low level API that allows users and - * addon author to perform meta-operations on a record. - */ - class RecordReference { - /** - * The `id` of the record that this reference refers to. - */ - id(): string; - /** - * How the reference will be looked up when it is loaded: Currently - * this always return `identity` to signifying that a record will be - * loaded by the `type` and `id`. - */ - remoteType(): string; - /** - * This API allows you to provide a reference with new data. The - * simplest usage of this API is similar to `store.push`: you provide a - * normalized hash of data and the object represented by the reference - * will update. - */ - push(payload: RSVP.Promise | {}): PromiseObject & T; - /** - * If the entity referred to by the reference is already loaded, it is - * present as `reference.value`. Otherwise the value returned by this function - * is `null`. - */ - value(): T | null; - /** - * Triggers a fetch for the backing entity based on its `remoteType` - * (see `remoteType` definitions per reference type). - */ - load(): PromiseObject & T; - /** - * Reloads the record if it is already loaded. If the record is not - * loaded it will load the record via `store.findRecord` - */ - reload(): PromiseObject & T; - } - /** - * A `ManyArray` is a `MutableArray` that represents the contents of a has-many - * relationship. - */ - interface ManyArray extends Ember.MutableArray {} - class ManyArray extends Ember.Object.extend( - Ember.MutableArray as {}, - Ember.Evented - ) { - /** - * The loading state of this array - */ - isLoaded: boolean; - /** - * Metadata associated with the request for async hasMany relationships. - */ - meta: {}; - /** - * Reloads all of the records in the manyArray. If the manyArray - * holds a relationship that was originally fetched using a links url - * Ember Data will revisit the original links url to repopulate the - * relationship. - */ - reload(): PromiseArray; - /** - * Saves all of the records in the `ManyArray`. - */ - save(): PromiseArray; - /** - * Create a child record within the owner - */ - createRecord(inputProperties?: {}): T; - } - /** - * A `PromiseArray` is an object that acts like both an `Ember.Array` - * and a promise. When the promise is resolved the resulting value - * will be set to the `PromiseArray`'s `content` property. This makes - * it easy to create data bindings with the `PromiseArray` that will be - * updated when the promise resolves. - */ - interface PromiseArray - extends Ember.ArrayProxy, - PromiseProxyMixin> {} - class PromiseArray {} - /** - * A `PromiseObject` is an object that acts like both an `Ember.Object` - * and a promise. When the promise is resolved, then the resulting value - * will be set to the `PromiseObject`'s `content` property. This makes - * it easy to create data bindings with the `PromiseObject` that will - * be updated when the promise resolves. - */ - interface PromiseObject - extends ObjectProxy, - PromiseProxyMixin {} - class PromiseObject {} - /** - * A PromiseManyArray is a PromiseArray that also proxies certain method calls - * to the underlying manyArray. - * Right now we proxy: - */ - class PromiseManyArray extends PromiseArray { - /** - * Reloads all of the records in the manyArray. If the manyArray - * holds a relationship that was originally fetched using a links url - * Ember Data will revisit the original links url to repopulate the - * relationship. - */ - reload(): PromiseManyArray; - /** - * Create a child record within the owner - */ - createRecord(inputProperties?: {}): T; - } - class SnapshotRecordArray { - /** - * Number of records in the array - */ - length: number; - /** - * Meta objects for the record array. - */ - meta: {}; - /** - * A hash of adapter options passed into the store method for this request. - */ - adapterOptions: {}; - /** - * The relationships to include for this request. - */ - include: string | any[]; - /** - * The type of the underlying records for the snapshots in the array, as a DS.Model - */ - type: ModelRegistry[K]; - /** - * Get snapshots of the underlying record array - */ - snapshots(): any[]; - } - class Snapshot { - /** - * The underlying record for this snapshot. Can be used to access methods and - * properties defined on the record. - */ - record: ModelRegistry[K]; - /** - * The id of the snapshot's underlying record - */ - id: string; - /** - * A hash of adapter options - */ - adapterOptions: {}; - /** - * The name of the type of the underlying record for this snapshot, as a string. - */ - modelName: K; - /** - * The type of the underlying record for this snapshot, as a DS.Model. - */ - type: ModelRegistry[K]; - /** - * Returns the value of an attribute. - */ - attr>(keyName: L): ModelRegistry[K][L]; - /** - * Returns all attributes and their corresponding values. - */ - attributes(): { [L in keyof ModelRegistry[K]]: ModelRegistry[K][L] }; - /** - * Returns all changed attributes and their old and new values. - */ - changedAttributes(): Partial<{ [L in keyof ModelRegistry[K]]: ModelRegistry[K][L] }>; - /** - * Returns the current value of a belongsTo relationship. - */ - belongsTo>( - keyName: L, - options?: {} - ): Snapshot['record'][L] | string | null | undefined; - /** - * Returns the current value of a hasMany relationship. - */ - hasMany>( - keyName: L, - options?: { ids: false } - ): Array['record'][L]> | undefined; - hasMany>( - keyName: L, - options: { ids: true } - ): string[] | undefined; - /** - * Iterates through all the attributes of the model, calling the passed - * function on each attribute. - */ - eachAttribute(callback: (key: keyof M, meta: AttributeMeta) => void, binding?: {}): any; - /** - * Iterates through all the relationships of the model, calling the passed - * function on each relationship. - */ - eachRelationship(callback: (key: keyof M, meta: RelationshipMeta) => void, binding?: {}): any; - /** - * Serializes the snapshot using the serializer for the model. - */ - serialize(options: {}): {}; - } - - /** - * The store contains all of the data for records loaded from the server. - * It is also responsible for creating instances of `DS.Model` that wrap - * the individual data for a record, so that they can be bound to in your - * Handlebars templates. - */ - class Store { - /** - * The default adapter to use to communicate to a backend server or - * other persistence layer. This will be overridden by an application - * adapter if present. - */ - adapter: string; - /** - * Create a new record in the current store. The properties passed - * to this method are set on the newly created record. - */ - createRecord( - modelName: K, - inputProperties?: {} - ): ModelRegistry[K]; - /** - * For symmetry, a record can be deleted via the store. - */ - deleteRecord(record: Model): void; - /** - * For symmetry, a record can be unloaded via the store. - * This will cause the record to be destroyed and freed up for garbage collection. - */ - unloadRecord(record: Model): void; - /** - * This method returns a record for a given type and id combination. - */ - findRecord( - modelName: K, - id: string | number, - options?: {} - ): PromiseObject & ModelRegistry[K]; - /** - * Get the reference for the specified record. - */ - getReference( - modelName: K, - id: string | number - ): RecordReference; - /** - * Get a record by a given type and ID without triggering a fetch. - */ - peekRecord( - modelName: K, - id: string | number - ): ModelRegistry[K] | null; - /** - * This method returns true if a record for a given modelName and id is already - * loaded in the store. Use this function to know beforehand if a findRecord() - * will result in a request or that it will be a cache hit. - */ - hasRecordForId( - modelName: K, - id: string | number - ): boolean; - /** - * This method delegates a query to the adapter. This is the one place where - * adapter-level semantics are exposed to the application. - */ - query( - modelName: K, - query: any - ): AdapterPopulatedRecordArray & PromiseArray; - /** - * This method makes a request for one record, where the `id` is not known - * beforehand (if the `id` is known, use [`findRecord`](#method_findRecord) - * instead). - */ - queryRecord( - modelName: K, - query: any - ): RSVP.Promise; - /** - * `findAll` asks the adapter's `findAll` method to find the records for the - * given type, and returns a promise which will resolve with all records of - * this type present in the store, even if the adapter only returns a subset - * of them. - */ - findAll( - modelName: K, - options?: { - reload?: boolean; - backgroundReload?: boolean; - include?: string; - adapterOptions?: any; - } - ): PromiseArray; - /** - * This method returns a filtered array that contains all of the - * known records for a given type in the store. - */ - peekAll(modelName: K): RecordArray; - /** - * This method unloads all records in the store. - * It schedules unloading to happen during the next run loop. - */ - unloadAll(modelName: K): void; - /** - * DEPRECATED: - * This method has been deprecated and is an alias for store.hasRecordForId, which should - * be used instead. - */ - recordIsLoaded(modelName: K, id: string): boolean; - /** - * Returns the model class for the particular `modelName`. - */ - modelFor(modelName: K): ModelRegistry[K]; - /** - * Push some data for a given type into the store. - */ - push(data: {}): Model | any[]; - /** - * Push some raw data into the store. - */ - pushPayload(modelName: K, inputPayload: {}): any; - pushPayload(inputPayload: {}): any; - /** - * `normalize` converts a json payload into the normalized form that - * [push](#method_push) expects. - */ - normalize(modelName: K, payload: {}): {}; - /** - * Returns an instance of the adapter for a given type. For - * example, `adapterFor('person')` will return an instance of - * `App.PersonAdapter`. - */ - adapterFor(modelName: K): AdapterRegistry[K]; - /** - * Returns an instance of the serializer for a given type. For - * example, `serializerFor('person')` will return an instance of - * `App.PersonSerializer`. - */ - serializerFor(modelName: K): SerializerRegistry[K]; - } - /** - * The `JSONAPIAdapter` is the default adapter used by Ember Data. It - * is responsible for transforming the store's requests into HTTP - * requests that follow the [JSON API](http://jsonapi.org/format/) - * format. - */ - class JSONAPIAdapter extends RESTAdapter { - /** - * By default the JSONAPIAdapter will send each find request coming from a `store.find` - * or from accessing a relationship separately to the server. If your server supports passing - * ids as a query string, you can set coalesceFindRequests to true to coalesce all find requests - * within a single runloop. - */ - coalesceFindRequests: boolean; - } - /** - * The REST adapter allows your store to communicate with an HTTP server by - * transmitting JSON via XHR. Most Ember.js apps that consume a JSON API - * should use the REST adapter. - */ - class RESTAdapter extends Adapter implements BuildURLMixin { - /** - * Takes a URL, an HTTP method and a hash of data, and makes an HTTP request. - */ - ajax( - url: string, - type: string, - options?: object - ): RSVP.Promise; - /** - * Generate ajax options - */ - ajaxOptions(url: string, type: string, options?: object): object; - /** - * By default, the RESTAdapter will send the query params sorted alphabetically to the - * server. - */ - sortQueryParams(obj: {}): {}; - /** - * By default the RESTAdapter will send each find request coming from a `store.find` - * or from accessing a relationship separately to the server. If your server supports passing - * ids as a query string, you can set coalesceFindRequests to true to coalesce all find requests - * within a single runloop. - */ - coalesceFindRequests: boolean; - /** - * Endpoint paths can be prefixed with a `namespace` by setting the namespace - * property on the adapter: - */ - namespace: string; - /** - * An adapter can target other hosts by setting the `host` property. - */ - host: string; - /** - * Some APIs require HTTP headers, e.g. to provide an API - * key. Arbitrary headers can be set as key/value pairs on the - * `RESTAdapter`'s `headers` object and Ember Data will send them - * along with each ajax request. For dynamic headers see [headers - * customization](/api/data/classes/DS.RESTAdapter.html#toc_headers-customization). - */ - headers: {}; - /** - * Called by the store in order to fetch the JSON for a given - * type and ID. - */ - findRecord( - store: Store, - type: ModelRegistry[K], - id: string, - snapshot: Snapshot - ): RSVP.Promise; - /** - * Called by the store in order to fetch a JSON array for all - * of the records for a given type. - */ - findAll( - store: Store, - type: ModelRegistry[K], - sinceToken: string, - snapshotRecordArray: SnapshotRecordArray - ): RSVP.Promise; - /** - * Called by the store in order to fetch a JSON array for - * the records that match a particular query. - */ - query(store: Store, type: ModelRegistry[K], query: {}): RSVP.Promise; - /** - * Called by the store in order to fetch a JSON object for - * the record that matches a particular query. - */ - queryRecord( - store: Store, - type: ModelRegistry[K], - query: {} - ): RSVP.Promise; - /** - * Called by the store in order to fetch several records together if `coalesceFindRequests` is true - */ - findMany( - store: Store, - type: ModelRegistry[K], - ids: any[], - snapshots: any[] - ): RSVP.Promise; - /** - * Called by the store in order to fetch a JSON array for - * the unloaded records in a has-many relationship that were originally - * specified as a URL (inside of `links`). - */ - findHasMany( - store: Store, - snapshot: Snapshot, - url: string, - relationship: {} - ): RSVP.Promise; - /** - * Called by the store in order to fetch the JSON for the unloaded record in a - * belongs-to relationship that was originally specified as a URL (inside of - * `links`). - */ - findBelongsTo( - store: Store, - snapshot: Snapshot, - url: string - ): RSVP.Promise; - /** - * Called by the store when a newly created record is - * saved via the `save` method on a model record instance. - */ - createRecord( - store: Store, - type: ModelRegistry[K], - snapshot: Snapshot - ): RSVP.Promise; - /** - * Called by the store when an existing record is saved - * via the `save` method on a model record instance. - */ - updateRecord( - store: Store, - type: ModelRegistry[K], - snapshot: Snapshot - ): RSVP.Promise; - /** - * Called by the store when a record is deleted. - */ - deleteRecord( - store: Store, - type: ModelRegistry[K], - snapshot: Snapshot - ): RSVP.Promise; - /** - * Organize records into groups, each of which is to be passed to separate - * calls to `findMany`. - */ - groupRecordsForFindMany(store: Store, snapshots: any[]): any[]; - /** - * Takes an ajax response, and returns the json payload or an error. - */ - handleResponse( - status: number, - headers: {}, - payload: {}, - requestData: {} - ): {}; - /** - * Default `handleResponse` implementation uses this hook to decide if the - * response is a success. - */ - isSuccess(status: number, headers: {}, payload: {}): boolean; - /** - * Default `handleResponse` implementation uses this hook to decide if the - * response is an invalid error. - */ - isInvalid(status: number, headers: {}, payload: {}): boolean; - /** - * Get the data (body or query params) for a request. - */ - dataForRequest(params: {}): {}; - /** - * Get the HTTP method for a request. - */ - methodForRequest(params: {}): string; - /** - * Get the URL for a request. - */ - urlForRequest(params: {}): string; - /** - * Get the headers for a request. - */ - headersForRequest(params: {}): {}; - /** - * Builds a URL for a given type and optional ID. - */ - buildURL( - modelName?: K, - id?: string | any[] | {} | null, - snapshot?: Snapshot | any[] | null, - requestType?: string, - query?: {} - ): string; - /** - * Builds a URL for a `store.findRecord(type, id)` call. - */ - urlForFindRecord( - id: string, - modelName: K, - snapshot: Snapshot - ): string; - /** - * Builds a URL for a `store.findAll(type)` call. - */ - urlForFindAll( - modelName: K, - snapshot: SnapshotRecordArray - ): string; - /** - * Builds a URL for a `store.query(type, query)` call. - */ - urlForQuery(query: {}, modelName: K): string; - /** - * Builds a URL for a `store.queryRecord(type, query)` call. - */ - urlForQueryRecord(query: {}, modelName: K): string; - /** - * Builds a URL for coalesceing multiple `store.findRecord(type, id)` - * records into 1 request when the adapter's `coalesceFindRequests` - * property is true. - */ - urlForFindMany( - ids: any[], - modelName: K, - snapshots: any[] - ): string; - /** - * Builds a URL for fetching a async hasMany relationship when a url - * is not provided by the server. - */ - urlForFindHasMany( - id: string, - modelName: K, - snapshot: Snapshot - ): string; - /** - * Builds a URL for fetching a async belongsTo relationship when a url - * is not provided by the server. - */ - urlForFindBelongsTo( - id: string, - modelName: K, - snapshot: Snapshot - ): string; - /** - * Builds a URL for a `record.save()` call when the record was created - * locally using `store.createRecord()`. - */ - urlForCreateRecord(modelName: K, snapshot: Snapshot): string; - /** - * Builds a URL for a `record.save()` call when the record has been update locally. - */ - urlForUpdateRecord( - id: string, - modelName: K, - snapshot: Snapshot - ): string; - /** - * Builds a URL for a `record.save()` call when the record has been deleted locally. - */ - urlForDeleteRecord( - id: string, - modelName: K, - snapshot: Snapshot - ): string; - /** - * Determines the pathname for a given type. - */ - pathForType(modelName: K): string; - } - /** - * ## Using Embedded Records - */ - class EmbeddedRecordsMixin { - /** - * Normalize the record and recursively normalize/extract all the embedded records - * while pushing them into the store as they are encountered - */ - normalize(typeClass: Model, hash: {}, prop: string): {}; - /** - * Serialize `belongsTo` relationship when it is configured as an embedded object. - */ - serializeBelongsTo( - snapshot: Snapshot, - json: {}, - relationship: {} - ): any; - /** - * Serializes `hasMany` relationships when it is configured as embedded objects. - */ - serializeHasMany( - snapshot: Snapshot, - json: {}, - relationship: {} - ): any; - /** - * When serializing an embedded record, modify the property (in the json payload) - * that refers to the parent record (foreign key for relationship). - */ - removeEmbeddedForeignKey( - snapshot: Snapshot, - embeddedSnapshot: Snapshot, - relationship: {}, - json: {} - ): any; - } - /** - * Ember Data 2.0 Serializer: - */ - class JSONAPISerializer extends JSONSerializer { - pushPayload(store: Store, payload: {}): any; - /** - * Dasherizes and singularizes the model name in the payload to match - * the format Ember Data uses internally for the model name. - */ - modelNameFromPayloadKey(key: string): string; - /** - * Converts the model name to a pluralized version of the model name. - */ - payloadKeyFromModelName(modelName: K): string; - /** - * `keyForAttribute` can be used to define rules for how to convert an - * attribute name in your model to a key in your JSON. - * By default `JSONAPISerializer` follows the format used on the examples of - * http://jsonapi.org/format and uses dashes as the word separator in the JSON - * attribute keys. - */ - keyForAttribute(key: string, method: string): string; - /** - * `keyForRelationship` can be used to define a custom key when - * serializing and deserializing relationship properties. - * By default `JSONAPISerializer` follows the format used on the examples of - * http://jsonapi.org/format and uses dashes as word separators in - * relationship properties. - */ - keyForRelationship( - key: string, - typeClass: string, - method: string - ): string; - /** - * `modelNameFromPayloadType` can be used to change the mapping for a DS model - * name, taken from the value in the payload. - */ - modelNameFromPayloadType(payloadType: string): string; - /** - * `payloadTypeFromModelName` can be used to change the mapping for the type in - * the payload, taken from the model name. - */ - payloadTypeFromModelName(modelName: K): string; - } - /** - * Ember Data 2.0 Serializer: - */ - class JSONSerializer extends Serializer { - /** - * The `primaryKey` is used when serializing and deserializing - * data. Ember Data always uses the `id` property to store the id of - * the record. The external source may not always follow this - * convention. In these cases it is useful to override the - * `primaryKey` property to match the `primaryKey` of your external - * store. - */ - primaryKey: string; - /** - * The `attrs` object can be used to declare a simple mapping between - * property names on `DS.Model` records and payload keys in the - * serialized JSON object representing the record. An object with the - * property `key` can also be used to designate the attribute's key on - * the response payload. - */ - attrs: {}; - /** - * The `normalizeResponse` method is used to normalize a payload from the - * server to a JSON-API Document. - */ - normalizeResponse( - store: Store, - primaryModelClass: Model, - payload: {}, - id: string | number, - requestType: string - ): {}; - normalizeFindRecordResponse( - store: Store, - primaryModelClass: Model, - payload: {}, - id: string | number, - requestType: string - ): {}; - normalizeQueryRecordResponse( - store: Store, - primaryModelClass: Model, - payload: {}, - id: string | number, - requestType: string - ): {}; - normalizeFindAllResponse( - store: Store, - primaryModelClass: Model, - payload: {}, - id: string | number, - requestType: string - ): {}; - normalizeFindBelongsToResponse( - store: Store, - primaryModelClass: Model, - payload: {}, - id: string | number, - requestType: string - ): {}; - normalizeFindHasManyResponse( - store: Store, - primaryModelClass: Model, - payload: {}, - id: string | number, - requestType: string - ): {}; - normalizeFindManyResponse( - store: Store, - primaryModelClass: Model, - payload: {}, - id: string | number, - requestType: string - ): {}; - normalizeQueryResponse( - store: Store, - primaryModelClass: Model, - payload: {}, - id: string | number, - requestType: string - ): {}; - normalizeCreateRecordResponse( - store: Store, - primaryModelClass: Model, - payload: {}, - id: string | number, - requestType: string - ): {}; - normalizeDeleteRecordResponse( - store: Store, - primaryModelClass: Model, - payload: {}, - id: string | number, - requestType: string - ): {}; - normalizeUpdateRecordResponse( - store: Store, - primaryModelClass: Model, - payload: {}, - id: string | number, - requestType: string - ): {}; - normalizeSaveResponse( - store: Store, - primaryModelClass: Model, - payload: {}, - id: string | number, - requestType: string - ): {}; - normalizeSingleResponse( - store: Store, - primaryModelClass: Model, - payload: {}, - id: string | number, - requestType: string - ): {}; - normalizeArrayResponse( - store: Store, - primaryModelClass: Model, - payload: {}, - id: string | number, - requestType: string - ): {}; - /** - * Normalizes a part of the JSON payload returned by - * the server. You should override this method, munge the hash - * and call super if you have generic normalization to do. - */ - normalize(typeClass: Model, hash: {}): {}; - /** - * Returns the resource's ID. - */ - extractId(modelClass: {}, resourceHash: {}): string; - /** - * Returns the resource's attributes formatted as a JSON-API "attributes object". - */ - extractAttributes(modelClass: {}, resourceHash: {}): {}; - /** - * Returns a relationship formatted as a JSON-API "relationship object". - */ - extractRelationship( - relationshipModelName: {}, - relationshipHash: {} - ): {}; - /** - * Returns a polymorphic relationship formatted as a JSON-API "relationship object". - */ - extractPolymorphicRelationship( - relationshipModelName: {}, - relationshipHash: {}, - relationshipOptions: {} - ): {}; - /** - * Returns the resource's relationships formatted as a JSON-API "relationships object". - */ - extractRelationships(modelClass: {}, resourceHash: {}): {}; - modelNameFromPayloadKey(key: string): string; - /** - * Check if the given hasMany relationship should be serialized - */ - shouldSerializeHasMany( - snapshot: Snapshot, - key: string, - relationshipType: string - ): boolean; - /** - * Called when a record is saved in order to convert the - * record into JSON. - */ - serialize(snapshot: Snapshot, options: {}): {}; - /** - * You can use this method to customize how a serialized record is added to the complete - * JSON hash to be sent to the server. By default the JSON Serializer does not namespace - * the payload and just sends the raw serialized JSON object. - * If your server expects namespaced keys, you should consider using the RESTSerializer. - * Otherwise you can override this method to customize how the record is added to the hash. - * The hash property should be modified by reference. - */ - serializeIntoHash( - hash: {}, - typeClass: ModelRegistry[K], - snapshot: Snapshot, - options?: {} - ): any; - /** - * `serializeAttribute` can be used to customize how `DS.attr` - * properties are serialized - */ - serializeAttribute( - snapshot: Snapshot, - json: {}, - key: string, - attribute: {} - ): any; - /** - * `serializeBelongsTo` can be used to customize how `DS.belongsTo` - * properties are serialized. - */ - serializeBelongsTo( - snapshot: Snapshot, - json: {}, - relationship: {} - ): any; - /** - * `serializeHasMany` can be used to customize how `DS.hasMany` - * properties are serialized. - */ - serializeHasMany( - snapshot: Snapshot, - json: {}, - relationship: {} - ): any; - /** - * You can use this method to customize how polymorphic objects are - * serialized. Objects are considered to be polymorphic if - * `{ polymorphic: true }` is pass as the second argument to the - * `DS.belongsTo` function. - */ - serializePolymorphicType( - snapshot: Snapshot, - json: {}, - relationship: {} - ): any; - /** - * `extractMeta` is used to deserialize any meta information in the - * adapter payload. By default Ember Data expects meta information to - * be located on the `meta` property of the payload object. - */ - extractMeta(store: Store, modelClass: Model, payload: {}): any; - /** - * `extractErrors` is used to extract model errors when a call - * to `DS.Model#save` fails with an `InvalidError`. By default - * Ember Data expects error information to be located on the `errors` - * property of the payload object. - */ - extractErrors( - store: Store, - typeClass: Model, - payload: {}, - id: string | number - ): {}; - /** - * `keyForAttribute` can be used to define rules for how to convert an - * attribute name in your model to a key in your JSON. - */ - keyForAttribute(key: string, method: string): string; - /** - * `keyForRelationship` can be used to define a custom key when - * serializing and deserializing relationship properties. By default - * `JSONSerializer` does not provide an implementation of this method. - */ - keyForRelationship( - key: string, - typeClass: string, - method: string - ): string; - /** - * `keyForLink` can be used to define a custom key when deserializing link - * properties. - */ - keyForLink(key: string, kind: string): string; - modelNameFromPayloadType(type: string): string; - /** - * serializeId can be used to customize how id is serialized - * For example, your server may expect integer datatype of id - */ - serializeId(snapshot: Snapshot, json: {}, primaryKey: string): any; - } - /** - * Normally, applications will use the `RESTSerializer` by implementing - * the `normalize` method. - */ - class RESTSerializer extends JSONSerializer { - /** - * `keyForPolymorphicType` can be used to define a custom key when - * serializing and deserializing a polymorphic type. By default, the - * returned key is `${key}Type`. - */ - keyForPolymorphicType( - key: string, - typeClass: string, - method: string - ): string; - /** - * Normalizes a part of the JSON payload returned by - * the server. You should override this method, munge the hash - * and call super if you have generic normalization to do. - */ - normalize(modelClass: Model, resourceHash: {}, prop?: string): {}; - /** - * This method allows you to push a payload containing top-level - * collections of records organized per type. - */ - pushPayload(store: Store, payload: {}): any; - /** - * This method is used to convert each JSON root key in the payload - * into a modelName that it can use to look up the appropriate model for - * that part of the payload. - */ - modelNameFromPayloadKey(key: string): string; - /** - * Called when a record is saved in order to convert the - * record into JSON. - */ - serialize(snapshot: Snapshot, options: {}): {}; - /** - * You can use this method to customize the root keys serialized into the JSON. - * The hash property should be modified by reference (possibly using something like _.extend) - * By default the REST Serializer sends the modelName of a model, which is a camelized - * version of the name. - */ - serializeIntoHash( - hash: {}, - typeClass: Model, - snapshot: Snapshot, - options?: {} - ): any; - /** - * You can use `payloadKeyFromModelName` to override the root key for an outgoing - * request. By default, the RESTSerializer returns a camelized version of the - * model's name. - */ - payloadKeyFromModelName(modelName: K): string; - /** - * You can use this method to customize how polymorphic objects are serialized. - * By default the REST Serializer creates the key by appending `Type` to - * the attribute and value from the model's camelcased model name. - */ - serializePolymorphicType( - snapshot: Snapshot, - json: {}, - relationship: {} - ): any; - /** - * You can use this method to customize how a polymorphic relationship should - * be extracted. - */ - extractPolymorphicRelationship( - relationshipType: {}, - relationshipHash: {}, - relationshipOptions: {} - ): {}; - /** - * `modelNameFromPayloadType` can be used to change the mapping for a DS model - * name, taken from the value in the payload. - */ - modelNameFromPayloadType(payloadType: string): string; - /** - * `payloadTypeFromModelName` can be used to change the mapping for the type in - * the payload, taken from the model name. - */ - payloadTypeFromModelName(modelName: K): string; - } - /** - * The `DS.BooleanTransform` class is used to serialize and deserialize - * boolean attributes on Ember Data record objects. This transform is - * used when `boolean` is passed as the type parameter to the - * [DS.attr](../../data#method_attr) function. - */ - class BooleanTransform extends Transform {} - /** - * The `DS.DateTransform` class is used to serialize and deserialize - * date attributes on Ember Data record objects. This transform is used - * when `date` is passed as the type parameter to the - * [DS.attr](../../data#method_attr) function. It uses the [`ISO 8601`](https://en.wikipedia.org/wiki/ISO_8601) - * standard. - */ - class DateTransform extends Transform {} - /** - * The `DS.NumberTransform` class is used to serialize and deserialize - * numeric attributes on Ember Data record objects. This transform is - * used when `number` is passed as the type parameter to the - * [DS.attr](../../data#method_attr) function. - */ - class NumberTransform extends Transform {} - /** - * The `DS.StringTransform` class is used to serialize and deserialize - * string attributes on Ember Data record objects. This transform is - * used when `string` is passed as the type parameter to the - * [DS.attr](../../data#method_attr) function. - */ - class StringTransform extends Transform {} - /** - * The `DS.Transform` class is used to serialize and deserialize model - * attributes when they are saved or loaded from an - * adapter. Subclassing `DS.Transform` is useful for creating custom - * attributes. All subclasses of `DS.Transform` must implement a - * `serialize` and a `deserialize` method. - */ - class Transform extends Ember.Object { - /** - * When given a deserialized value from a record attribute this - * method must return the serialized value. - */ - serialize(deserialized: any, options: AttrOptions): any; - /** - * When given a serialize value from a JSON object this method must - * return the deserialized value for the record attribute. - */ - deserialize(serialized: any, options: AttrOptions): any; - } - /** - * An adapter is an object that receives requests from a store and - * translates them into the appropriate action to take against your - * persistence layer. The persistence layer is usually an HTTP API, but - * may be anything, such as the browser's local storage. Typically the - * adapter is not invoked directly instead its functionality is accessed - * through the `store`. - */ - class Adapter extends Ember.Object { - /** - * If you would like your adapter to use a custom serializer you can - * set the `defaultSerializer` property to be the name of the custom - * serializer. - */ - defaultSerializer: string; - /** - * The `findRecord()` method is invoked when the store is asked for a record that - * has not previously been loaded. In response to `findRecord()` being called, you - * should query your persistence layer for a record with the given ID. The `findRecord` - * method should return a promise that will resolve to a JavaScript object that will be - * normalized by the serializer. - */ - findRecord( - store: Store, - type: ModelRegistry[K], - id: string, - snapshot: Snapshot - ): RSVP.Promise; - /** - * The `findAll()` method is used to retrieve all records for a given type. - */ - findAll( - store: Store, - type: ModelRegistry[K], - sinceToken: string, - snapshotRecordArray: SnapshotRecordArray - ): RSVP.Promise; - /** - * This method is called when you call `query` on the store. - */ - query( - store: Store, - type: ModelRegistry[K], - query: {}, - recordArray: AdapterPopulatedRecordArray - ): RSVP.Promise; - /** - * The `queryRecord()` method is invoked when the store is asked for a single - * record through a query object. - */ - queryRecord( - store: Store, - type: ModelRegistry[K], - query: {} - ): RSVP.Promise; - /** - * If the globally unique IDs for your records should be generated on the client, - * implement the `generateIdForRecord()` method. This method will be invoked - * each time you create a new record, and the value returned from it will be - * assigned to the record's `primaryKey`. - */ - generateIdForRecord( - store: Store, - type: ModelRegistry[K], - inputProperties: {} - ): string | number; - /** - * Proxies to the serializer's `serialize` method. - */ - serialize(snapshot: Snapshot, options: {}): {}; - /** - * Implement this method in a subclass to handle the creation of - * new records. - */ - createRecord( - store: Store, - type: ModelRegistry[K], - snapshot: Snapshot - ): RSVP.Promise; - /** - * Implement this method in a subclass to handle the updating of - * a record. - */ - updateRecord( - store: Store, - type: ModelRegistry[K], - snapshot: Snapshot - ): RSVP.Promise; - /** - * Implement this method in a subclass to handle the deletion of - * a record. - */ - deleteRecord( - store: Store, - type: ModelRegistry[K], - snapshot: Snapshot - ): RSVP.Promise; - /** - * By default the store will try to coalesce all `fetchRecord` calls within the same runloop - * into as few requests as possible by calling groupRecordsForFindMany and passing it into a findMany call. - * You can opt out of this behaviour by either not implementing the findMany hook or by setting - * coalesceFindRequests to false. - */ - coalesceFindRequests: boolean; - /** - * The store will call `findMany` instead of multiple `findRecord` - * requests to find multiple records at once if coalesceFindRequests - * is true. - */ - findMany( - store: Store, - type: ModelRegistry[K], - ids: any[], - snapshots: any[] - ): RSVP.Promise; - /** - * Organize records into groups, each of which is to be passed to separate - * calls to `findMany`. - */ - groupRecordsForFindMany(store: Store, snapshots: any[]): any[]; - /** - * This method is used by the store to determine if the store should - * reload a record from the adapter when a record is requested by - * `store.findRecord`. - */ - shouldReloadRecord(store: Store, snapshot: Snapshot): boolean; - /** - * This method is used by the store to determine if the store should - * reload all records from the adapter when records are requested by - * `store.findAll`. - */ - shouldReloadAll( - store: Store, - snapshotRecordArray: SnapshotRecordArray - ): boolean; - /** - * This method is used by the store to determine if the store should - * reload a record after the `store.findRecord` method resolves a - * cached record. - */ - shouldBackgroundReloadRecord( - store: Store, - snapshot: Snapshot - ): boolean; - /** - * This method is used by the store to determine if the store should - * reload a record array after the `store.findAll` method resolves - * with a cached record array. - */ - shouldBackgroundReloadAll( - store: Store, - snapshotRecordArray: SnapshotRecordArray - ): boolean; - } - /** - * `DS.Serializer` is an abstract base class that you should override in your - * application to customize it for your backend. The minimum set of methods - * that you should implement is: - */ - class Serializer extends Ember.Object { - /** - * The `store` property is the application's `store` that contains - * all records. It can be used to look up serializers for other model - * types that may be nested inside the payload response. - */ - store: Store; - /** - * The `normalizeResponse` method is used to normalize a payload from the - * server to a JSON-API Document. - */ - normalizeResponse( - store: Store, - primaryModelClass: Model, - payload: {}, - id: string | number, - requestType: string - ): {}; - /** - * The `serialize` method is used when a record is saved in order to convert - * the record into the form that your external data source expects. - */ - serialize(snapshot: Snapshot, options: {}): {}; - /** - * The `normalize` method is used to convert a payload received from your - * external data source into the normalized form `store.push()` expects. You - * should override this method, munge the hash and return the normalized - * payload. - */ - normalize(typeClass: Model, hash: {}): {}; - } - } - - export default DS; +export interface ModelRegistry {} +export interface AdapterRegistry {} +export interface SerializerRegistry {} +export interface TransformRegistry { + string: string; + boolean: boolean; + number: number; + date: Date; } -declare module 'ember' { - import DS from 'ember-data'; - namespace Ember { - /* - * The store is automatically injected into these objects - * - * https://github.com/emberjs/data/blob/05e95280e11c411177f2fbcb65fd83488d6a9d89/addon/setup-container.js#L71-L78 - */ - interface Route { - store: DS.Store; - } - interface Controller { - store: DS.Store; - } - interface DataAdapter { - store: DS.Store; - } +type AttributesFor = keyof Model; // TODO: filter to attr properties only (TS 2.8) +type RelationshipsFor = keyof Model; // TODO: filter to hasMany/belongsTo properties only (TS 2.8) + +export interface ChangedAttributes { + [key: string]: [any, any] | undefined; +} +interface AttributeMeta { + type: keyof TransformRegistry; + options: object; + name: AttributesFor; + parentType: Model; + isAttribute: true; +} +interface RelationshipMeta { + key: RelationshipsFor; + kind: 'belongsTo' | 'hasMany'; + type: keyof ModelRegistry; + options: object; + name: string; + parentType: Model; + isRelationship: true; +} + +export namespace DS { + /** + * Convert an hash of errors into an array with errors in JSON-API format. + */ + function errorsHashToArray(errors: {}): any[]; + /** + * Convert an array of errors in JSON-API format into an object. + */ + function errorsArrayToHash(errors: any[]): {}; + + interface RelationshipOptions { + async?: boolean; + inverse?: RelationshipsFor | null; + polymorphic?: boolean; } - // It is also available to inject anywhere - module '@ember/service' { - interface Registry { - 'store': DS.Store; - } + interface Sync { + async: false; + } + interface Async { + async?: true; + } + + /** + * `DS.belongsTo` is used to define One-To-One and One-To-Many + * relationships on a [DS.Model](/api/data/classes/DS.Model.html). + */ + function belongsTo( + modelName: K, + options: RelationshipOptions & Sync + ): Ember.ComputedProperty; + function belongsTo( + modelName: K, + options?: RelationshipOptions & Async + ): Ember.ComputedProperty< + ModelRegistry[K] & PromiseObject, + ModelRegistry[K] + >; + /** + * `DS.hasMany` is used to define One-To-Many and Many-To-Many + * relationships on a [DS.Model](/api/data/classes/DS.Model.html). + */ + function hasMany( + type: K, + options: RelationshipOptions & Sync + ): Ember.ComputedProperty>; + function hasMany( + type: K, + options?: RelationshipOptions & Async + ): Ember.ComputedProperty< + PromiseManyArray, + Ember.Array + >; + /** + * This method normalizes a modelName into the format Ember Data uses + * internally. + */ + function normalizeModelName( + modelName: K + ): string; + const VERSION: string; + + interface AttrOptions { + defaultValue?: T | (() => T); + allowNull?: boolean; // TODO: restrict to boolean transform (TS 2.8) + } + + /** + * `DS.attr` defines an attribute on a [DS.Model](/api/data/classes/DS.Model.html). + * By default, attributes are passed through as-is, however you can specify an + * optional type to have the value automatically transformed. + * Ember Data ships with four basic transform types: `string`, `number`, + * `boolean` and `date`. You can define your own transforms by subclassing + * [DS.Transform](/api/data/classes/DS.Transform.html). + */ + function attr( + type: K, + options?: AttrOptions + ): Ember.ComputedProperty; + function attr(options?: AttrOptions): Ember.ComputedProperty; + /** + * WARNING: This interface is likely to change in order to accomodate https://github.com/emberjs/rfcs/pull/4 + * ## Using BuildURLMixin + * To use url building, include the mixin when extending an adapter, and call `buildURL` where needed. + * The default behaviour is designed for RESTAdapter. + * ### Example + * ```javascript + * export default DS.Adapter.extend(BuildURLMixin, { + * findRecord: function(store, type, id, snapshot) { + * var url = this.buildURL(type.modelName, id, snapshot, 'findRecord'); + * return this.ajax(url, 'GET'); + * } + * }); + * ``` + * ### Attributes + * The `host` and `namespace` attributes will be used if defined, and are optional. + */ + class BuildURLMixin { + /** + * Builds a URL for a given type and optional ID. + */ + buildURL( + modelName?: K, + id?: string | any[] | {} | null, + snapshot?: Snapshot | any[] | null, + requestType?: string, + query?: {} + ): string; + /** + * Builds a URL for a `store.findRecord(type, id)` call. + */ + urlForFindRecord( + id: string, + modelName: K, + snapshot: Snapshot + ): string; + /** + * Builds a URL for a `store.findAll(type)` call. + */ + urlForFindAll( + modelName: K, + snapshot: SnapshotRecordArray + ): string; + /** + * Builds a URL for a `store.query(type, query)` call. + */ + urlForQuery( + query: {}, + modelName: K + ): string; + /** + * Builds a URL for a `store.queryRecord(type, query)` call. + */ + urlForQueryRecord( + query: {}, + modelName: K + ): string; + /** + * Builds a URL for coalesceing multiple `store.findRecord(type, id)` + * records into 1 request when the adapter's `coalesceFindRequests` + * property is true. + */ + urlForFindMany( + ids: any[], + modelName: K, + snapshots: any[] + ): string; + /** + * Builds a URL for fetching a async hasMany relationship when a url + * is not provided by the server. + */ + urlForFindHasMany( + id: string, + modelName: K, + snapshot: Snapshot + ): string; + /** + * Builds a URL for fetching a async belongsTo relationship when a url + * is not provided by the server. + */ + urlForFindBelongsTo( + id: string, + modelName: K, + snapshot: Snapshot + ): string; + /** + * Builds a URL for a `record.save()` call when the record was created + * locally using `store.createRecord()`. + */ + urlForCreateRecord( + modelName: K, + snapshot: Snapshot + ): string; + /** + * Builds a URL for a `record.save()` call when the record has been update locally. + */ + urlForUpdateRecord( + id: string, + modelName: K, + snapshot: Snapshot + ): string; + /** + * Builds a URL for a `record.save()` call when the record has been deleted locally. + */ + urlForDeleteRecord( + id: string, + modelName: K, + snapshot: Snapshot + ): string; + /** + * Determines the pathname for a given type. + */ + pathForType(modelName: K): string; + } + /** + * A `DS.AdapterError` is used by an adapter to signal that an error occurred + * during a request to an external API. It indicates a generic error, and + * subclasses are used to indicate specific error states. The following + * subclasses are provided: + */ + class AdapterError extends Ember.Object {} + /** + * A `DS.InvalidError` is used by an adapter to signal the external API + * was unable to process a request because the content was not + * semantically correct or meaningful per the API. Usually this means a + * record failed some form of server side validation. When a promise + * from an adapter is rejected with a `DS.InvalidError` the record will + * transition to the `invalid` state and the errors will be set to the + * `errors` property on the record. + */ + class InvalidError extends AdapterError { + constructor(errors: any[]); + } + /** + * A `DS.TimeoutError` is used by an adapter to signal that a request + * to the external API has timed out. I.e. no response was received from + * the external API within an allowed time period. + */ + class TimeoutError extends AdapterError {} + /** + * A `DS.AbortError` is used by an adapter to signal that a request to + * the external API was aborted. For example, this can occur if the user + * navigates away from the current page after a request to the external API + * has been initiated but before a response has been received. + */ + class AbortError extends AdapterError {} + /** + * A `DS.UnauthorizedError` equates to a HTTP `401 Unauthorized` response + * status. It is used by an adapter to signal that a request to the external + * API was rejected because authorization is required and has failed or has not + * yet been provided. + */ + class UnauthorizedError extends AdapterError {} + /** + * A `DS.ForbiddenError` equates to a HTTP `403 Forbidden` response status. + * It is used by an adapter to signal that a request to the external API was + * valid but the server is refusing to respond to it. If authorization was + * provided and is valid, then the authenticated user does not have the + * necessary permissions for the request. + */ + class ForbiddenError extends AdapterError {} + /** + * A `DS.NotFoundError` equates to a HTTP `404 Not Found` response status. + * It is used by an adapter to signal that a request to the external API + * was rejected because the resource could not be found on the API. + */ + class NotFoundError extends AdapterError {} + /** + * A `DS.ConflictError` equates to a HTTP `409 Conflict` response status. + * It is used by an adapter to indicate that the request could not be processed + * because of a conflict in the request. An example scenario would be when + * creating a record with a client generated id but that id is already known + * to the external API. + */ + class ConflictError extends AdapterError {} + /** + * A `DS.ServerError` equates to a HTTP `500 Internal Server Error` response + * status. It is used by the adapter to indicate that a request has failed + * because of an error in the external API. + */ + class ServerError extends AdapterError {} + /** + * Holds validation errors for a given record, organized by attribute names. + */ + interface Errors extends Ember.Enumerable, Evented {} + class Errors extends Ember.Object { + /** + * DEPRECATED: + * Register with target handler + */ + registerHandlers( + target: {}, + becameInvalid: Function, + becameValid: Function + ): any; + /** + * Returns errors for a given attribute + */ + errorsFor(attribute: string): any[]; + /** + * An array containing all of the error messages for this + * record. This is useful for displaying all errors to the user. + */ + messages: Ember.ComputedProperty; + /** + * Total number of errors. + */ + length: Ember.ComputedProperty; + isEmpty: Ember.ComputedProperty; + /** + * DEPRECATED: + * Adds error messages to a given attribute and sends + * `becameInvalid` event to the record. + */ + add(attribute: string, messages: any[] | string): any; + /** + * DEPRECATED: + * Removes all error messages from the given attribute and sends + * `becameValid` event to the record if there no more errors left. + */ + remove(attribute: string): any; + /** + * DEPRECATED: + * Removes all error messages and sends `becameValid` event + * to the record. + */ + clear(): any; + /** + * Checks if there is error messages for the given attribute. + */ + has(attribute: string): boolean; + } + /** + * The model class that all Ember Data records descend from. + * This is the public API of Ember Data models. If you are using Ember Data + * in your application, this is the class you should use. + * If you are working on Ember Data internals, you most likely want to be dealing + * with `InternalModel` + */ + class Model extends Ember.Object { + /** + * If this property is `true` the record is in the `empty` + * state. Empty is the first state all records enter after they have + * been created. Most records created by the store will quickly + * transition to the `loading` state if data needs to be fetched from + * the server or the `created` state if the record is created on the + * client. A record can also enter the empty state if the adapter is + * unable to locate the record. + */ + isEmpty: Ember.ComputedProperty; + /** + * If this property is `true` the record is in the `loading` state. A + * record enters this state when the store asks the adapter for its + * data. It remains in this state until the adapter provides the + * requested data. + */ + isLoading: Ember.ComputedProperty; + /** + * If this property is `true` the record is in the `loaded` state. A + * record enters this state when its data is populated. Most of a + * record's lifecycle is spent inside substates of the `loaded` + * state. + */ + isLoaded: Ember.ComputedProperty; + /** + * If this property is `true` the record is in the `dirty` state. The + * record has local changes that have not yet been saved by the + * adapter. This includes records that have been created (but not yet + * saved) or deleted. + */ + hasDirtyAttributes: Ember.ComputedProperty; + /** + * If this property is `true` the record is in the `saving` state. A + * record enters the saving state when `save` is called, but the + * adapter has not yet acknowledged that the changes have been + * persisted to the backend. + */ + isSaving: Ember.ComputedProperty; + /** + * If this property is `true` the record is in the `deleted` state + * and has been marked for deletion. When `isDeleted` is true and + * `hasDirtyAttributes` is true, the record is deleted locally but the deletion + * was not yet persisted. When `isSaving` is true, the change is + * in-flight. When both `hasDirtyAttributes` and `isSaving` are false, the + * change has persisted. + */ + isDeleted: Ember.ComputedProperty; + /** + * If this property is `true` the record is in the `new` state. A + * record will be in the `new` state when it has been created on the + * client and the adapter has not yet report that it was successfully + * saved. + */ + isNew: Ember.ComputedProperty; + /** + * If this property is `true` the record is in the `valid` state. + */ + isValid: Ember.ComputedProperty; + /** + * If the record is in the dirty state this property will report what + * kind of change has caused it to move into the dirty + * state. Possible values are: + */ + dirtyType: Ember.ComputedProperty; + /** + * If `true` the adapter reported that it was unable to save local + * changes to the backend for any reason other than a server-side + * validation error. + */ + isError: boolean; + /** + * If `true` the store is attempting to reload the record from the adapter. + */ + isReloading: boolean; + /** + * All ember models have an id property. This is an identifier + * managed by an external source. These are always coerced to be + * strings before being used internally. Note when declaring the + * attributes for a model it is an error to declare an id + * attribute. + */ + id: string; + /** + * When the record is in the `invalid` state this object will contain + * any errors returned by the adapter. When present the errors hash + * contains keys corresponding to the invalid property names + * and values which are arrays of Javascript objects with two keys: + */ + errors: Ember.ComputedProperty; + /** + * This property holds the `DS.AdapterError` object with which + * last adapter operation was rejected. + */ + adapterError: AdapterError; + /** + * Create a JSON representation of the record, using the serialization + * strategy of the store's adapter. + */ + serialize(options?: { includeId?: boolean }): {}; + /** + * Use [DS.JSONSerializer](DS.JSONSerializer.html) to + * get the JSON representation of a record. + */ + toJSON(options: {}): {}; + /** + * Fired when the record is ready to be interacted with, + * that is either loaded from the server or created locally. + */ + ready(): void; + /** + * Fired when the record is loaded from the server. + */ + didLoad(): void; + /** + * Fired when the record is updated. + */ + didUpdate(): void; + /** + * Fired when a new record is commited to the server. + */ + didCreate(): void; + /** + * Fired when the record is deleted. + */ + didDelete(): void; + /** + * Fired when the record becomes invalid. + */ + becameInvalid(): void; + /** + * Fired when the record enters the error state. + */ + becameError(): void; + /** + * Fired when the record is rolled back. + */ + rolledBack(): void; + /** + * Marks the record as deleted but does not save it. You must call + * `save` afterwards if you want to persist it. You might use this + * method if you want to allow the user to still `rollbackAttributes()` + * after a delete was made. + */ + deleteRecord(): any; + /** + * Same as `deleteRecord`, but saves the record immediately. + */ + destroyRecord(options?: {}): RSVP.Promise; + /** + * Unloads the record from the store. This will cause the record to be destroyed and freed up for garbage collection. + */ + unloadRecord(): any; + /** + * Returns an object, whose keys are changed properties, and value is + * an [oldProp, newProp] array. + */ + changedAttributes(): ChangedAttributes; + /** + * If the model `hasDirtyAttributes` this function will discard any unsaved + * changes. If the model `isNew` it will be removed from the store. + */ + rollbackAttributes(): any; + /** + * Save the record and persist any changes to the record to an + * external source via the adapter. + */ + save(options?: {}): RSVP.Promise; + /** + * Reload the record from the adapter. + */ + reload(): RSVP.Promise; + /** + * Get the reference for the specified belongsTo relationship. + */ + belongsTo(name: RelationshipsFor): BelongsToReference; + /** + * Get the reference for the specified hasMany relationship. + */ + hasMany(name: RelationshipsFor): HasManyReference; + /** + * Given a callback, iterates over each of the relationships in the model, + * invoking the callback with the name of each relationship and its relationship + * descriptor. + */ + eachRelationship( + callback: (name: string, details: RelationshipMeta) => void, + binding?: any + ): any; + /** + * Represents the model's class name as a string. This can be used to look up the model's class name through + * `DS.Store`'s modelFor method. + */ + static modelName: keyof ModelRegistry; + /** + * For a given relationship name, returns the model type of the relationship. + */ + static typeForRelationship( + name: K, + store: Store + ): ModelRegistry[K]; + /** + * Find the relationship which is the inverse of the one asked for. + */ + static inverseFor( + name: K, + store: Store + ): {}; + /** + * The model's relationships as a map, keyed on the type of the + * relationship. The value of each entry is an array containing a descriptor + * for each relationship with that type, describing the name of the relationship + * as well as the type. + */ + static relationships: Ember.ComputedProperty; + /** + * A hash containing lists of the model's relationships, grouped + * by the relationship kind. For example, given a model with this + * definition: + */ + static relationshipNames: Ember.ComputedProperty<{}>; + /** + * An array of types directly related to a model. Each type will be + * included once, regardless of the number of relationships it has with + * the model. + */ + static relatedTypes: Ember.ComputedProperty>; + /** + * A map whose keys are the relationships of a model and whose values are + * relationship descriptors. + */ + static relationshipsByName: Ember.ComputedProperty; + /** + * A map whose keys are the fields of the model and whose values are strings + * describing the kind of the field. A model's fields are the union of all of its + * attributes and relationships. + */ + static fields: Ember.ComputedProperty; + /** + * Given a callback, iterates over each of the relationships in the model, + * invoking the callback with the name of each relationship and its relationship + * descriptor. + */ + static eachRelationship( + callback: (name: string, details: RelationshipMeta) => void, + binding?: any + ): any; + /** + * Given a callback, iterates over each of the types related to a model, + * invoking the callback with the related type's class. Each type will be + * returned just once, regardless of how many different relationships it has + * with a model. + */ + static eachRelatedType(callback: Function, binding: any): any; + /** + * A map whose keys are the attributes of the model (properties + * described by DS.attr) and whose values are the meta object for the + * property. + */ + static attributes: Ember.ComputedProperty; + /** + * A map whose keys are the attributes of the model (properties + * described by DS.attr) and whose values are type of transformation + * applied to each attribute. This map does not include any + * attributes that do not have an transformation type. + */ + static transformedAttributes: Ember.ComputedProperty; + /** + * Iterates through the attributes of the model, calling the passed function on each + * attribute. + */ + static eachAttribute(callback: Function, binding: {}): any; + /** + * Iterates through the transformedAttributes of the model, calling + * the passed function on each attribute. Note the callback will not be + * called for any attributes that do not have an transformation type. + */ + static eachTransformedAttribute(callback: Function, binding: {}): any; + /** + * Discards any unsaved changes to the given attribute. This feature is not enabled by default. You must enable `ds-rollback-attribute` and be running a canary build. + */ + rollbackAttribute(): any; + /** + * This Ember.js hook allows an object to be notified when a property + * is defined. + */ + didDefineProperty( + proto: {}, + key: string, + value: Ember.ComputedProperty + ): any; + } + /** + * ### State + */ + class RootState {} + /** + * Represents an ordered list of records whose order and membership is + * determined by the adapter. For example, a query sent to the adapter + * may trigger a search on the server, whose results would be loaded + * into an instance of the `AdapterPopulatedRecordArray`. + */ + class AdapterPopulatedRecordArray extends RecordArray {} + /** + * Represents a list of records whose membership is determined by the + * store. As records are created, loaded, or modified, the store + * evaluates them to determine if they should be part of the record + * array. + */ + class FilteredRecordArray extends RecordArray { + /** + * The filterFunction is a function used to test records from the store to + * determine if they should be part of the record array. + */ + filterFunction(record: Model): boolean; + } + /** + * A record array is an array that contains records of a certain modelName. The record + * array materializes records as needed when they are retrieved for the first + * time. You should not create record arrays yourself. Instead, an instance of + * `DS.RecordArray` or its subclasses will be returned by your application's store + * in response to queries. + */ + interface RecordArray extends Ember.ArrayProxy, Evented {} + class RecordArray { + /** + * The flag to signal a `RecordArray` is finished loading data. + */ + isLoaded: boolean; + /** + * The flag to signal a `RecordArray` is currently loading data. + */ + isUpdating: boolean; + /** + * The modelClass represented by this record array. + */ + type: Ember.ComputedProperty; + /** + * Used to get the latest version of all of the records in this array + * from the adapter. + */ + update(): any; + /** + * Saves all of the records in the `RecordArray`. + */ + save(): PromiseArray; + } + /** + * A BelongsToReference is a low level API that allows users and + * addon author to perform meta-operations on a belongs-to + * relationship. + */ + class BelongsToReference { + /** + * This returns a string that represents how the reference will be + * looked up when it is loaded. If the relationship has a link it will + * use the "link" otherwise it defaults to "id". + */ + remoteType(): string; + /** + * The `id` of the record that this reference refers to. Together, the + * `type()` and `id()` methods form a composite key for the identity + * map. This can be used to access the id of an async relationship + * without triggering a fetch that would normally happen if you + * attempted to use `record.get('relationship.id')`. + */ + id(): string; + /** + * The link Ember Data will use to fetch or reload this belongs-to + * relationship. + */ + link(): string; + /** + * The meta data for the belongs-to relationship. + */ + meta(): {}; + /** + * `push` can be used to update the data in the relationship and Ember + * Data will treat the new data as the conanical value of this + * relationship on the backend. + */ + push(objectOrPromise: {} | RSVP.Promise): RSVP.Promise; + /** + * `value()` synchronously returns the current value of the belongs-to + * relationship. Unlike `record.get('relationshipName')`, calling + * `value()` on a reference does not trigger a fetch if the async + * relationship is not yet loaded. If the relationship is not loaded + * it will always return `null`. + */ + value(objectOrPromise: {} | RSVP.Promise): Model; + /** + * Loads a record in a belongs to relationship if it is not already + * loaded. If the relationship is already loaded this method does not + * trigger a new load. + */ + load(): RSVP.Promise; + /** + * Triggers a reload of the value in this relationship. If the + * remoteType is `"link"` Ember Data will use the relationship link to + * reload the relationship. Otherwise it will reload the record by its + * id. + */ + reload(): RSVP.Promise; + } + /** + * A HasManyReference is a low level API that allows users and addon + * author to perform meta-operations on a has-many relationship. + */ + class HasManyReference { + /** + * This returns a string that represents how the reference will be + * looked up when it is loaded. If the relationship has a link it will + * use the "link" otherwise it defaults to "id". + */ + remoteType(): string; + /** + * The link Ember Data will use to fetch or reload this has-many + * relationship. + */ + link(): string; + /** + * `ids()` returns an array of the record ids in this relationship. + */ + ids(): any[]; + /** + * The meta data for the has-many relationship. + */ + meta(): {}; + /** + * `push` can be used to update the data in the relationship and Ember + * Data will treat the new data as the canonical value of this + * relationship on the backend. + */ + push(objectOrPromise: T[] | RSVP.Promise): ManyArray; + /** + * `value()` synchronously returns the current value of the has-many + * relationship. Unlike `record.get('relationshipName')`, calling + * `value()` on a reference does not trigger a fetch if the async + * relationship is not yet loaded. If the relationship is not loaded + * it will always return `null`. + */ + value(): ManyArray; + /** + * Loads the relationship if it is not already loaded. If the + * relationship is already loaded this method does not trigger a new + * load. + */ + load(): RSVP.Promise; + /** + * Reloads this has-many relationship. + */ + reload(): RSVP.Promise; + } + /** + * An RecordReference is a low level API that allows users and + * addon author to perform meta-operations on a record. + */ + class RecordReference { + /** + * The `id` of the record that this reference refers to. + */ + id(): string; + /** + * How the reference will be looked up when it is loaded: Currently + * this always return `identity` to signifying that a record will be + * loaded by the `type` and `id`. + */ + remoteType(): string; + /** + * This API allows you to provide a reference with new data. The + * simplest usage of this API is similar to `store.push`: you provide a + * normalized hash of data and the object represented by the reference + * will update. + */ + push(payload: RSVP.Promise | {}): PromiseObject & T; + /** + * If the entity referred to by the reference is already loaded, it is + * present as `reference.value`. Otherwise the value returned by this function + * is `null`. + */ + value(): T | null; + /** + * Triggers a fetch for the backing entity based on its `remoteType` + * (see `remoteType` definitions per reference type). + */ + load(): PromiseObject & T; + /** + * Reloads the record if it is already loaded. If the record is not + * loaded it will load the record via `store.findRecord` + */ + reload(): PromiseObject & T; + } + /** + * A `ManyArray` is a `MutableArray` that represents the contents of a has-many + * relationship. + */ + interface ManyArray extends Ember.MutableArray {} + class ManyArray extends Ember.Object.extend( + Ember.MutableArray as {}, + Ember.Evented + ) { + /** + * The loading state of this array + */ + isLoaded: boolean; + /** + * Metadata associated with the request for async hasMany relationships. + */ + meta: {}; + /** + * Reloads all of the records in the manyArray. If the manyArray + * holds a relationship that was originally fetched using a links url + * Ember Data will revisit the original links url to repopulate the + * relationship. + */ + reload(): PromiseArray; + /** + * Saves all of the records in the `ManyArray`. + */ + save(): PromiseArray; + /** + * Create a child record within the owner + */ + createRecord(inputProperties?: {}): T; + } + /** + * A `PromiseArray` is an object that acts like both an `Ember.Array` + * and a promise. When the promise is resolved the resulting value + * will be set to the `PromiseArray`'s `content` property. This makes + * it easy to create data bindings with the `PromiseArray` that will be + * updated when the promise resolves. + */ + interface PromiseArray + extends Ember.ArrayProxy, + PromiseProxyMixin> {} + class PromiseArray {} + /** + * A `PromiseObject` is an object that acts like both an `Ember.Object` + * and a promise. When the promise is resolved, then the resulting value + * will be set to the `PromiseObject`'s `content` property. This makes + * it easy to create data bindings with the `PromiseObject` that will + * be updated when the promise resolves. + */ + interface PromiseObject + extends ObjectProxy, + PromiseProxyMixin {} + class PromiseObject {} + /** + * A PromiseManyArray is a PromiseArray that also proxies certain method calls + * to the underlying manyArray. + * Right now we proxy: + */ + class PromiseManyArray extends PromiseArray { + /** + * Reloads all of the records in the manyArray. If the manyArray + * holds a relationship that was originally fetched using a links url + * Ember Data will revisit the original links url to repopulate the + * relationship. + */ + reload(): PromiseManyArray; + /** + * Create a child record within the owner + */ + createRecord(inputProperties?: {}): T; + } + class SnapshotRecordArray { + /** + * Number of records in the array + */ + length: number; + /** + * Meta objects for the record array. + */ + meta: {}; + /** + * A hash of adapter options passed into the store method for this request. + */ + adapterOptions: {}; + /** + * The relationships to include for this request. + */ + include: string | any[]; + /** + * The type of the underlying records for the snapshots in the array, as a DS.Model + */ + type: ModelRegistry[K]; + /** + * Get snapshots of the underlying record array + */ + snapshots(): any[]; + } + class Snapshot { + /** + * The underlying record for this snapshot. Can be used to access methods and + * properties defined on the record. + */ + record: ModelRegistry[K]; + /** + * The id of the snapshot's underlying record + */ + id: string; + /** + * A hash of adapter options + */ + adapterOptions: {}; + /** + * The name of the type of the underlying record for this snapshot, as a string. + */ + modelName: K; + /** + * The type of the underlying record for this snapshot, as a DS.Model. + */ + type: ModelRegistry[K]; + /** + * Returns the value of an attribute. + */ + attr>( + keyName: L + ): ModelRegistry[K][L]; + /** + * Returns all attributes and their corresponding values. + */ + attributes(): { [L in keyof ModelRegistry[K]]: ModelRegistry[K][L] }; + /** + * Returns all changed attributes and their old and new values. + */ + changedAttributes(): Partial< + { [L in keyof ModelRegistry[K]]: ModelRegistry[K][L] } + >; + /** + * Returns the current value of a belongsTo relationship. + */ + belongsTo>( + keyName: L, + options?: {} + ): Snapshot['record'][L] | string | null | undefined; + /** + * Returns the current value of a hasMany relationship. + */ + hasMany>( + keyName: L, + options?: { ids: false } + ): Array['record'][L]> | undefined; + hasMany>( + keyName: L, + options: { ids: true } + ): string[] | undefined; + /** + * Iterates through all the attributes of the model, calling the passed + * function on each attribute. + */ + eachAttribute( + callback: (key: keyof M, meta: AttributeMeta) => void, + binding?: {} + ): any; + /** + * Iterates through all the relationships of the model, calling the passed + * function on each relationship. + */ + eachRelationship( + callback: (key: keyof M, meta: RelationshipMeta) => void, + binding?: {} + ): any; + /** + * Serializes the snapshot using the serializer for the model. + */ + serialize(options: {}): {}; + } + + /** + * The store contains all of the data for records loaded from the server. + * It is also responsible for creating instances of `DS.Model` that wrap + * the individual data for a record, so that they can be bound to in your + * Handlebars templates. + */ + class Store { + /** + * The default adapter to use to communicate to a backend server or + * other persistence layer. This will be overridden by an application + * adapter if present. + */ + adapter: string; + /** + * Create a new record in the current store. The properties passed + * to this method are set on the newly created record. + */ + createRecord( + modelName: K, + inputProperties?: {} + ): ModelRegistry[K]; + /** + * For symmetry, a record can be deleted via the store. + */ + deleteRecord(record: Model): void; + /** + * For symmetry, a record can be unloaded via the store. + * This will cause the record to be destroyed and freed up for garbage collection. + */ + unloadRecord(record: Model): void; + /** + * This method returns a record for a given type and id combination. + */ + findRecord( + modelName: K, + id: string | number, + options?: {} + ): PromiseObject & ModelRegistry[K]; + /** + * Get the reference for the specified record. + */ + getReference( + modelName: K, + id: string | number + ): RecordReference; + /** + * Get a record by a given type and ID without triggering a fetch. + */ + peekRecord( + modelName: K, + id: string | number + ): ModelRegistry[K] | null; + /** + * This method returns true if a record for a given modelName and id is already + * loaded in the store. Use this function to know beforehand if a findRecord() + * will result in a request or that it will be a cache hit. + */ + hasRecordForId( + modelName: K, + id: string | number + ): boolean; + /** + * This method delegates a query to the adapter. This is the one place where + * adapter-level semantics are exposed to the application. + */ + query( + modelName: K, + query: any + ): AdapterPopulatedRecordArray & + PromiseArray; + /** + * This method makes a request for one record, where the `id` is not known + * beforehand (if the `id` is known, use [`findRecord`](#method_findRecord) + * instead). + */ + queryRecord( + modelName: K, + query: any + ): RSVP.Promise; + /** + * `findAll` asks the adapter's `findAll` method to find the records for the + * given type, and returns a promise which will resolve with all records of + * this type present in the store, even if the adapter only returns a subset + * of them. + */ + findAll( + modelName: K, + options?: { + reload?: boolean; + backgroundReload?: boolean; + include?: string; + adapterOptions?: any; + } + ): PromiseArray; + /** + * This method returns a filtered array that contains all of the + * known records for a given type in the store. + */ + peekAll( + modelName: K + ): RecordArray; + /** + * This method unloads all records in the store. + * It schedules unloading to happen during the next run loop. + */ + unloadAll(modelName: K): void; + /** + * DEPRECATED: + * This method has been deprecated and is an alias for store.hasRecordForId, which should + * be used instead. + */ + recordIsLoaded( + modelName: K, + id: string + ): boolean; + /** + * Returns the model class for the particular `modelName`. + */ + modelFor(modelName: K): ModelRegistry[K]; + /** + * Push some data for a given type into the store. + */ + push(data: {}): Model | any[]; + /** + * Push some raw data into the store. + */ + pushPayload( + modelName: K, + inputPayload: {} + ): any; + pushPayload(inputPayload: {}): any; + /** + * `normalize` converts a json payload into the normalized form that + * [push](#method_push) expects. + */ + normalize(modelName: K, payload: {}): {}; + /** + * Returns an instance of the adapter for a given type. For + * example, `adapterFor('person')` will return an instance of + * `App.PersonAdapter`. + */ + adapterFor( + modelName: K + ): AdapterRegistry[K]; + /** + * Returns an instance of the serializer for a given type. For + * example, `serializerFor('person')` will return an instance of + * `App.PersonSerializer`. + */ + serializerFor( + modelName: K + ): SerializerRegistry[K]; + } + /** + * The `JSONAPIAdapter` is the default adapter used by Ember Data. It + * is responsible for transforming the store's requests into HTTP + * requests that follow the [JSON API](http://jsonapi.org/format/) + * format. + */ + class JSONAPIAdapter extends RESTAdapter { + /** + * By default the JSONAPIAdapter will send each find request coming from a `store.find` + * or from accessing a relationship separately to the server. If your server supports passing + * ids as a query string, you can set coalesceFindRequests to true to coalesce all find requests + * within a single runloop. + */ + coalesceFindRequests: boolean; + } + /** + * The REST adapter allows your store to communicate with an HTTP server by + * transmitting JSON via XHR. Most Ember.js apps that consume a JSON API + * should use the REST adapter. + */ + class RESTAdapter extends Adapter implements BuildURLMixin { + /** + * Takes a URL, an HTTP method and a hash of data, and makes an HTTP request. + */ + ajax(url: string, type: string, options?: object): RSVP.Promise; + /** + * Generate ajax options + */ + ajaxOptions(url: string, type: string, options?: object): object; + /** + * By default, the RESTAdapter will send the query params sorted alphabetically to the + * server. + */ + sortQueryParams(obj: {}): {}; + /** + * By default the RESTAdapter will send each find request coming from a `store.find` + * or from accessing a relationship separately to the server. If your server supports passing + * ids as a query string, you can set coalesceFindRequests to true to coalesce all find requests + * within a single runloop. + */ + coalesceFindRequests: boolean; + /** + * Endpoint paths can be prefixed with a `namespace` by setting the namespace + * property on the adapter: + */ + namespace: string; + /** + * An adapter can target other hosts by setting the `host` property. + */ + host: string; + /** + * Some APIs require HTTP headers, e.g. to provide an API + * key. Arbitrary headers can be set as key/value pairs on the + * `RESTAdapter`'s `headers` object and Ember Data will send them + * along with each ajax request. For dynamic headers see [headers + * customization](/api/data/classes/DS.RESTAdapter.html#toc_headers-customization). + */ + headers: {}; + /** + * Called by the store in order to fetch the JSON for a given + * type and ID. + */ + findRecord( + store: Store, + type: ModelRegistry[K], + id: string, + snapshot: Snapshot + ): RSVP.Promise; + /** + * Called by the store in order to fetch a JSON array for all + * of the records for a given type. + */ + findAll( + store: Store, + type: ModelRegistry[K], + sinceToken: string, + snapshotRecordArray: SnapshotRecordArray + ): RSVP.Promise; + /** + * Called by the store in order to fetch a JSON array for + * the records that match a particular query. + */ + query( + store: Store, + type: ModelRegistry[K], + query: {} + ): RSVP.Promise; + /** + * Called by the store in order to fetch a JSON object for + * the record that matches a particular query. + */ + queryRecord( + store: Store, + type: ModelRegistry[K], + query: {} + ): RSVP.Promise; + /** + * Called by the store in order to fetch several records together if `coalesceFindRequests` is true + */ + findMany( + store: Store, + type: ModelRegistry[K], + ids: any[], + snapshots: any[] + ): RSVP.Promise; + /** + * Called by the store in order to fetch a JSON array for + * the unloaded records in a has-many relationship that were originally + * specified as a URL (inside of `links`). + */ + findHasMany( + store: Store, + snapshot: Snapshot, + url: string, + relationship: {} + ): RSVP.Promise; + /** + * Called by the store in order to fetch the JSON for the unloaded record in a + * belongs-to relationship that was originally specified as a URL (inside of + * `links`). + */ + findBelongsTo( + store: Store, + snapshot: Snapshot, + url: string + ): RSVP.Promise; + /** + * Called by the store when a newly created record is + * saved via the `save` method on a model record instance. + */ + createRecord( + store: Store, + type: ModelRegistry[K], + snapshot: Snapshot + ): RSVP.Promise; + /** + * Called by the store when an existing record is saved + * via the `save` method on a model record instance. + */ + updateRecord( + store: Store, + type: ModelRegistry[K], + snapshot: Snapshot + ): RSVP.Promise; + /** + * Called by the store when a record is deleted. + */ + deleteRecord( + store: Store, + type: ModelRegistry[K], + snapshot: Snapshot + ): RSVP.Promise; + /** + * Organize records into groups, each of which is to be passed to separate + * calls to `findMany`. + */ + groupRecordsForFindMany(store: Store, snapshots: any[]): any[]; + /** + * Takes an ajax response, and returns the json payload or an error. + */ + handleResponse( + status: number, + headers: {}, + payload: {}, + requestData: {} + ): {}; + /** + * Default `handleResponse` implementation uses this hook to decide if the + * response is a success. + */ + isSuccess(status: number, headers: {}, payload: {}): boolean; + /** + * Default `handleResponse` implementation uses this hook to decide if the + * response is an invalid error. + */ + isInvalid(status: number, headers: {}, payload: {}): boolean; + /** + * Get the data (body or query params) for a request. + */ + dataForRequest(params: {}): {}; + /** + * Get the HTTP method for a request. + */ + methodForRequest(params: {}): string; + /** + * Get the URL for a request. + */ + urlForRequest(params: {}): string; + /** + * Get the headers for a request. + */ + headersForRequest(params: {}): {}; + /** + * Builds a URL for a given type and optional ID. + */ + buildURL( + modelName?: K, + id?: string | any[] | {} | null, + snapshot?: Snapshot | any[] | null, + requestType?: string, + query?: {} + ): string; + /** + * Builds a URL for a `store.findRecord(type, id)` call. + */ + urlForFindRecord( + id: string, + modelName: K, + snapshot: Snapshot + ): string; + /** + * Builds a URL for a `store.findAll(type)` call. + */ + urlForFindAll( + modelName: K, + snapshot: SnapshotRecordArray + ): string; + /** + * Builds a URL for a `store.query(type, query)` call. + */ + urlForQuery( + query: {}, + modelName: K + ): string; + /** + * Builds a URL for a `store.queryRecord(type, query)` call. + */ + urlForQueryRecord( + query: {}, + modelName: K + ): string; + /** + * Builds a URL for coalesceing multiple `store.findRecord(type, id)` + * records into 1 request when the adapter's `coalesceFindRequests` + * property is true. + */ + urlForFindMany( + ids: any[], + modelName: K, + snapshots: any[] + ): string; + /** + * Builds a URL for fetching a async hasMany relationship when a url + * is not provided by the server. + */ + urlForFindHasMany( + id: string, + modelName: K, + snapshot: Snapshot + ): string; + /** + * Builds a URL for fetching a async belongsTo relationship when a url + * is not provided by the server. + */ + urlForFindBelongsTo( + id: string, + modelName: K, + snapshot: Snapshot + ): string; + /** + * Builds a URL for a `record.save()` call when the record was created + * locally using `store.createRecord()`. + */ + urlForCreateRecord( + modelName: K, + snapshot: Snapshot + ): string; + /** + * Builds a URL for a `record.save()` call when the record has been update locally. + */ + urlForUpdateRecord( + id: string, + modelName: K, + snapshot: Snapshot + ): string; + /** + * Builds a URL for a `record.save()` call when the record has been deleted locally. + */ + urlForDeleteRecord( + id: string, + modelName: K, + snapshot: Snapshot + ): string; + /** + * Determines the pathname for a given type. + */ + pathForType(modelName: K): string; + } + /** + * ## Using Embedded Records + */ + class EmbeddedRecordsMixin { + /** + * Normalize the record and recursively normalize/extract all the embedded records + * while pushing them into the store as they are encountered + */ + normalize(typeClass: Model, hash: {}, prop: string): {}; + /** + * Serialize `belongsTo` relationship when it is configured as an embedded object. + */ + serializeBelongsTo( + snapshot: Snapshot, + json: {}, + relationship: {} + ): any; + /** + * Serializes `hasMany` relationships when it is configured as embedded objects. + */ + serializeHasMany( + snapshot: Snapshot, + json: {}, + relationship: {} + ): any; + /** + * When serializing an embedded record, modify the property (in the json payload) + * that refers to the parent record (foreign key for relationship). + */ + removeEmbeddedForeignKey( + snapshot: Snapshot, + embeddedSnapshot: Snapshot, + relationship: {}, + json: {} + ): any; + } + /** + * Ember Data 2.0 Serializer: + */ + class JSONAPISerializer extends JSONSerializer { + pushPayload(store: Store, payload: {}): any; + /** + * Dasherizes and singularizes the model name in the payload to match + * the format Ember Data uses internally for the model name. + */ + modelNameFromPayloadKey(key: string): string; + /** + * Converts the model name to a pluralized version of the model name. + */ + payloadKeyFromModelName( + modelName: K + ): string; + /** + * `keyForAttribute` can be used to define rules for how to convert an + * attribute name in your model to a key in your JSON. + * By default `JSONAPISerializer` follows the format used on the examples of + * http://jsonapi.org/format and uses dashes as the word separator in the JSON + * attribute keys. + */ + keyForAttribute(key: string, method: string): string; + /** + * `keyForRelationship` can be used to define a custom key when + * serializing and deserializing relationship properties. + * By default `JSONAPISerializer` follows the format used on the examples of + * http://jsonapi.org/format and uses dashes as word separators in + * relationship properties. + */ + keyForRelationship( + key: string, + typeClass: string, + method: string + ): string; + /** + * `modelNameFromPayloadType` can be used to change the mapping for a DS model + * name, taken from the value in the payload. + */ + modelNameFromPayloadType(payloadType: string): string; + /** + * `payloadTypeFromModelName` can be used to change the mapping for the type in + * the payload, taken from the model name. + */ + payloadTypeFromModelName( + modelName: K + ): string; + } + /** + * Ember Data 2.0 Serializer: + */ + class JSONSerializer extends Serializer { + /** + * The `primaryKey` is used when serializing and deserializing + * data. Ember Data always uses the `id` property to store the id of + * the record. The external source may not always follow this + * convention. In these cases it is useful to override the + * `primaryKey` property to match the `primaryKey` of your external + * store. + */ + primaryKey: string; + /** + * The `attrs` object can be used to declare a simple mapping between + * property names on `DS.Model` records and payload keys in the + * serialized JSON object representing the record. An object with the + * property `key` can also be used to designate the attribute's key on + * the response payload. + */ + attrs: {}; + /** + * The `normalizeResponse` method is used to normalize a payload from the + * server to a JSON-API Document. + */ + normalizeResponse( + store: Store, + primaryModelClass: Model, + payload: {}, + id: string | number, + requestType: string + ): {}; + normalizeFindRecordResponse( + store: Store, + primaryModelClass: Model, + payload: {}, + id: string | number, + requestType: string + ): {}; + normalizeQueryRecordResponse( + store: Store, + primaryModelClass: Model, + payload: {}, + id: string | number, + requestType: string + ): {}; + normalizeFindAllResponse( + store: Store, + primaryModelClass: Model, + payload: {}, + id: string | number, + requestType: string + ): {}; + normalizeFindBelongsToResponse( + store: Store, + primaryModelClass: Model, + payload: {}, + id: string | number, + requestType: string + ): {}; + normalizeFindHasManyResponse( + store: Store, + primaryModelClass: Model, + payload: {}, + id: string | number, + requestType: string + ): {}; + normalizeFindManyResponse( + store: Store, + primaryModelClass: Model, + payload: {}, + id: string | number, + requestType: string + ): {}; + normalizeQueryResponse( + store: Store, + primaryModelClass: Model, + payload: {}, + id: string | number, + requestType: string + ): {}; + normalizeCreateRecordResponse( + store: Store, + primaryModelClass: Model, + payload: {}, + id: string | number, + requestType: string + ): {}; + normalizeDeleteRecordResponse( + store: Store, + primaryModelClass: Model, + payload: {}, + id: string | number, + requestType: string + ): {}; + normalizeUpdateRecordResponse( + store: Store, + primaryModelClass: Model, + payload: {}, + id: string | number, + requestType: string + ): {}; + normalizeSaveResponse( + store: Store, + primaryModelClass: Model, + payload: {}, + id: string | number, + requestType: string + ): {}; + normalizeSingleResponse( + store: Store, + primaryModelClass: Model, + payload: {}, + id: string | number, + requestType: string + ): {}; + normalizeArrayResponse( + store: Store, + primaryModelClass: Model, + payload: {}, + id: string | number, + requestType: string + ): {}; + /** + * Normalizes a part of the JSON payload returned by + * the server. You should override this method, munge the hash + * and call super if you have generic normalization to do. + */ + normalize(typeClass: Model, hash: {}): {}; + /** + * Returns the resource's ID. + */ + extractId(modelClass: {}, resourceHash: {}): string; + /** + * Returns the resource's attributes formatted as a JSON-API "attributes object". + */ + extractAttributes(modelClass: {}, resourceHash: {}): {}; + /** + * Returns a relationship formatted as a JSON-API "relationship object". + */ + extractRelationship( + relationshipModelName: {}, + relationshipHash: {} + ): {}; + /** + * Returns a polymorphic relationship formatted as a JSON-API "relationship object". + */ + extractPolymorphicRelationship( + relationshipModelName: {}, + relationshipHash: {}, + relationshipOptions: {} + ): {}; + /** + * Returns the resource's relationships formatted as a JSON-API "relationships object". + */ + extractRelationships(modelClass: {}, resourceHash: {}): {}; + modelNameFromPayloadKey(key: string): string; + /** + * Check if the given hasMany relationship should be serialized + */ + shouldSerializeHasMany( + snapshot: Snapshot, + key: string, + relationshipType: string + ): boolean; + /** + * Called when a record is saved in order to convert the + * record into JSON. + */ + serialize( + snapshot: Snapshot, + options: {} + ): {}; + /** + * You can use this method to customize how a serialized record is added to the complete + * JSON hash to be sent to the server. By default the JSON Serializer does not namespace + * the payload and just sends the raw serialized JSON object. + * If your server expects namespaced keys, you should consider using the RESTSerializer. + * Otherwise you can override this method to customize how the record is added to the hash. + * The hash property should be modified by reference. + */ + serializeIntoHash( + hash: {}, + typeClass: ModelRegistry[K], + snapshot: Snapshot, + options?: {} + ): any; + /** + * `serializeAttribute` can be used to customize how `DS.attr` + * properties are serialized + */ + serializeAttribute( + snapshot: Snapshot, + json: {}, + key: string, + attribute: {} + ): any; + /** + * `serializeBelongsTo` can be used to customize how `DS.belongsTo` + * properties are serialized. + */ + serializeBelongsTo( + snapshot: Snapshot, + json: {}, + relationship: {} + ): any; + /** + * `serializeHasMany` can be used to customize how `DS.hasMany` + * properties are serialized. + */ + serializeHasMany( + snapshot: Snapshot, + json: {}, + relationship: {} + ): any; + /** + * You can use this method to customize how polymorphic objects are + * serialized. Objects are considered to be polymorphic if + * `{ polymorphic: true }` is pass as the second argument to the + * `DS.belongsTo` function. + */ + serializePolymorphicType( + snapshot: Snapshot, + json: {}, + relationship: {} + ): any; + /** + * `extractMeta` is used to deserialize any meta information in the + * adapter payload. By default Ember Data expects meta information to + * be located on the `meta` property of the payload object. + */ + extractMeta(store: Store, modelClass: Model, payload: {}): any; + /** + * `extractErrors` is used to extract model errors when a call + * to `DS.Model#save` fails with an `InvalidError`. By default + * Ember Data expects error information to be located on the `errors` + * property of the payload object. + */ + extractErrors( + store: Store, + typeClass: Model, + payload: {}, + id: string | number + ): {}; + /** + * `keyForAttribute` can be used to define rules for how to convert an + * attribute name in your model to a key in your JSON. + */ + keyForAttribute(key: string, method: string): string; + /** + * `keyForRelationship` can be used to define a custom key when + * serializing and deserializing relationship properties. By default + * `JSONSerializer` does not provide an implementation of this method. + */ + keyForRelationship( + key: string, + typeClass: string, + method: string + ): string; + /** + * `keyForLink` can be used to define a custom key when deserializing link + * properties. + */ + keyForLink(key: string, kind: string): string; + modelNameFromPayloadType(type: string): string; + /** + * serializeId can be used to customize how id is serialized + * For example, your server may expect integer datatype of id + */ + serializeId( + snapshot: Snapshot, + json: {}, + primaryKey: string + ): any; + } + /** + * Normally, applications will use the `RESTSerializer` by implementing + * the `normalize` method. + */ + class RESTSerializer extends JSONSerializer { + /** + * `keyForPolymorphicType` can be used to define a custom key when + * serializing and deserializing a polymorphic type. By default, the + * returned key is `${key}Type`. + */ + keyForPolymorphicType( + key: string, + typeClass: string, + method: string + ): string; + /** + * Normalizes a part of the JSON payload returned by + * the server. You should override this method, munge the hash + * and call super if you have generic normalization to do. + */ + normalize(modelClass: Model, resourceHash: {}, prop?: string): {}; + /** + * This method allows you to push a payload containing top-level + * collections of records organized per type. + */ + pushPayload(store: Store, payload: {}): any; + /** + * This method is used to convert each JSON root key in the payload + * into a modelName that it can use to look up the appropriate model for + * that part of the payload. + */ + modelNameFromPayloadKey(key: string): string; + /** + * Called when a record is saved in order to convert the + * record into JSON. + */ + serialize( + snapshot: Snapshot, + options: {} + ): {}; + /** + * You can use this method to customize the root keys serialized into the JSON. + * The hash property should be modified by reference (possibly using something like _.extend) + * By default the REST Serializer sends the modelName of a model, which is a camelized + * version of the name. + */ + serializeIntoHash( + hash: {}, + typeClass: Model, + snapshot: Snapshot, + options?: {} + ): any; + /** + * You can use `payloadKeyFromModelName` to override the root key for an outgoing + * request. By default, the RESTSerializer returns a camelized version of the + * model's name. + */ + payloadKeyFromModelName( + modelName: K + ): string; + /** + * You can use this method to customize how polymorphic objects are serialized. + * By default the REST Serializer creates the key by appending `Type` to + * the attribute and value from the model's camelcased model name. + */ + serializePolymorphicType( + snapshot: Snapshot, + json: {}, + relationship: {} + ): any; + /** + * You can use this method to customize how a polymorphic relationship should + * be extracted. + */ + extractPolymorphicRelationship( + relationshipType: {}, + relationshipHash: {}, + relationshipOptions: {} + ): {}; + /** + * `modelNameFromPayloadType` can be used to change the mapping for a DS model + * name, taken from the value in the payload. + */ + modelNameFromPayloadType(payloadType: string): string; + /** + * `payloadTypeFromModelName` can be used to change the mapping for the type in + * the payload, taken from the model name. + */ + payloadTypeFromModelName( + modelName: K + ): string; + } + /** + * The `DS.BooleanTransform` class is used to serialize and deserialize + * boolean attributes on Ember Data record objects. This transform is + * used when `boolean` is passed as the type parameter to the + * [DS.attr](../../data#method_attr) function. + */ + class BooleanTransform extends Transform {} + /** + * The `DS.DateTransform` class is used to serialize and deserialize + * date attributes on Ember Data record objects. This transform is used + * when `date` is passed as the type parameter to the + * [DS.attr](../../data#method_attr) function. It uses the [`ISO 8601`](https://en.wikipedia.org/wiki/ISO_8601) + * standard. + */ + class DateTransform extends Transform {} + /** + * The `DS.NumberTransform` class is used to serialize and deserialize + * numeric attributes on Ember Data record objects. This transform is + * used when `number` is passed as the type parameter to the + * [DS.attr](../../data#method_attr) function. + */ + class NumberTransform extends Transform {} + /** + * The `DS.StringTransform` class is used to serialize and deserialize + * string attributes on Ember Data record objects. This transform is + * used when `string` is passed as the type parameter to the + * [DS.attr](../../data#method_attr) function. + */ + class StringTransform extends Transform {} + /** + * The `DS.Transform` class is used to serialize and deserialize model + * attributes when they are saved or loaded from an + * adapter. Subclassing `DS.Transform` is useful for creating custom + * attributes. All subclasses of `DS.Transform` must implement a + * `serialize` and a `deserialize` method. + */ + class Transform extends Ember.Object { + /** + * When given a deserialized value from a record attribute this + * method must return the serialized value. + */ + serialize(deserialized: any, options: AttrOptions): any; + /** + * When given a serialize value from a JSON object this method must + * return the deserialized value for the record attribute. + */ + deserialize(serialized: any, options: AttrOptions): any; + } + /** + * An adapter is an object that receives requests from a store and + * translates them into the appropriate action to take against your + * persistence layer. The persistence layer is usually an HTTP API, but + * may be anything, such as the browser's local storage. Typically the + * adapter is not invoked directly instead its functionality is accessed + * through the `store`. + */ + class Adapter extends Ember.Object { + /** + * If you would like your adapter to use a custom serializer you can + * set the `defaultSerializer` property to be the name of the custom + * serializer. + */ + defaultSerializer: string; + /** + * The `findRecord()` method is invoked when the store is asked for a record that + * has not previously been loaded. In response to `findRecord()` being called, you + * should query your persistence layer for a record with the given ID. The `findRecord` + * method should return a promise that will resolve to a JavaScript object that will be + * normalized by the serializer. + */ + findRecord( + store: Store, + type: ModelRegistry[K], + id: string, + snapshot: Snapshot + ): RSVP.Promise; + /** + * The `findAll()` method is used to retrieve all records for a given type. + */ + findAll( + store: Store, + type: ModelRegistry[K], + sinceToken: string, + snapshotRecordArray: SnapshotRecordArray + ): RSVP.Promise; + /** + * This method is called when you call `query` on the store. + */ + query( + store: Store, + type: ModelRegistry[K], + query: {}, + recordArray: AdapterPopulatedRecordArray + ): RSVP.Promise; + /** + * The `queryRecord()` method is invoked when the store is asked for a single + * record through a query object. + */ + queryRecord( + store: Store, + type: ModelRegistry[K], + query: {} + ): RSVP.Promise; + /** + * If the globally unique IDs for your records should be generated on the client, + * implement the `generateIdForRecord()` method. This method will be invoked + * each time you create a new record, and the value returned from it will be + * assigned to the record's `primaryKey`. + */ + generateIdForRecord( + store: Store, + type: ModelRegistry[K], + inputProperties: {} + ): string | number; + /** + * Proxies to the serializer's `serialize` method. + */ + serialize( + snapshot: Snapshot, + options: {} + ): {}; + /** + * Implement this method in a subclass to handle the creation of + * new records. + */ + createRecord( + store: Store, + type: ModelRegistry[K], + snapshot: Snapshot + ): RSVP.Promise; + /** + * Implement this method in a subclass to handle the updating of + * a record. + */ + updateRecord( + store: Store, + type: ModelRegistry[K], + snapshot: Snapshot + ): RSVP.Promise; + /** + * Implement this method in a subclass to handle the deletion of + * a record. + */ + deleteRecord( + store: Store, + type: ModelRegistry[K], + snapshot: Snapshot + ): RSVP.Promise; + /** + * By default the store will try to coalesce all `fetchRecord` calls within the same runloop + * into as few requests as possible by calling groupRecordsForFindMany and passing it into a findMany call. + * You can opt out of this behaviour by either not implementing the findMany hook or by setting + * coalesceFindRequests to false. + */ + coalesceFindRequests: boolean; + /** + * The store will call `findMany` instead of multiple `findRecord` + * requests to find multiple records at once if coalesceFindRequests + * is true. + */ + findMany( + store: Store, + type: ModelRegistry[K], + ids: any[], + snapshots: any[] + ): RSVP.Promise; + /** + * Organize records into groups, each of which is to be passed to separate + * calls to `findMany`. + */ + groupRecordsForFindMany(store: Store, snapshots: any[]): any[]; + /** + * This method is used by the store to determine if the store should + * reload a record from the adapter when a record is requested by + * `store.findRecord`. + */ + shouldReloadRecord( + store: Store, + snapshot: Snapshot + ): boolean; + /** + * This method is used by the store to determine if the store should + * reload all records from the adapter when records are requested by + * `store.findAll`. + */ + shouldReloadAll( + store: Store, + snapshotRecordArray: SnapshotRecordArray + ): boolean; + /** + * This method is used by the store to determine if the store should + * reload a record after the `store.findRecord` method resolves a + * cached record. + */ + shouldBackgroundReloadRecord( + store: Store, + snapshot: Snapshot + ): boolean; + /** + * This method is used by the store to determine if the store should + * reload a record array after the `store.findAll` method resolves + * with a cached record array. + */ + shouldBackgroundReloadAll( + store: Store, + snapshotRecordArray: SnapshotRecordArray + ): boolean; + } + /** + * `DS.Serializer` is an abstract base class that you should override in your + * application to customize it for your backend. The minimum set of methods + * that you should implement is: + */ + class Serializer extends Ember.Object { + /** + * The `store` property is the application's `store` that contains + * all records. It can be used to look up serializers for other model + * types that may be nested inside the payload response. + */ + store: Store; + /** + * The `normalizeResponse` method is used to normalize a payload from the + * server to a JSON-API Document. + */ + normalizeResponse( + store: Store, + primaryModelClass: Model, + payload: {}, + id: string | number, + requestType: string + ): {}; + /** + * The `serialize` method is used when a record is saved in order to convert + * the record into the form that your external data source expects. + */ + serialize( + snapshot: Snapshot, + options: {} + ): {}; + /** + * The `normalize` method is used to convert a payload received from your + * external data source into the normalized form `store.push()` expects. You + * should override this method, munge the hash and return the normalized + * payload. + */ + normalize(typeClass: Model, hash: {}): {}; } } + +export default DS; + +declare module '@ember/routing/route' { + export default interface Route { + store: DS.Store; + } +} +declare module '@ember/controller' { + export default interface Controller { + store: DS.Store; + } +} +declare module '@ember/debug/data-adapter' { + export default interface DataAdapter { + store: DS.Store; + } +} +declare module '@ember/service' { + interface Registry { + store: DS.Store; + } +} + declare module 'ember-test-helpers' { - import DS from 'ember-data'; interface TestContext { store: DS.Store; } } -declare module 'ember-data/adapter' { - import DS from 'ember-data'; - export default DS.Adapter; - export { AdapterRegistry } from 'ember-data'; -} -declare module 'ember-data/adapters/errors' { - import DS from 'ember-data'; - const AdapterError: typeof DS.AdapterError; - const InvalidError: typeof DS.InvalidError; - const UnauthorizedError: typeof DS.UnauthorizedError; - const ForbiddenError: typeof DS.ForbiddenError; - const NotFoundError: typeof DS.NotFoundError; - const ConflictError: typeof DS.ConflictError; - const ServerError: typeof DS.ServerError; - const TimeoutError: typeof DS.TimeoutError; - const AbortError: typeof DS.AbortError; - const errorsHashToArray: typeof DS.errorsHashToArray; - const errorsArrayToHash: typeof DS.errorsArrayToHash; -} -declare module 'ember-data/adapters/json-api' { - import DS from 'ember-data'; - export default DS.JSONAPIAdapter; -} -declare module 'ember-data/adapters/rest' { - import DS from 'ember-data'; - export default DS.RESTAdapter; -} -declare module 'ember-data/attr' { - import DS from 'ember-data'; - export default DS.attr; -} -declare module 'ember-data/model' { - import DS from 'ember-data'; - export default DS.Model; - export { ModelRegistry } from 'ember-data'; -} -declare module 'ember-data/relationships' { - import DS from 'ember-data'; - const hasMany: typeof DS.hasMany; - const belongsTo: typeof DS.belongsTo; -} -declare module 'ember-data/serializer' { - import DS from 'ember-data'; - export default DS.Serializer; - export { SerializerRegistry } from 'ember-data'; -} -declare module 'ember-data/serializers/embedded-records-mixin' { - import DS from 'ember-data'; - export default DS.EmbeddedRecordsMixin; -} -declare module 'ember-data/serializers/json-api' { - import DS from 'ember-data'; - export default DS.JSONAPISerializer; -} -declare module 'ember-data/serializers/json' { - import DS from 'ember-data'; - export default DS.JSONSerializer; -} -declare module 'ember-data/serializers/rest' { - import DS from 'ember-data'; - export default DS.RESTSerializer; -} -declare module 'ember-data/store' { - import DS from 'ember-data'; - export default DS.Store; -} -declare module 'ember-data/transform' { - import DS from 'ember-data'; - export default DS.Transform; -} -declare module 'ember-data/transforms/boolean' { - import DS from 'ember-data'; - export default DS.BooleanTransform; -} -declare module 'ember-data/transforms/date' { - import DS from 'ember-data'; - export default DS.DateTransform; -} -declare module 'ember-data/transforms/number' { - import DS from 'ember-data'; - export default DS.NumberTransform; -} -declare module 'ember-data/transforms/string' { - import DS from 'ember-data'; - export default DS.StringTransform; -} -declare module 'ember-data/transforms/transform' { - import DS from 'ember-data'; - export default DS.Transform; -} diff --git a/types/ember-data/model.d.ts b/types/ember-data/model.d.ts new file mode 100644 index 0000000000..1c0a646988 --- /dev/null +++ b/types/ember-data/model.d.ts @@ -0,0 +1,3 @@ +import DS from 'ember-data'; +export default DS.Model; +export { ModelRegistry } from 'ember-data'; diff --git a/types/ember-data/relationships.d.ts b/types/ember-data/relationships.d.ts new file mode 100644 index 0000000000..ae09039123 --- /dev/null +++ b/types/ember-data/relationships.d.ts @@ -0,0 +1,3 @@ +import DS from 'ember-data'; +export const hasMany: typeof DS.hasMany; +export const belongsTo: typeof DS.belongsTo; diff --git a/types/ember-data/serializer.d.ts b/types/ember-data/serializer.d.ts new file mode 100644 index 0000000000..398eb9d5b5 --- /dev/null +++ b/types/ember-data/serializer.d.ts @@ -0,0 +1,3 @@ +import DS from 'ember-data'; +export default DS.Serializer; +export { SerializerRegistry } from 'ember-data'; diff --git a/types/ember-data/serializers/embedded-records-mixin.d.ts b/types/ember-data/serializers/embedded-records-mixin.d.ts new file mode 100644 index 0000000000..d5004c5032 --- /dev/null +++ b/types/ember-data/serializers/embedded-records-mixin.d.ts @@ -0,0 +1,2 @@ +import DS from 'ember-data'; +export default DS.EmbeddedRecordsMixin; diff --git a/types/ember-data/serializers/json-api.d.ts b/types/ember-data/serializers/json-api.d.ts new file mode 100644 index 0000000000..bd74a12782 --- /dev/null +++ b/types/ember-data/serializers/json-api.d.ts @@ -0,0 +1,2 @@ +import DS from 'ember-data'; +export default DS.JSONAPISerializer; diff --git a/types/ember-data/serializers/json.d.ts b/types/ember-data/serializers/json.d.ts new file mode 100644 index 0000000000..12d8dc3f6e --- /dev/null +++ b/types/ember-data/serializers/json.d.ts @@ -0,0 +1,2 @@ +import DS from 'ember-data'; +export default DS.JSONSerializer; diff --git a/types/ember-data/serializers/rest.d.ts b/types/ember-data/serializers/rest.d.ts new file mode 100644 index 0000000000..a294ce7a90 --- /dev/null +++ b/types/ember-data/serializers/rest.d.ts @@ -0,0 +1,2 @@ +import DS from 'ember-data'; +export default DS.RESTSerializer; diff --git a/types/ember-data/store.d.ts b/types/ember-data/store.d.ts new file mode 100644 index 0000000000..412930a147 --- /dev/null +++ b/types/ember-data/store.d.ts @@ -0,0 +1,2 @@ +import DS from 'ember-data'; +export default DS.Store; diff --git a/types/ember-data/test/injections.ts b/types/ember-data/test/injections.ts index 3e32a2b805..a3a3bc0627 100644 --- a/types/ember-data/test/injections.ts +++ b/types/ember-data/test/injections.ts @@ -1,5 +1,6 @@ import Ember from 'ember'; import DS from 'ember-data'; +import Controller from '@ember/controller'; class MyModel extends DS.Model {} @@ -15,9 +16,10 @@ Ember.Route.extend({ } }); -Ember.Controller.extend({ +Controller.extend({ actions: { create(): any { + this.queryParams; return this.store.createRecord('my-model'); } } diff --git a/types/ember-data/test/store.ts b/types/ember-data/test/store.ts index f512afd8a7..41b9a12d2d 100644 --- a/types/ember-data/test/store.ts +++ b/types/ember-data/test/store.ts @@ -101,7 +101,7 @@ const MyRoute = Ember.Route.extend({ }); // Store is injectable via `inject` and resolves to `DS.Store`. -const SomeComponent = Ember.Component.extend({ +const SomeComponent = Ember.Object.extend({ store: Ember.inject.service('store'), lookUpUsers() { diff --git a/types/ember-data/transform.d.ts b/types/ember-data/transform.d.ts new file mode 100644 index 0000000000..b57b7cbe76 --- /dev/null +++ b/types/ember-data/transform.d.ts @@ -0,0 +1,2 @@ +import DS from 'ember-data'; +export default DS.Transform; diff --git a/types/ember-data/transforms/boolean.d.ts b/types/ember-data/transforms/boolean.d.ts new file mode 100644 index 0000000000..6c26d15325 --- /dev/null +++ b/types/ember-data/transforms/boolean.d.ts @@ -0,0 +1,2 @@ +import DS from 'ember-data'; +export default DS.BooleanTransform; diff --git a/types/ember-data/transforms/date.d.ts b/types/ember-data/transforms/date.d.ts new file mode 100644 index 0000000000..45016cb94e --- /dev/null +++ b/types/ember-data/transforms/date.d.ts @@ -0,0 +1,2 @@ +import DS from 'ember-data'; +export default DS.DateTransform; diff --git a/types/ember-data/transforms/number.d.ts b/types/ember-data/transforms/number.d.ts new file mode 100644 index 0000000000..3c1179416d --- /dev/null +++ b/types/ember-data/transforms/number.d.ts @@ -0,0 +1,2 @@ +import DS from 'ember-data'; +export default DS.NumberTransform; diff --git a/types/ember-data/transforms/string.d.ts b/types/ember-data/transforms/string.d.ts new file mode 100644 index 0000000000..d4e44189e5 --- /dev/null +++ b/types/ember-data/transforms/string.d.ts @@ -0,0 +1,2 @@ +import DS from 'ember-data'; +export default DS.StringTransform; diff --git a/types/ember-data/transforms/transform.d.ts b/types/ember-data/transforms/transform.d.ts new file mode 100644 index 0000000000..b57b7cbe76 --- /dev/null +++ b/types/ember-data/transforms/transform.d.ts @@ -0,0 +1,2 @@ +import DS from 'ember-data'; +export default DS.Transform; diff --git a/types/ember-data/tsconfig.json b/types/ember-data/tsconfig.json index 9bdb160a16..8de9ad784b 100644 --- a/types/ember-data/tsconfig.json +++ b/types/ember-data/tsconfig.json @@ -16,6 +16,14 @@ "paths": { "@ember/debug": ["ember__debug"], "@ember/debug/*": ["ember__debug/*"], + "@ember/service": ["ember__service"], + "@ember/array": ["ember__array"], + "@ember/array/*": ["ember__array/*"], + "@ember/debug": ["ember__debug"], + "@ember/debug/*": ["ember__debug/*"], + "@ember/controller": ["ember__controller"], + "@ember/routing": ["ember__routing"], + "@ember/routing/*": ["ember__routing/*"], "@ember/object": ["ember__object"], "@ember/object/*": ["ember__object/*"] }, @@ -26,6 +34,25 @@ }, "files": [ "index.d.ts", + "adapters/errors.d.ts", + "adapters/json-api.d.ts", + "adapters/rest.d.ts", + "serializers/embedded-records-mixin.d.ts", + "serializers/json-api.d.ts", + "serializers/json.d.ts", + "serializers/rest.d.ts", + "transforms/boolean.d.ts", + "transforms/date.d.ts", + "transforms/number.d.ts", + "transforms/string.d.ts", + "transforms/transform.d.ts", + "adapter.d.ts", + "attr.d.ts", + "model.d.ts", + "relationships.d.ts", + "serializer.d.ts", + "store.d.ts", + "transform.d.ts", "test/lib/assert.ts", "test/model.ts", "test/module-api.ts", diff --git a/types/ember-feature-flags/tsconfig.json b/types/ember-feature-flags/tsconfig.json index 966e80a2ba..54f7acecb3 100644 --- a/types/ember-feature-flags/tsconfig.json +++ b/types/ember-feature-flags/tsconfig.json @@ -14,6 +14,7 @@ "../" ], "paths": { + "@ember/service": ["ember__service"], "@ember/object": ["ember__object"], "@ember/object/*": ["ember__object/*"] }, diff --git a/types/ember-mocha/tsconfig.json b/types/ember-mocha/tsconfig.json index 33768e7c41..2c00d52341 100644 --- a/types/ember-mocha/tsconfig.json +++ b/types/ember-mocha/tsconfig.json @@ -15,6 +15,8 @@ "paths": { "@ember/engine": ["ember__engine"], "@ember/engine/*": ["ember__engine/*"], + "@ember/application": ["ember__application"], + "@ember/application/*": ["ember__application/*"], "@ember/object": ["ember__object"], "@ember/object/*": ["ember__object/*"] }, diff --git a/types/ember-modal-dialog/tsconfig.json b/types/ember-modal-dialog/tsconfig.json index 8f02b9e0f8..9a842ee744 100644 --- a/types/ember-modal-dialog/tsconfig.json +++ b/types/ember-modal-dialog/tsconfig.json @@ -15,7 +15,9 @@ ], "paths": { "@ember/object": ["ember__object"], - "@ember/object/*": ["ember__object/*"] + "@ember/object/*": ["ember__object/*"], + "@ember/component": ["ember__component"], + "@ember/component/*": ["ember__component/*"] }, "types": [], "noEmit": true, diff --git a/types/ember-qunit/tsconfig.json b/types/ember-qunit/tsconfig.json index 86590138a0..7b184205af 100644 --- a/types/ember-qunit/tsconfig.json +++ b/types/ember-qunit/tsconfig.json @@ -14,6 +14,12 @@ "../" ], "paths": { + "@ember/engine": ["ember__engine"], + "@ember/engine/*": ["ember__engine/*"], + "@ember/application": ["ember__application"], + "@ember/application/*": ["ember__application/*"], + "@ember/test": ["ember__test"], + "@ember/test/*": ["ember__test/*"], "@ember/object": ["ember__object"], "@ember/object/*": ["ember__object/*"] }, diff --git a/types/ember-resolver/ember-resolver-tests.ts b/types/ember-resolver/ember-resolver-tests.ts index 6973daeda0..ac348f1d79 100644 --- a/types/ember-resolver/ember-resolver-tests.ts +++ b/types/ember-resolver/ember-resolver-tests.ts @@ -1,5 +1,5 @@ import EmberResolver from 'ember-resolver'; -import { Ember } from 'ember'; +import Ember from 'ember'; const MyResolver = EmberResolver.extend({ pluralizedTypes: { diff --git a/types/ember-resolver/tsconfig.json b/types/ember-resolver/tsconfig.json index 60667c8a52..e8dfb6e8ce 100644 --- a/types/ember-resolver/tsconfig.json +++ b/types/ember-resolver/tsconfig.json @@ -15,6 +15,8 @@ "paths": { "@ember/engine": ["ember__engine"], "@ember/engine/*": ["ember__engine/*"], + "@ember/application": ["ember__application"], + "@ember/application/*": ["ember__application/*"], "@ember/object": ["ember__object"], "@ember/object/*": ["ember__object/*"] }, diff --git a/types/ember-test-helpers/tsconfig.json b/types/ember-test-helpers/tsconfig.json index a6e8d61ba8..2d9eb44d16 100644 --- a/types/ember-test-helpers/tsconfig.json +++ b/types/ember-test-helpers/tsconfig.json @@ -16,6 +16,8 @@ "paths": { "@ember/engine": ["ember__engine"], "@ember/engine/*": ["ember__engine/*"], + "@ember/application": ["ember__application"], + "@ember/application/*": ["ember__application/*"], "@ember/object": ["ember__object"], "@ember/object/*": ["ember__object/*"] }, diff --git a/types/ember/index.d.ts b/types/ember/index.d.ts index 0899ab50a3..594e2e2fcc 100755 --- a/types/ember/index.d.ts +++ b/types/ember/index.d.ts @@ -21,6 +21,14 @@ /// /// /// +/// +/// +/// +/// +/// +/// +/// +/// declare module 'ember' { import { @@ -41,11 +49,16 @@ declare module 'ember' { import { Registry as ServiceRegistry } from '@ember/service'; import { Registry as ControllerRegistry } from '@ember/controller'; import * as EmberStringNs from '@ember/string'; + // tslint:disable-next-line:no-duplicate-imports + import * as EmberServiceNs from '@ember/service'; import * as EmberPolyfillsNs from '@ember/polyfills'; import * as EmberUtilsNs from '@ember/utils'; + import * as EmberRunloopNs from '@ember/runloop'; import * as EmberObjectNs from '@ember/object'; import * as EmberObjectObserversNs from '@ember/object/observers'; import * as EmberObjectMixinNs from '@ember/object/mixin'; + import * as EmberObjectProxyNs from '@ember/object/proxy'; + import * as EmberObjectPromiseProxyNs from '@ember/object/promise-proxy-mixin'; import * as EmberObjectInternalsNs from '@ember/object/internals'; import * as EmberObjectComputedNs from '@ember/object/computed'; import * as EmberObjectEventedNs from '@ember/object/evented'; @@ -53,24 +66,59 @@ declare module 'ember' { // @ember/debug import * as EmberDebugNs from '@ember/debug'; import _ContainerDebugAdapter from '@ember/debug/container-debug-adapter'; - import _DataAdapter from '@ember/debug/data-adapter'; + import EmberDataAdapter from '@ember/debug/data-adapter'; // @ember/engine import * as EmberEngineNs from '@ember/engine'; import * as EmberEngineInstanceNs from '@ember/engine/instance'; import _ContainerProxyMixin from '@ember/engine/-private/container-proxy-mixin'; import _RegistryProxyMixin from '@ember/engine/-private/registry-proxy-mixin'; import EmberCoreObject from '@ember/object/core'; + import * as EmberApplicationNs from '@ember/application'; + import * as EmberApplicationInstanceNs from '@ember/application/instance'; + import * as EmberApplicationDeprecateNs from '@ember/application/deprecations'; + import * as EmberTestNs from '@ember/test'; + // tslint:disable-next-line:no-duplicate-imports + import * as EmberControllerNs from '@ember/controller'; // tslint:disable-next-line:no-duplicate-imports import EmberMixin from '@ember/object/mixin'; - import Observable from '@ember/object/observable'; + import EmberObservable from '@ember/object/observable'; // @ember/array import * as EmberArrayNs from '@ember/array'; import EmberMutableArray from '@ember/array/mutable'; + import EmberNativeArray from '@ember/array/-private/native-array'; import EmberArrayProxy from '@ember/array/proxy'; import EmberEnumerable from '@ember/array/-private/enumerable'; + import EmberMutableEnumerable from '@ember/array/-private/mutable-enumerable'; import EmberArrayProtoExtensions from '@ember/array/types/prototype-extensions'; + // @ember/run + import { RunMethod } from '@ember/runloop/-private/types'; + // @ember/error + import EmberError from '@ember/error'; type EmberArray = EmberArrayNs.default; + import EmberActionHandler from '@ember/object/-private/action-handler'; + import EmberComponent from '@ember/component'; + import EmberTextArea from '@ember/component/text-area'; + import EmberTextField from '@ember/component/text-field'; + import EmberCheckbox from '@ember/component/checkbox'; + import EmberHelper from '@ember/component/helper'; + // @ember/routing + import EmberRoutingRouter from '@ember/routing/router'; + import EmberRoutingRoute from '@ember/routing/route'; + import EmberRoutingTransition from '@ember/routing/-private/transition'; + import EmberRoutingRouterService from '@ember/routing/router-service'; + import EmberRoutingHashLocation from '@ember/routing/hash-location'; + import EmberRoutingAutoLocation from '@ember/routing/auto-location'; + import EmberRoutingHistoryLocation from '@ember/routing/history-location'; + import EmberRoutingNoneLocation from '@ember/routing/none-location'; + import EmberRoutingLinkComponent from '@ember/routing/link-component'; + // @ember/application + import EmberDefaultResolver from '@ember/application/-private/default-resolver'; + import EmberEventDispatcher from '@ember/application/-private/event-dispatcher'; + import EmberRegistry from '@ember/application/-private/registry'; + import EmberResolver from '@ember/application/resolver'; + // @ember/test + import EmberTestAdapter from '@ember/test/adapter'; type Mix = B & Pick>; type Mix3 = Mix, C>; @@ -82,190 +130,12 @@ declare module 'ember' { */ type MixinOrLiteral = EmberMixin | T; - /** - * Used to infer the type of ember classes of type `T`. - * - * Generally you would use `EmberClass.create()` instead of `new EmberClass()`. - * - * The single-arg constructor is required by the typescript compiler. - * The multi-arg constructor is included for better ergonomics. - * - * Implementation is carefully chosen for the reasons described in - * https://github.com/typed-ember/ember-typings/pull/29 - */ - - interface ActionsHash { - [index: string]: (...params: any[]) => any; - } - - interface EmberRunTimer { - __ember_run_timer_brand__: any; - } - - type RunMethod = ((this: Target, ...args: any[]) => Ret) | keyof Target; - type EmberRunQueues = - | 'sync' - | 'actions' - | 'routerTransitions' - | 'render' - | 'afterRender' - | 'destroy'; - type QueryParamTypes = 'boolean' | 'number' | 'array' | 'string'; - type QueryParamScopeTypes = 'controller' | 'model'; - - interface RenderOptions { - into?: string; - controller?: string; - model?: any; - outlet?: string; - view?: string; - } - - interface RouteQueryParam { - refreshModel?: boolean; - replace?: boolean; - as?: string; - } - - interface EventDispatcherEvents { - touchstart?: string | null; - touchmove?: string | null; - touchend?: string | null; - touchcancel?: string | null; - keydown?: string | null; - keyup?: string | null; - keypress?: string | null; - mousedown?: string | null; - mouseup?: string | null; - contextmenu?: string | null; - click?: string | null; - dblclick?: string | null; - mousemove?: string | null; - focusin?: string | null; - focusout?: string | null; - mouseenter?: string | null; - mouseleave?: string | null; - submit?: string | null; - input?: string | null; - change?: string | null; - dragstart?: string | null; - drag?: string | null; - dragenter?: string | null; - dragleave?: string | null; - dragover?: string | null; - drop?: string | null; - dragend?: string | null; - [event: string]: string | null | undefined; - } - - interface ViewMixin { - /** - * A list of properties of the view to apply as attributes. If the property - * is a string value, the value of that string will be applied as the value - * for an attribute of the property's name. - */ - attributeBindings: string[]; - /** - * Returns the current DOM element for the view. - */ - element: Element; - /** - * Returns a jQuery object for this view's element. If you pass in a selector - * string, this method will return a jQuery object, using the current element - * as its buffer. - */ - $: JQueryStatic; - /** - * The HTML `id` of the view's element in the DOM. You can provide this - * value yourself but it must be unique (just as in HTML): - */ - elementId: string; - /** - * Tag name for the view's outer element. The tag name is only used when an - * element is first created. If you change the `tagName` for an element, you - * must destroy and recreate the view element. - */ - tagName: string; - /** - * Renders the view again. This will work regardless of whether the - * view is already in the DOM or not. If the view is in the DOM, the - * rendering process will be deferred to give bindings a chance - * to synchronize. - */ - rerender(): void; - /** - * Called when a view is going to insert an element into the DOM. - */ - willInsertElement(): void; - /** - * Called when the element of the view has been inserted into the DOM. - * Override this function to do any set up that requires an element - * in the document body. - */ - didInsertElement(): void; - /** - * Called when the view is about to rerender, but before anything has - * been torn down. This is a good opportunity to tear down any manual - * observers you have installed based on the DOM state - */ - willClearRender(): void; - /** - * Called when the element of the view is going to be destroyed. Override - * this function to do any teardown that requires an element, like removing - * event listeners. - */ - willDestroyElement(): void; - } - const ViewMixin: EmberMixin; - /** * Ember.CoreView is an abstract class that exists to give view-like behavior to both Ember's main * view class Ember.Component and other classes that don't need the full functionality of Ember.Component. * Unless you have specific needs for CoreView, you will use Ember.Component in your applications. */ class CoreView extends Ember.Object.extend(Ember.Evented, Ember.ActionHandler) {} - interface ActionSupport { - sendAction(action: string, ...params: any[]): void; - } - const ActionSupport: EmberMixin; - - interface ClassNamesSupport { - /** - * A list of properties of the view to apply as class names. If the property is a string value, - * the value of that string will be applied as a class name. - * - * If the value of the property is a Boolean, the name of that property is added as a dasherized - * class name. - * - * If you would prefer to use a custom value instead of the dasherized property name, you can - * pass a binding like this: `classNameBindings: ['isUrgent:urgent']` - * - * This list of properties is inherited from the component's superclasses as well. - */ - classNameBindings: string[]; - /** - * Standard CSS class names to apply to the view's outer element. This - * property automatically inherits any class names defined by the view's - * superclasses as well. - */ - classNames: string[]; - } - const ClassNamesSupport: EmberMixin; - - interface TriggerActionOptions { - action?: string; - target?: Ember.Object; - actionContext?: Ember.Object; - } - /** - * Ember.TargetActionSupport is a mixin that can be included in a class to add a triggerAction method - * with semantics similar to the Handlebars {{action}} helper. In normal Ember usage, the {{action}} - * helper is usually the best choice. This mixin is most often useful when you are doing more - * complex event handling in Components. - */ - interface TargetActionSupport { - triggerAction(opts: TriggerActionOptions): boolean; - } export namespace Ember { const A: typeof EmberArrayNs.A; @@ -275,6 +145,34 @@ declare module 'ember' { class ArrayProxy extends EmberArrayProxy {} export type Array = EmberArray; export const Array: typeof EmberArrayNs.default; + export type MutableArray = EmberMutableArray; + export const MutableArray: typeof EmberMutableArray; + export type NativeArray = EmberNativeArray; + export const NativeArray: typeof EmberNativeArray; + export type MutableEnumerable = EmberMutableEnumerable; + export const MutableEnumerable: typeof EmberMutableEnumerable; + class Router extends EmberRoutingRouter {} + class Route extends EmberRoutingRoute {} + const ActionHandler: typeof EmberActionHandler; + class Controller extends EmberControllerNs.default {} + export class Component extends EmberComponent {} + export class TextArea extends EmberTextArea {} + export class TextField extends EmberTextField {} + export class Checkbox extends EmberCheckbox {} + export class Helper extends EmberHelper {} + + export class HashLocation extends EmberRoutingHashLocation {} + export class NoneLocation extends EmberRoutingNoneLocation {} + export class HistoryLocation extends EmberRoutingHistoryLocation {} + export class LinkComponent extends EmberRoutingLinkComponent {} + const deprecateFunc: typeof EmberApplicationDeprecateNs.deprecateFunc; + const deprecate: typeof EmberApplicationDeprecateNs.deprecate; + const getOwner: typeof EmberApplicationNs.getOwner; + const setOwner: typeof EmberApplicationNs.setOwner; + class DefaultResolver extends EmberDefaultResolver {} + class Resolver extends EmberResolver {} + class EventDispatcher extends EmberEventDispatcher {} + class Registry extends EmberRegistry {} interface FunctionPrototypeExtensions { /** * The `property` extension of Javascript's Function prototype is available @@ -308,134 +206,7 @@ declare module 'ember' { underscore(): string; w(): string[]; } - /** - * Ember.ActionHandler is available on some familiar classes including Ember.Route, - * Ember.Component, and Ember.Controller. (Internally the mixin is used by Ember.CoreView, - * Ember.ControllerMixin, and Ember.Route and available to the above classes through inheritance.) - */ - interface ActionHandler { - /** - * Triggers a named action on the ActionHandler. Any parameters supplied after the actionName - * string will be passed as arguments to the action target function. - * - * If the ActionHandler has its target property set, actions may bubble to the target. - * Bubbling happens when an actionName can not be found in the ActionHandler's actions - * hash or if the action target function returns true. - */ - send(actionName: string, ...args: any[]): void; - /** - * The collection of functions, keyed by name, available on this ActionHandler as action targets. - */ - actions: ActionsHash; - } - const ActionHandler: EmberMixin; - /** - * An instance of Ember.Application is the starting point for every Ember application. It helps to - * instantiate, initialize and coordinate the many objects that make up your app. - */ - class Application extends EmberEngineNs.default { - /** - * Call advanceReadiness after any asynchronous setup logic has completed. - * Each call to deferReadiness must be matched by a call to advanceReadiness - * or the application will never become ready and routing will not begin. - */ - advanceReadiness(): void; - /** - * Use this to defer readiness until some condition is true. - * - * This allows you to perform asynchronous setup logic and defer - * booting your application until the setup has finished. - * - * However, if the setup requires a loading UI, it might be better - * to use the router for this purpose. - */ - deferReadiness(): void; - /** - * defines an injection or typeInjection - */ - inject(factoryNameOrType: string, property: string, injectionName: string): void; - /** - * This injects the test helpers into the window's scope. If a function of the - * same name has already been defined it will be cached (so that it can be reset - * if the helper is removed with `unregisterHelper` or `removeTestHelpers`). - * Any callbacks registered with `onInjectHelpers` will be called once the - * helpers have been injected. - */ - injectTestHelpers(): void; - /** - * registers a factory for later injection - * @param fullName type:name (e.g., 'model:user') - * @param factory (e.g., App.Person) - */ - register(fullName: string, factory: any): void; - /** - * This removes all helpers that have been registered, and resets and functions - * that were overridden by the helpers. - */ - removeTestHelpers(): void; - /** - * Reset the application. This is typically used only in tests. - */ - reset(): void; - /** - * This hook defers the readiness of the application, so that you can start - * the app when your tests are ready to run. It also sets the router's - * location to 'none', so that the window's location will not be modified - * (preventing both accidental leaking of state between tests and interference - * with your testing framework). - */ - setupForTesting(): void; - /** - * The DOM events for which the event dispatcher should listen. - */ - customEvents: EventDispatcherEvents; - /** - * The Ember.EventDispatcher responsible for delegating events to this application's views. - */ - eventDispatcher: EventDispatcher; - /** - * Set this to provide an alternate class to Ember.DefaultResolver - */ - resolver: DefaultResolver; - /** - * The root DOM element of the Application. This can be specified as an - * element or a jQuery-compatible selector string. - * - * This is the element that will be passed to the Application's, eventDispatcher, - * which sets up the listeners for event delegation. Every view in your application - * should be a child of the element you specify here. - */ - rootElement: HTMLElement | string; - /** - * Called when the Application has become ready. - * The call will be delayed until the DOM has become ready. - */ - ready: (...args: any[]) => any; - /** - * Application's router. - */ - Router: Router; - registry: Registry; - /** - * Initialize the application and return a promise that resolves with the `Application` - * object when the boot process is complete. - */ - boot(): Promise; - /** - * Create an ApplicationInstance for this Application. - */ - buildInstance(options?: object): ApplicationInstance; - } - /** - * The `ApplicationInstance` encapsulates all of the stateful aspects of a - * running `Application`. - */ - class ApplicationInstance extends EngineInstance {} - /** - * AutoLocation will select the best location option based off browser support with the priority order: history, hash, none. - */ - class AutoLocation extends Object {} /** * Connects the properties of two objects so that whenever the value of one property changes, * the other property will be changed also. @@ -451,11 +222,6 @@ declare module 'ember' { to(path: string | string[]): Binding; toString(): string; } - /** - * The internal class used to create text inputs when the {{input}} helper is used - * with type of checkbox. See Handlebars.helpers.input for usage details. - */ - class Checkbox extends Component {} /** * Implements some standard methods for comparing objects. Add this mixin to * any class you create that can compare its instances. @@ -464,79 +230,6 @@ declare module 'ember' { compare(a: any, b: any): number; } const Comparable: EmberMixin; - /** - * A view that is completely isolated. Property access in its templates go to the view object - * and actions are targeted at the view object. There is no access to the surrounding context or - * outer controller; all contextual information is passed in. - */ - class Component extends CoreView.extend(ViewMixin, ActionSupport, ClassNamesSupport) { - // methods - readDOMAttr(name: string): string; - // properties - /** - * The WAI-ARIA role of the control represented by this view. For example, a button may have a - * role of type 'button', or a pane may have a role of type 'alertdialog'. This property is - * used by assistive software to help visually challenged users navigate rich web applications. - */ - ariaRole: string; - /** - * The HTML id of the component's element in the DOM. You can provide this value yourself but - * it must be unique (just as in HTML): - * - * If not manually set a default value will be provided by the framework. Once rendered an - * element's elementId is considered immutable and you should never change it. If you need - * to compute a dynamic value for the elementId, you should do this when the component or - * element is being instantiated: - */ - elementId: string; - /** - * If false, the view will appear hidden in DOM. - */ - isVisible: boolean; - /** - * A component may contain a layout. A layout is a regular template but supersedes the template - * property during rendering. It is the responsibility of the layout template to retrieve the - * template property from the component (or alternatively, call Handlebars.helpers.yield, - * {{yield}}) to render it in the correct location. This is useful for a component that has a - * shared wrapper, but which delegates the rendering of the contents of the wrapper to the - * template property on a subclass. - */ - layout: TemplateFactory | string; - /** - * Enables components to take a list of parameters as arguments. - */ - static positionalParams: string[] | string; - // events - /** - * Called when the attributes passed into the component have been updated. Called both during the - * initial render of a container and during a rerender. Can be used in place of an observer; code - * placed here will be executed every time any attribute updates. - */ - didReceiveAttrs(): void; - /** - * Called after a component has been rendered, both on initial render and in subsequent rerenders. - */ - didRender(): void; - /** - * Called when the component has updated and rerendered itself. Called only during a rerender, - * not during an initial render. - */ - didUpdate(): void; - /** - * Called when the attributes passed into the component have been changed. Called only during a - * rerender, not during an initial render. - */ - didUpdateAttrs(): void; - /** - * Called before a component has been rendered, both on initial render and in subsequent rerenders. - */ - willRender(): void; - /** - * Called when the component is about to update and rerender itself. Called only during a rerender, - * not during an initial render. - */ - willUpdate(): void; - } export class ComputedProperty extends EmberObjectComputedNs.default {} /** * A container used to instantiate and cache objects. @@ -551,70 +244,26 @@ declare module 'ember' { factoryFor(fullName: string, options?: {}): any; } class ContainerDebugAdapter extends _ContainerDebugAdapter {} - /** - * Additional methods for the Controller. - */ - interface ControllerMixin extends ActionHandler { - replaceRoute(name: string, ...args: any[]): void; - transitionToRoute(name: string, ...args: any[]): void; - model: any; - queryParams: string | string[] | EmberArray<{ [key: string]: { - type?: QueryParamTypes, - scope?: QueryParamScopeTypes, - as?: string - }}>; - target: object; - } - const ControllerMixin: EmberMixin; - class Controller extends Object.extend(ControllerMixin) {} + // TODO: replace with a proper ES6 reexport once we remove declare module 'ember' {} class Object extends EmberObjectNs.default {} + class ObjectProxy extends EmberObjectProxyNs.default {} + const Observable: typeof EmberObservable; + const PromiseProxyMixin: typeof EmberObjectPromiseProxyNs.default; class CoreObject extends EmberCoreObject {} - class DataAdapter extends _DataAdapter {} + class DataAdapter extends EmberDataAdapter {} const Debug: { registerDeprecationHandler: typeof EmberDebugNs.registerDeprecationHandler; registerWarnHandler: typeof EmberDebugNs.registerWarnHandler; }; - /** - * The DefaultResolver defines the default lookup rules to resolve - * container lookups before consulting the container for registered - * items: - */ - class DefaultResolver extends Resolver { - /** - * This method is called via the container's resolver method. - * It parses the provided `fullName` and then looks up and - * returns the appropriate template or class. - */ - resolve(fullName: string): {}; - /** - * This will be set to the Application instance when it is - * created. - */ - namespace: Application; - } - class EngineInstance extends EmberEngineInstanceNs.default {} class Engine extends EmberEngineNs.default {} /** * A subclass of the JavaScript Error object for use in Ember. */ - const Error: ErrorConstructor; - /** - * `Ember.EventDispatcher` handles delegating browser events to their - * corresponding `Ember.Views.` For example, when you click on a view, - * `Ember.EventDispatcher` ensures that that view's `mouseDown` method gets - * called. - */ - class EventDispatcher extends Object { - /** - * The set of events names (and associated handler function names) to be setup - * and dispatched by the `EventDispatcher`. Modifications to this list can be done - * at setup time, generally via the `Ember.Application.customEvents` hash. - */ - events: EventDispatcherEvents; - } + const Error: EmberError; + const Evented: typeof EmberObjectEventedNs.default; /** * The `Ember.Freezable` mixin implements some basic methods for marking an @@ -627,38 +276,6 @@ declare module 'ember' { isFrozen: boolean; } const Freezable: EmberMixin; - /** - * `Ember.HashLocation` implements the location API using the browser's - * hash. At present, it relies on a `hashchange` event existing in the - * browser. - */ - class HashLocation extends Object {} - /** - * Ember.HistoryLocation implements the location API using the browser's - * history.pushState API. - */ - class HistoryLocation extends Object {} - /** - * Ember Helpers are functions that can compute values, and are used in templates. - * For example, this code calls a helper named `format-currency`: - */ - class Helper extends Object { - /** - * In many cases, the ceremony of a full `Ember.Helper` class is not required. - * The `helper` method create pure-function helpers without instances. For - * example: - */ - static helper(helper: (params: any[], hash?: object) => any): Helper; - /** - * Override this function when writing a class-based helper. - */ - compute(params: any[], hash: object): any; - /** - * On a class-based helper, it may be useful to force a recomputation of that - * helpers value. This is akin to `rerender` on a component. - */ - recompute(): any; - } /** * The purpose of the Ember Instrumentation module is * to provide efficient, general-purpose instrumentation @@ -670,55 +287,6 @@ declare module 'ember' { subscribe(pattern: string, object: any): void; unsubscribe(subscriber: any): void; }; - /** - * `Ember.LinkComponent` renders an element whose `click` event triggers a - * transition of the application's instance of `Ember.Router` to - * a supplied route by name. - */ - class LinkComponent extends Component { - /** - * Used to determine when this `LinkComponent` is active. - */ - currentWhen: any; - /** - * Sets the `title` attribute of the `LinkComponent`'s HTML element. - */ - title: string | null; - /** - * Sets the `rel` attribute of the `LinkComponent`'s HTML element. - */ - rel: string | null; - /** - * Sets the `tabindex` attribute of the `LinkComponent`'s HTML element. - */ - tabindex: string | null; - /** - * Sets the `target` attribute of the `LinkComponent`'s HTML element. - */ - target: string | null; - /** - * The CSS class to apply to `LinkComponent`'s element when its `active` - * property is `true`. - */ - activeClass: string; - /** - * Determines whether the `LinkComponent` will trigger routing via - * the `replaceWith` routing strategy. - */ - replace: boolean; - } - /** - * Ember.Location returns an instance of the correct implementation of - * the `location` API. - */ - const Location: { - /** - * This is deprecated in favor of using the container to lookup the location - * implementation as desired. - * @deprecated Use the container to lookup the location implementation that you need. - */ - create(options?: {}): any; - }; /** * Inside Ember-Metal, simply uses the methods from `imports.console`. * Override this to provide more robust logging functionality. @@ -772,7 +340,6 @@ declare module 'ember' { static create(): MapWithDefault; } class Mixin extends EmberMixin {} - const MutableArray: typeof EmberMutableArray; /** * A Namespace is an object usually used to contain other objects or methods @@ -781,13 +348,6 @@ declare module 'ember' { */ class Namespace extends Object {} - /** - * Ember.NoneLocation does not interact with the browser. It is useful for - * testing, or when you need to manage state with your Router, but temporarily - * don't want it to muck with the URL (for example when you embed your - * application in a larger page). - */ - class NoneLocation extends Object {} /** * This class is used internally by Ember and Ember Data. * Please do not use it at this time. We plan to clean it up @@ -805,411 +365,7 @@ declare module 'ember' { toArray(): any[]; } - /** - * A registry used to store factory and option information keyed - * by type. - */ - class Registry { - register( - fullName: string, - factory: EmberClassConstructor, - options?: { singleton?: boolean } - ): void; - } - class Resolver extends Ember.Object {} - /** - * The `Ember.Route` class is used to define individual routes. Refer to - * the [routing guide](http://emberjs.com/guides/routing/) for documentation. - */ - class Route extends Object.extend(ActionHandler, Evented) { - // methods - /** - * This hook is called after this route's model has resolved. - * It follows identical async/promise semantics to `beforeModel` - * but is provided the route's resolved model in addition to - * the `transition`, and is therefore suited to performing - * logic that can only take place after the model has already - * resolved. - */ - afterModel(resolvedModel: any, transition: Transition): any; - - /** - * This hook is the first of the route entry validation hooks - * called when an attempt is made to transition into a route - * or one of its children. It is called before `model` and - * `afterModel`, and is appropriate for cases when: - * 1) A decision can be made to redirect elsewhere without - * needing to resolve the model first. - * 2) Any async operations need to occur first before the - * model is attempted to be resolved. - * This hook is provided the current `transition` attempt - * as a parameter, which can be used to `.abort()` the transition, - * save it for a later `.retry()`, or retrieve values set - * on it from a previous hook. You can also just call - * `this.transitionTo` to another route to implicitly - * abort the `transition`. - * You can return a promise from this hook to pause the - * transition until the promise resolves (or rejects). This could - * be useful, for instance, for retrieving async code from - * the server that is required to enter a route. - */ - beforeModel(transition: Transition): any; - - /** - * Returns the controller for a particular route or name. - * The controller instance must already have been created, either through entering the - * associated route or using `generateController`. - */ - controllerFor(name: K): ControllerRegistry[K]; - - /** - * Disconnects a view that has been rendered into an outlet. - */ - disconnectOutlet(options: string | { outlet?: string; parentView?: string }): void; - - /** - * A hook you can implement to convert the URL into the model for - * this route. - */ - model(params: {}, transition: Transition): any; - - /** - * Returns the model of a parent (or any ancestor) route - * in a route hierarchy. During a transition, all routes - * must resolve a model object, and if a route - * needs access to a parent route's model in order to - * resolve a model (or just reuse the model from a parent), - * it can call `this.modelFor(theNameOfParentRoute)` to - * retrieve it. - */ - modelFor(name: string): {}; - - /** - * Retrieves parameters, for current route using the state.params - * variable and getQueryParamsFor, using the supplied routeName. - */ - paramsFor(name: string): {}; - - /** - * Refresh the model on this route and any child routes, firing the - * `beforeModel`, `model`, and `afterModel` hooks in a similar fashion - * to how routes are entered when transitioning in from other route. - * The current route params (e.g. `article_id`) will be passed in - * to the respective model hooks, and if a different model is returned, - * `setupController` and associated route hooks will re-fire as well. - * An example usage of this method is re-querying the server for the - * latest information using the same parameters as when the route - * was first entered. - * Note that this will cause `model` hooks to fire even on routes - * that were provided a model object when the route was initially - * entered. - */ - redirect(): Transition; - - /** - * Refresh the model on this route and any child routes, firing the - * `beforeModel`, `model`, and `afterModel` hooks in a similar fashion - * to how routes are entered when transitioning in from other route. - * The current route params (e.g. `article_id`) will be passed in - * to the respective model hooks, and if a different model is returned, - * `setupController` and associated route hooks will re-fire as well. - * An example usage of this method is re-querying the server for the - * latest information using the same parameters as when the route - * was first entered. - * Note that this will cause `model` hooks to fire even on routes - * that were provided a model object when the route was initially - * entered. - */ - refresh(): Transition; - - /** - * `render` is used to render a template into a region of another template - * (indicated by an `{{outlet}}`). `render` is used both during the entry - * phase of routing (via the `renderTemplate` hook) and later in response to - * user interaction. - */ - render(name: string, options?: RenderOptions): void; - - /** - * A hook you can use to render the template for the current route. - * This method is called with the controller for the current route and the - * model supplied by the `model` hook. By default, it renders the route's - * template, configured with the controller for the route. - * This method can be overridden to set up and render additional or - * alternative templates. - */ - renderTemplate(controller: Controller, model: {}): void; - - /** - * Transition into another route while replacing the current URL, if possible. - * This will replace the current history entry instead of adding a new one. - * Beside that, it is identical to `transitionTo` in all other respects. See - * 'transitionTo' for additional information regarding multiple models. - */ - replaceWith(name: string, ...args: any[]): Transition; - - /** - * A hook you can use to reset controller values either when the model - * changes or the route is exiting. - */ - resetController(controller: Controller, isExiting: boolean, transition: any): void; - - /** - * Sends an action to the router, which will delegate it to the currently active - * route hierarchy per the bubbling rules explained under actions. - */ - send(name: string, ...args: any[]): void; - - /** - * A hook you can implement to convert the route's model into parameters - * for the URL. - * - * The default `serialize` method will insert the model's `id` into the - * route's dynamic segment (in this case, `:post_id`) if the segment contains '_id'. - * If the route has multiple dynamic segments or does not contain '_id', `serialize` - * will return `Ember.getProperties(model, params)` - * This method is called when `transitionTo` is called with a context - * in order to populate the URL. - */ - serialize(model: {}, params: string[]): string | object; - - /** - * A hook you can use to setup the controller for the current route. - * This method is called with the controller for the current route and the - * model supplied by the `model` hook. - * By default, the `setupController` hook sets the `model` property of - * the controller to the `model`. - * If you implement the `setupController` hook in your Route, it will - * prevent this default behavior. If you want to preserve that behavior - * when implementing your `setupController` function, make sure to call - * `_super` - */ - setupController(controller: Controller, model: {}): void; - - /** - * Transition the application into another route. The route may - * be either a single route or route path - */ - transitionTo(name: string, ...object: any[]): Transition; - - /** - * The name of the view to use by default when rendering this routes template. - * When rendering a template, the route will, by default, determine the - * template and view to use from the name of the route itself. If you need to - * define a specific view, set this property. - * This is useful when multiple routes would benefit from using the same view - * because it doesn't require a custom `renderTemplate` method. - */ - transitionTo(name: string, ...object: any[]): Transition; - - // https://emberjs.com/api/ember/3.2/classes/Route/methods/intermediateTransitionTo?anchor=intermediateTransitionTo - /** - * Perform a synchronous transition into another route without attempting to resolve promises, - * update the URL, or abort any currently active asynchronous transitions - * (i.e. regular transitions caused by transitionTo or URL changes). - * - * @param name the name of the route or a URL - * @param object the model(s) or identifier(s) to be used while - * transitioning to the route. - * @returns the Transition object associated with this attempted transition - */ - intermediateTransitionTo(name: string, ...object: any[]): Transition; - - // properties - /** - * The controller associated with this route. - */ - controller: Controller; - - /** - * The name of the controller to associate with this route. - * By default, Ember will lookup a route's controller that matches the name - * of the route (i.e. `App.PostController` for `App.PostRoute`). However, - * if you would like to define a specific controller to use, you can do so - * using this property. - * This is useful in many ways, as the controller specified will be: - * * p assed to the `setupController` method. - * * used as the controller for the view being rendered by the route. - * * returned from a call to `controllerFor` for the route. - */ - controllerName: string; - - /** - * Configuration hash for this route's queryParams. - */ - queryParams: { [key: string]: RouteQueryParam }; - - /** - * The name of the route, dot-delimited - */ - routeName: string; - - /** - * The name of the template to use by default when rendering this routes - * template. - * This is similar with `viewName`, but is useful when you just want a custom - * template without a view. - */ - templateName: string; - - // events - /** - * This hook is executed when the router enters the route. It is not executed - * when the model for the route changes. - */ - activate(): void; - - /** - * This hook is executed when the router completely exits this route. It is - * not executed when the model for the route changes. - */ - deactivate(): void; - - /** - * The didTransition action is fired after a transition has successfully been - * completed. This occurs after the normal model hooks (beforeModel, model, - * afterModel, setupController) have resolved. The didTransition action has - * no arguments, however, it can be useful for tracking page views or resetting - * state on the controller. - */ - didTransition(): void; - - /** - * When attempting to transition into a route, any of the hooks may return a promise - * that rejects, at which point an error action will be fired on the partially-entered - * routes, allowing for per-route error handling logic, or shared error handling logic - * defined on a parent route. - */ - error(error: any, transition: Transition): void; - - /** - * The loading action is fired on the route when a route's model hook returns a - * promise that is not already resolved. The current Transition object is the first - * parameter and the route that triggered the loading event is the second parameter. - */ - loading(transition: Transition, route: Route): void; - - /** - * The willTransition action is fired at the beginning of any attempted transition - * with a Transition object as the sole argument. This action can be used for aborting, - * redirecting, or decorating the transition from the currently active routes. - */ - willTransition(transition: Transition): void; - } - /** - * The `Ember.Router` class manages the application state and URLs. Refer to - * the [routing guide](http://emberjs.com/guides/routing/) for documentation. - */ - class Router extends Object.extend(Evented) { - /** - * The `Router.map` function allows you to define mappings from URLs to routes - * in your application. These mappings are defined within the - * supplied callback function using `this.route`. - */ - static map(callback: (this: RouterDSL) => void): void; - /** - * The `location` property determines the type of URL's that your - * application will use. - */ - location: string; - /** - * Represents the URL of the root of the application, often '/'. This prefix is - * assumed on all routes defined on this router. - */ - rootURL: string; - /** - * Handles updating the paths and notifying any listeners of the URL - * change. - */ - didTransition(): any; - /** - * Handles notifying any listeners of an impending URL - * change. - */ - willTransition(): any; - /** - * Transition the application into another route. The route may - * be either a single route or route path: - */ - transitionTo(name: string, options?: {}): Transition; - transitionTo(name: string, ...models: any[]): Transition; - transitionTo(name: string, options: {}): Transition; - } - class RouterDSL { - constructor(name: string, options: object); - route(name: string, callback: (this: RouterDSL) => void): void; - route( - name: string, - options?: { path?: string; resetNamespace?: boolean }, - callback?: (this: RouterDSL) => void - ): void; - mount( - name: string, - options?: { - as?: string, - path?: string, - resetNamespace?: boolean, - engineInfo?: any - } - ): void; - } class Service extends Object {} - /** - * The internal class used to create textarea element when the `{{textarea}}` - * helper is used. - */ - class TextArea extends Component.extend(TextSupport) {} - /** - * The internal class used to create text inputs when the `{{input}}` - * helper is used with `type` of `text`. - */ - class TextField extends Component.extend(TextSupport) { - /** - * The `value` attribute of the input element. As the user inputs text, this - * property is updated live. - */ - value: string; - /** - * The `type` attribute of the input element. - */ - type: string; - /** - * The `size` of the text field in characters. - */ - size: string; - /** - * The `pattern` attribute of input element. - */ - pattern: string; - /** - * The `min` attribute of input element used with `type="number"` or `type="range"`. - */ - min: string; - /** - * The `max` attribute of input element used with `type="number"` or `type="range"`. - */ - max: string; - } - /** - * `TextSupport` is a shared mixin used by both `Ember.TextField` and - * `Ember.TextArea`. `TextSupport` adds a number of methods that allow you to - * specify a controller action to invoke when a certain event is fired on your - * text field or textarea. The specifed controller action would get the current - * value of the field passed in as the only argument unless the value of - * the field is empty. In that case, the instance of the field itself is passed - * in as the only argument. - */ - interface TextSupport extends TargetActionSupport { - cancel(event: (...args: any[]) => any): void; - focusIn(event: (...args: any[]) => any): void; - focusOut(event: (...args: any[]) => any): void; - insertNewLine(event: (...args: any[]) => any): void; - keyPress(event: (...args: any[]) => any): void; - action: string; - bubbles: boolean; - onEvent: string; - } - const TextSupport: Mixin; interface Transition { /** * Aborts the Transition. Note you can also implicitly abort a transition @@ -1237,32 +393,18 @@ declare module 'ember' { namespace RSVP { type Promise = Rsvp.Promise; } - + class Application extends EmberApplicationNs.default {} + class ApplicationInstance extends EmberApplicationInstanceNs.default {} /** * This is a container for an assortment of testing related functionality */ namespace Test { - /** - * `registerHelper` is used to register a test helper that will be injected - * when `App.injectTestHelpers` is called. - */ - function registerHelper( - name: string, - helperMethod: (app: Application, ...args: any[]) => any, - options?: object - ): any; - /** - * `registerAsyncHelper` is used to register an async test helper that will be injected - * when `App.injectTestHelpers` is called. - */ - function registerAsyncHelper( - name: string, - helperMethod: (app: Application, ...args: any[]) => any - ): void; - /** - * Remove a previously added helper method. - */ - function unregisterHelper(name: string): void; + class Adapter extends EmberTestAdapter {} + const registerHelper: typeof EmberTestNs.registerHelper; + const unregisterHelper: typeof EmberTestNs.unregisterHelper; + const registerWaiter: typeof EmberTestNs.registerWaiter; + const unregisterWaiter: typeof EmberTestNs.unregisterWaiter; + const registerAsyncHelper: typeof EmberTestNs.registerAsyncHelper; /** * Used to register callbacks to be fired whenever `App.injectTestHelpers` * is called. @@ -1286,28 +428,7 @@ declare module 'ember' { * an instance of `Ember.Test.Promise` */ function resolve(value?: T | PromiseLike, label?: string): Ember.Test.Promise; - /** - * This allows ember-testing to play nicely with other asynchronous - * events, such as an application that is waiting for a CSS3 - * transition or an IndexDB transaction. The waiter runs periodically - * after each async helper (i.e. `click`, `andThen`, `visit`, etc) has executed, - * until the returning result is truthy. After the waiters finish, the next async helper - * is executed and the process repeats. - */ - function registerWaiter(callback: () => boolean): any; - function registerWaiter( - context: Context, - callback: (this: Context) => boolean - ): any; - /** - * `unregisterWaiter` is used to unregister a callback that was - * registered with `registerWaiter`. - */ - function unregisterWaiter(callback: () => boolean): any; - function unregisterWaiter( - context: Context, - callback: (this: Context) => boolean - ): any; + /** * Iterates through each registered test waiter, and invokes * its callback. If any waiter returns false, this method will return @@ -1318,32 +439,13 @@ declare module 'ember' { * Used to allow ember-testing to communicate with a specific testing * framework. */ - const adapter: Adapter; - /** - * The primary purpose of this class is to create hooks that can be implemented - * by an adapter for various test frameworks. - */ - class Adapter { - /** - * This callback will be called whenever an async operation is about to start. - */ - asyncStart(): any; - /** - * This callback will be called whenever an async operation has completed. - */ - asyncEnd(): any; - /** - * Override this method with your testing framework's false assertion. - * This function is called whenever an exception occurs causing the testing - * promise to fail. - */ - exception(error: string): any; - } + const adapter: EmberTestAdapter; + /** * This class implements the methods defined by Ember.Test.Adapter for the * QUnit testing framework. */ - class QUnitAdapter extends Adapter {} + class QUnitAdapter extends EmberTestAdapter {} class Promise extends Rsvp.Promise { constructor( executor: ( @@ -1365,14 +467,7 @@ declare module 'ember' { function controller( name: K ): ComputedProperty; - /** - * Creates a property that lazily looks up a service in the container. There - * are no restrictions as to what objects a service can be injected into. - */ - function service(): ComputedProperty; - function service( - name: K - ): ComputedProperty; + const service: typeof EmberServiceNs.inject; } namespace ENV { const EXTEND_PROTOTYPES: typeof Ember.EXTEND_PROTOTYPES; @@ -1417,300 +512,7 @@ declare module 'ember' { const w: typeof EmberStringNs.w; } const computed: typeof EmberObjectNs.computed; - const run: { - /** - * Runs the passed target and method inside of a RunLoop, ensuring any - * deferred actions including bindings and views updates are flushed at the - * end. - */ - (method: (...args: any[]) => Ret): Ret; - (target: Target, method: RunMethod): Ret; - /** - * If no run-loop is present, it creates a new one. If a run loop is - * present it will queue itself to run on the existing run-loops action - * queue. - */ - join(method: (...args: any[]) => Ret, ...args: any[]): Ret | undefined; - join( - target: Target, - method: RunMethod, - ...args: any[] - ): Ret | undefined; - /** - * Allows you to specify which context to call the specified function in while - * adding the execution of that function to the Ember run loop. This ability - * makes this method a great way to asynchronously integrate third-party libraries - * into your Ember application. - */ - bind( - target: Target, - method: RunMethod, - ...args: any[] - ): (...args: any[]) => Ret; - /** - * Begins a new RunLoop. Any deferred actions invoked after the begin will - * be buffered until you invoke a matching call to `run.end()`. This is - * a lower-level way to use a RunLoop instead of using `run()`. - */ - begin(): void; - /** - * Ends a RunLoop. This must be called sometime after you call - * `run.begin()` to flush any deferred actions. This is a lower-level way - * to use a RunLoop instead of using `run()`. - */ - end(): void; - /** - * Adds the passed target/method and any optional arguments to the named - * queue to be executed at the end of the RunLoop. If you have not already - * started a RunLoop when calling this method one will be started for you - * automatically. - */ - schedule( - queue: EmberRunQueues, - target: Target, - method: RunMethod, - ...args: any[] - ): EmberRunTimer; - schedule( - queue: EmberRunQueues, - method: (args: any[]) => any, - ...args: any[] - ): EmberRunTimer; - /** - * Invokes the passed target/method and optional arguments after a specified - * period of time. The last parameter of this method must always be a number - * of milliseconds. - */ - later(method: (...args: any[]) => any, wait: number): EmberRunTimer; - later(target: Target, method: RunMethod, wait: number): EmberRunTimer; - later( - target: Target, - method: RunMethod, - arg0: any, - wait: number - ): EmberRunTimer; - later( - target: Target, - method: RunMethod, - arg0: any, - arg1: any, - wait: number - ): EmberRunTimer; - later( - target: Target, - method: RunMethod, - arg0: any, - arg1: any, - arg2: any, - wait: number - ): EmberRunTimer; - later( - target: Target, - method: RunMethod, - arg0: any, - arg1: any, - arg2: any, - arg3: any, - wait: number - ): EmberRunTimer; - later( - target: Target, - method: RunMethod, - arg0: any, - arg1: any, - arg2: any, - arg3: any, - arg4: any, - wait: number - ): EmberRunTimer; - later( - target: Target, - method: RunMethod, - arg0: any, - arg1: any, - arg2: any, - arg3: any, - arg4: any, - arg5: any, - wait: number - ): EmberRunTimer; - /** - * Schedule a function to run one time during the current RunLoop. This is equivalent - * to calling `scheduleOnce` with the "actions" queue. - */ - once(target: Target, method: RunMethod, ...args: any[]): EmberRunTimer; - /** - * Schedules a function to run one time in a given queue of the current RunLoop. - * Calling this method with the same queue/target/method combination will have - * no effect (past the initial call). - */ - scheduleOnce( - queue: EmberRunQueues, - target: Target, - method: RunMethod, - ...args: any[] - ): EmberRunTimer; - /** - * Schedules an item to run from within a separate run loop, after - * control has been returned to the system. This is equivalent to calling - * `run.later` with a wait time of 1ms. - */ - next(target: Target, method: RunMethod, ...args: any[]): EmberRunTimer; - /** - * Cancels a scheduled item. Must be a value returned by `run.later()`, - * `run.once()`, `run.scheduleOnce()`, `run.next()`, `run.debounce()`, or - * `run.throttle()`. - */ - cancel(timer: EmberRunTimer): boolean; - /** - * Delay calling the target method until the debounce period has elapsed - * with no additional debounce calls. If `debounce` is called again before - * the specified time has elapsed, the timer is reset and the entire period - * must pass again before the target method is called. - */ - debounce( - method: (...args: any[]) => any, - wait: number, - immediate?: boolean - ): EmberRunTimer; - debounce( - target: Target, - method: RunMethod, - wait: number, - immediate?: boolean - ): EmberRunTimer; - debounce( - target: Target, - method: RunMethod, - arg0: any, - wait: number, - immediate?: boolean - ): EmberRunTimer; - debounce( - target: Target, - method: RunMethod, - arg0: any, - arg1: any, - wait: number, - immediate?: boolean - ): EmberRunTimer; - debounce( - target: Target, - method: RunMethod, - arg0: any, - arg1: any, - arg2: any, - wait: number, - immediate?: boolean - ): EmberRunTimer; - debounce( - target: Target, - method: RunMethod, - arg0: any, - arg1: any, - arg2: any, - arg3: any, - wait: number, - immediate?: boolean - ): EmberRunTimer; - debounce( - target: Target, - method: RunMethod, - arg0: any, - arg1: any, - arg2: any, - arg3: any, - arg4: any, - wait: number, - immediate?: boolean - ): EmberRunTimer; - debounce( - target: Target, - method: RunMethod, - arg0: any, - arg1: any, - arg2: any, - arg3: any, - arg4: any, - arg5: any, - wait: number, - immediate?: boolean - ): EmberRunTimer; - /** - * Ensure that the target method is never called more frequently than - * the specified spacing period. The target method is called immediately. - */ - throttle( - method: (...args: any[]) => any, - spacing: number, - immediate?: boolean - ): EmberRunTimer; - throttle( - target: Target, - method: RunMethod, - spacing: number, - immediate?: boolean - ): EmberRunTimer; - throttle( - target: Target, - method: RunMethod, - arg0: any, - spacing: number, - immediate?: boolean - ): EmberRunTimer; - throttle( - target: Target, - method: RunMethod, - arg0: any, - arg1: any, - spacing: number, - immediate?: boolean - ): EmberRunTimer; - throttle( - target: Target, - method: RunMethod, - arg0: any, - arg1: any, - arg2: any, - spacing: number, - immediate?: boolean - ): EmberRunTimer; - throttle( - target: Target, - method: RunMethod, - arg0: any, - arg1: any, - arg2: any, - arg3: any, - spacing: number, - immediate?: boolean - ): EmberRunTimer; - throttle( - target: Target, - method: RunMethod, - arg0: any, - arg1: any, - arg2: any, - arg3: any, - arg4: any, - spacing: number, - immediate?: boolean - ): EmberRunTimer; - throttle( - target: Target, - method: RunMethod, - arg0: any, - arg1: any, - arg2: any, - arg3: any, - arg4: any, - arg5: any, - spacing: number, - immediate?: boolean - ): EmberRunTimer; - - queues: EmberRunQueues[]; - }; + const run: typeof EmberRunloopNs.run; const platform: { defineProperty: boolean; hasPropertyAccessors: boolean; @@ -1720,41 +522,10 @@ declare module 'ember' { * `getEngineParent` retrieves an engine instance's parent instance. */ function getEngineParent(engine: EngineInstance): EngineInstance; - /** - * Display a deprecation warning with the provided message and a stack trace - * (Chrome and Firefox only). - */ - function deprecate( - message: string, - test: boolean, - options: { id: string; until: string } - ): any; - /** - * @deprecated Missing deprecation options: https://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options - */ - function deprecate( - message: string, - test: boolean, - options?: { id?: string; until?: string } - ): any; + const assert: typeof EmberDebugNs.assert; const debug: typeof EmberDebugNs.debug; const defineProperty: typeof EmberObjectNs.defineProperty; - /** - * Alias an old, deprecated method with its new counterpart. - */ - function deprecateFunc any)>( - message: string, - options: { id: string; until: string }, - func: Func - ): Func; - /** - * @deprecated Missing deprecation options: https://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options - */ - function deprecateFunc any)>( - message: string, - func: Func - ): Func; export const runInDebug: typeof EmberDebugNs.runInDebug; export const warn: typeof EmberDebugNs.warn; @@ -1786,17 +557,6 @@ declare module 'ember' { const setProperties: typeof EmberObjectNs.setProperties; const set: typeof EmberObjectNs.set; const trySet: typeof EmberObjectNs.trySet; - - /** - * Detects when a specific package of Ember (e.g. 'Ember.Application') - * has fully loaded and is available for extension. - */ - function onLoad(name: string, callback: (...args: any[]) => any): any; - /** - * Called when an Ember.js package (e.g Ember.Application) has finished - * loading. Triggers any callbacks registered for this event. - */ - function runLoadHooks(name: string, object?: {}): any; const compare: typeof EmberUtilsNs.compare; /** * Creates a shallow copy of the passed object. A deep copy of the object is @@ -1824,18 +584,7 @@ declare module 'ember' { const guidFor: typeof EmberObjectInternalsNs.guidFor; const inspect: typeof EmberDebugNs.inspect; const tryInvoke: typeof EmberUtilsNs.tryInvoke; - /** - * Framework objects in an Ember application (components, services, routes, etc.) - * are created via a factory and dependency injection system. Each of these - * objects is the responsibility of an "owner", which handled its - * instantiation and manages its lifetime. - */ - function getOwner(object: any): any; - /** - * `setOwner` forces a new owner on a given object instance. This is primarily - * useful in some testing cases. - */ - function setOwner(object: any, owner: any): void; + /** * A function may be assigned to `Ember.onerror` to be called when Ember * internals encounter an error. This is useful for specialized error handling @@ -1872,327 +621,15 @@ declare module 'ember' { const expandProperties: typeof EmberObjectComputedNs.expandProperties; } - type RouteModel = object | string | number; - // https://emberjs.com/api/ember/2.18/classes/RouterService - /** - * The Router service is the public API that provides component/view layer access to the router. - */ - export class RouterService extends Ember.Service { - // - /** - * Name of the current route. - * This property represent the logical name of the route, - * which is comma separated. - * For the following router: - * ```app/router.js - * Router.map(function() { - * this.route('about'); - * this.route('blog', function () { - * this.route('post', { path: ':post_id' }); - * }); - * }); - * ``` - * It will return: - * * `index` when you visit `/` - * * `about` when you visit `/about` - * * `blog.index` when you visit `/blog` - * * `blog.post` when you visit `/blog/some-post-id` - */ - readonly currentRouteName: string; - // - /** - * Current URL for the application. - * This property represent the URL path for this route. - * For the following router: - * ```app/router.js - * Router.map(function() { - * this.route('about'); - * this.route('blog', function () { - * this.route('post', { path: ':post_id' }); - * }); - * }); - * ``` - * It will return: - * * `/` when you visit `/` - * * `/about` when you visit `/about` - * * `/blog` when you visit `/blog` - * * `/blog/some-post-id` when you visit `/blog/some-post-id` - */ - readonly currentURL: string; - // - /** - * Determines whether a route is active. - * - * @param routeName the name of the route - * @param models the model(s) or identifier(s) to be used while - * transitioning to the route - * @param options optional hash with a queryParams property containing a - * mapping of query parameters - */ - isActive(routeName: string, options?: { queryParams: object }): boolean; - isActive(routeName: string, models: RouteModel, options?: { queryParams: object }): boolean; - isActive(routeName: string, modelsA: RouteModel, modelsB: RouteModel, options?: { queryParams: object }): boolean; - isActive(routeName: string, modelsA: RouteModel, modelsB: RouteModel, modelsC: RouteModel, options?: { queryParams: object }): boolean; - isActive(routeName: string, modelsA: RouteModel, modelsB: RouteModel, modelsC: RouteModel, modelsD: RouteModel, options?: { queryParams: object }): boolean; - - // https://emberjs.com/api/ember/2.18/classes/RouterService/methods/isActive?anchor=replaceWith - /** - * Transition into another route while replacing the current URL, if - * possible. The route may be either a single route or route path. - * - * @param routeNameOrUrl the name of the route or a URL - * @param models the model(s) or identifier(s) to be used while - * transitioning to the route. - * @param options optional hash with a queryParams property - * containing a mapping of query parameters - * @returns the Transition object associated with this attempted transition - */ - replaceWith(routeNameOrUrl: string, options?: { queryParams: object }): Ember.Transition; - replaceWith(routeNameOrUrl: string, models: RouteModel, options?: { queryParams: object }): Ember.Transition; - replaceWith(routeNameOrUrl: string, modelsA: RouteModel, modelsB: RouteModel, options?: { queryParams: object }): Ember.Transition; - replaceWith(routeNameOrUrl: string, modelsA: RouteModel, modelsB: RouteModel, modelsC: RouteModel, options?: { queryParams: object }): Ember.Transition; - replaceWith(routeNameOrUrl: string, modelsA: RouteModel, modelsB: RouteModel, modelsC: RouteModel, modelsD: RouteModel, options?: { queryParams: object }): Ember.Transition; - - // https://emberjs.com/api/ember/2.18/classes/RouterService/methods/isActive?anchor=transitionTo - /** - * Transition the application into another route. The route may be - * either a single route or route path - * - * @param routeNameOrUrl the name of the route or a URL - * @param models the model(s) or identifier(s) to be used while - * transitioning to the route. - * @param options optional hash with a queryParams property - * containing a mapping of query parameters - * @returns the Transition object associated with this attempted transition - */ - transitionTo(routeNameOrUrl: string, options?: { queryParam: object }): Ember.Transition; - transitionTo(routeNameOrUrl: string, models: RouteModel, options?: { queryParams: object }): Ember.Transition; - transitionTo(routeNameOrUrl: string, modelsA: RouteModel, modelsB: RouteModel, options?: { queryParams: object }): Ember.Transition; - transitionTo(routeNameOrUrl: string, modelsA: RouteModel, modelsB: RouteModel, modelsC: RouteModel, options?: { queryParams: object }): Ember.Transition; - transitionTo(routeNameOrUrl: string, modelsA: RouteModel, modelsB: RouteModel, modelsC: RouteModel, modelsD: RouteModel, options?: { queryParams: object }): Ember.Transition; - - // https://emberjs.com/api/ember/2.18/classes/RouterService/methods/isActive?anchor=urlFor - /** - * Generate a URL based on the supplied route name. - * - * @param routeName the name of the route or a URL - * @param models the model(s) or identifier(s) to be used while - * transitioning to the route. - * @param options optional hash with a queryParams property containing - * a mapping of query parameters - * @returns the string representing the generated URL - */ - urlFor(routeName: string, options?: { queryParams: object }): string; - urlFor(routeName: string, models: RouteModel, options?: { queryParams: object }): string; - urlFor(routeName: string, modelsA: RouteModel, modelsB: RouteModel, options?: { queryParams: object }): string; - urlFor(routeName: string, modelsA: RouteModel, modelsB: RouteModel, modelsC: RouteModel, options?: { queryParams: object }): string; - urlFor(routeName: string, modelsA: RouteModel, modelsB: RouteModel, modelsC: RouteModel, modelsD: RouteModel, options?: { queryParams: object }): string; - } - module '@ember/service' { interface Registry { - 'router': RouterService; + 'router': EmberRoutingRouterService; } } export default Ember; } -declare module '@ember/application' { - import Ember from 'ember'; - export default class Application extends Ember.Application { } - export const getOwner: typeof Ember.getOwner; - export const onLoad: typeof Ember.onLoad; - export const runLoadHooks: typeof Ember.runLoadHooks; - export const setOwner: typeof Ember.setOwner; -} - -declare module '@ember/application/deprecations' { - import Ember from 'ember'; - export const deprecate: typeof Ember.deprecate; - export const deprecateFunc: typeof Ember.deprecateFunc; -} - -declare module '@ember/application/globals-resolver' { - import Ember from 'ember'; - export default class GlobalsResolver extends Ember.DefaultResolver { } -} - -declare module '@ember/application/instance' { - import Ember from 'ember'; - export default class ApplicationInstance extends Ember.ApplicationInstance { } -} - -declare module '@ember/application/resolver' { - import Ember from 'ember'; - export default class Resolver extends Ember.Resolver { } -} - -declare module '@ember/component' { - import Ember from 'ember'; - export default class Component extends Ember.Component { } -} - -declare module '@ember/component/checkbox' { - import Ember from 'ember'; - export default class Checkbox extends Ember.Checkbox { } -} - -declare module '@ember/component/helper' { - import Ember from 'ember'; - export default class Helper extends Ember.Helper { } - /** - * In many cases, the ceremony of a full `Helper` class is not required. - * The `helper` method create pure-function helpers without instances. For - * example: - * ```app/helpers/format-currency.js - * import { helper } from '@ember/component/helper'; - * export default helper(function(params, hash) { - * let cents = params[0]; - * let currency = hash.currency; - * return `${currency}${cents * 0.01}`; - * }); - * ``` - */ - export function helper(helperFn: (params: any[], hash?: any) => any): any; -} - -declare module '@ember/component/text-area' { - import Ember from 'ember'; - export default class TextArea extends Ember.TextArea { } -} - -declare module '@ember/component/text-field' { - import Ember from 'ember'; - export default class TextField extends Ember.TextField { } -} - -declare module '@ember/controller' { - import Ember from 'ember'; - export default class Controller extends Ember.Controller { } - export const inject: typeof Ember.inject.controller; - - // A type registry for Ember `Controller`s. Meant to be declaration-merged - // so string lookups resolve to the correct type. - // tslint:disable-next-line:no-empty-interface - export interface Registry {} -} - -// declare module '@ember/debug' { -// import Ember from 'ember'; -// export const assert: typeof Ember.assert; -// export const debug: typeof Ember.debug; -// export const inspect: typeof Ember.inspect; -// export const registerDeprecationHandler: typeof Ember.Debug.registerDeprecationHandler; -// export const registerWarnHandler: typeof Ember.Debug.registerWarnHandler; -// export const runInDebug: typeof Ember.runInDebug; -// export const warn: typeof Ember.warn; -// } - -// declare module '@ember/debug/container-debug-adapter' { -// import Ember from 'ember'; -// export default class ContainerDebugAdapter extends Ember.ContainerDebugAdapter { } -// } - -// declare module '@ember/debug/data-adapter' { -// import Ember from 'ember'; -// export default class DataAdapter extends Ember.DataAdapter { } -// } - -declare module '@ember/error' { - import Ember from 'ember'; - const Error: typeof Ember.Error; - export default Error; -} - -declare module '@ember/routing/auto-location' { - import Ember from 'ember'; - export default class AutoLocation extends Ember.AutoLocation { } -} - -declare module '@ember/routing/hash-location' { - import Ember from 'ember'; - export default class HashLocation extends Ember.HashLocation { } -} - -declare module '@ember/routing/history-location' { - import Ember from 'ember'; - export default class HistoryLocation extends Ember.HistoryLocation { } -} - -declare module '@ember/routing/link-component' { - import Ember from 'ember'; - export default class LinkComponent extends Ember.LinkComponent { } -} - -declare module '@ember/routing/location' { - import Ember from 'ember'; - const Location: typeof Ember.Location; - export default Location; -} - -declare module '@ember/routing/none-location' { - import Ember from 'ember'; - export default class NoneLocation extends Ember.NoneLocation { } -} - -declare module '@ember/routing/route' { - import Ember from 'ember'; - export default class Route extends Ember.Route { } -} - -declare module '@ember/routing/router' { - import Ember from 'ember'; - export default class EmberRouter extends Ember.Router { } -} - -declare module '@ember/routing/router-service' { - import { RouterService } from 'ember'; - export default class extends RouterService { } -} - -declare module '@ember/runloop' { - import Ember from 'ember'; - export const begin: typeof Ember.run.begin; - export const bind: typeof Ember.run.bind; - export const cancel: typeof Ember.run.cancel; - export const debounce: typeof Ember.run.debounce; - export const end: typeof Ember.run.end; - export const join: typeof Ember.run.join; - export const later: typeof Ember.run.later; - export const next: typeof Ember.run.next; - export const once: typeof Ember.run.once; - export const run: typeof Ember.run; - export const schedule: typeof Ember.run.schedule; - export const scheduleOnce: typeof Ember.run.scheduleOnce; - export const throttle: typeof Ember.run.throttle; -} - -declare module '@ember/service' { - import Ember from 'ember'; - export default class Service extends Ember.Service { } - export const inject: typeof Ember.inject.service; - - // A type registry for Ember `Service`s. Meant to be declaration-merged so - // string lookups resolve to the correct type. - // tslint:disable-next-line:no-empty-interface - interface Registry {} -} - -declare module '@ember/test' { - import Ember from 'ember'; - export const registerAsyncHelper: typeof Ember.Test.registerAsyncHelper; - export const registerHelper: typeof Ember.Test.registerHelper; - export const registerWaiter: typeof Ember.Test.registerWaiter; - export const unregisterHelper: typeof Ember.Test.unregisterHelper; - export const unregisterWaiter: typeof Ember.Test.unregisterWaiter; -} - -declare module '@ember/test/adapter' { - import Ember from 'ember'; - export default class TestAdapter extends Ember.Test.Adapter { } -} - declare module 'htmlbars-inline-precompile' { interface TemplateFactory { __htmlbars_inline_precompile_template_factory: any; diff --git a/types/ember/test/ember-module-tests.ts b/types/ember/test/ember-module-tests.ts new file mode 100644 index 0000000000..ed90fe42ef --- /dev/null +++ b/types/ember/test/ember-module-tests.ts @@ -0,0 +1,277 @@ +import Ember from 'ember'; + +// $ +Ember.$; // $ExpectType JQueryStatic +// A +Ember.A(); // $ExpectType NativeArray<{}> +Ember.A([1, 2]); // $ExpectType NativeArray +// addListener +Ember.addListener({ a: 'foo' }, 'a', {}, () => {}); +Ember.addListener({ a: 'foo' }, 'a', null, () => {}); +// addObserver +Ember.addObserver({ a: 'foo' }, 'a', null, () => {}); +Ember.addObserver({ a: 'foo' }, 'a', {}, () => {}); +// aliasMethod +Ember.aliasMethod('init'); +// assert +Ember.assert('2+2 should always be 4', 2 + 2 === 4); +// assign +const o1 = Ember.assign({ a: 1 }, { b: 2 }); +o1.a; // $ExpectType number +o1.b; // $ExpectType number +o1.c; // $ExpectError +// Ember.bind // $ExpectError +// cacheFor +Ember.cacheFor({ a: 123 }, 'a'); // $ExpectType number | undefined +Ember.cacheFor({ a: 123 }, 'x'); // $ExpectError +// compare +Ember.compare('31', '114'); // $ExpectType number +// copy +Ember.copy({ a: 12 }, true).a; // $ExpectType number +Ember.copy({ a: 12 }); // $ExpectType any +Ember.copy({ a: 12 }).a; // $ExpectType any +Ember.copy({ a: 12 }).b; // $ExpectType any +// debug +Ember.debug('some info for developers'); +// deprecate +Ember.deprecate("you shouldn't use this anymore", 3 === 3, { + id: 'no-longer-allowed', + until: '99.0.0' +}); +// get +Ember.get({ z: 23 }, 'z'); // $ExpectType number +Ember.get({ z: 23 }, 'zz'); // $ExpectError +// getEngineParent +Ember.getEngineParent(new Ember.EngineInstance()); // $ExpectType EngineInstance +// getOwner +Ember.getOwner(new Ember.Component()); +// getProperties +Ember.getProperties({ z: 23 }, 'z').z; // $ExpectType number +Ember.getProperties({ z: 23 }, 'z', 'z').z; // $ExpectType number +Ember.getProperties({ z: 23 }, 'z', 'a').z; // $ExpectError +Ember.getProperties({ z: 23 }, ['z', 'z']).z; // $ExpectType number +Ember.getProperties({ z: 23 }, ['z', 'a']).z; // $ExpectError +// getWithDefault +Ember.getWithDefault({ z: 23 }, 'z', 43); // $ExpectType number +Ember.getWithDefault({ a: undefined as number | undefined, z: 23 }, 'a', 99); // $ExpectType number | undefined + +// guidFor +Ember.guidFor({}); // $ExpectType string +Ember.guidFor(''); // $ExpectType string +// isArray +Ember.isArray(''); // $ExpectType boolean +Ember.isArray([]); // $ExpectType boolean +// isBlank +Ember.isBlank(''); // $ExpectType boolean +Ember.isBlank([]); // $ExpectType boolean +// isEmpty +Ember.isEmpty(''); // $ExpectType boolean +Ember.isEmpty([]); // $ExpectType boolean +// isEqual +Ember.isEqual('', 'foo'); // $ExpectType boolean +Ember.isEqual([], ''); // $ExpectType boolean +// isNone +Ember.isNone(''); // $ExpectType boolean +Ember.isNone([]); // $ExpectType boolean +// isPresent +Ember.isPresent(''); // $ExpectType boolean +Ember.isPresent([]); // $ExpectType boolean +// merge +Ember.merge({ a: 12 }, { b: 34 }).a; // $ExpectType number +// observer +const o2 = Ember.Object.extend({ + name: 'foo', + age: 3, + nameWatcher: Ember.observer('name', () => {}), + nameWatcher2: Ember.observer('name', 'fullName', () => {}) +}); +// on +const o3 = Ember.Object.extend({ + name: 'foo', + nameWatcher: Ember.on('init', () => {}), + nameWatcher2: Ember.on('destroy', () => {}) +}); +// removeListener +Ember.addListener(o2, 'create', () => {}); +Ember.addListener({}, 'create', () => {}); // $ExpectError +// removeObserver +Ember.removeObserver(o2, 'create', () => {}); +Ember.removeObserver({}, 'create', () => {}); // $ExpectError +// runInDebug +Ember.runInDebug(() => {}); +// sendEvent +Ember.sendEvent(o2, 'clicked', [1, 2]); // $ExpectType boolean +// set +Ember.set(o2.create(), 'name', 'bar'); // $ExpectType string +Ember.set(o2.create(), 'age', 4); // $ExpectType number +Ember.set(o2.create(), 'nam', 'bar'); // $ExpectError +// setOwner +Ember.setOwner(o2.create(), {}); +// setProperties +Ember.setProperties(o2.create(), { name: 'bar' }).name; // $ExpectType string +// tryInvoke +Ember.tryInvoke(o2, 'init'); +Ember.tryInvoke(o2, 'init', [441]); +// trySet +Ember.trySet(o2, 'nam', ''); // $ExpectType any +// typeOf +Ember.typeOf(''); // $ExpectType "string" +Ember.typeOf(Ember.A()); // $ExpectType "array" +// warn +Ember.warn('be caseful!'); +// VERSION +Ember.VERSION; // $ExpectType string + +// onerror + +Ember.onerror = (err: Error) => console.error(err); +Ember.onerror = (num: number, err: Error) => console.error(err); // $ExpectError + +// Classes +// TODO ContainerProxyMixin +// Ember +// Ember.Application +new Ember.Application(); // $ExpectType Application +Ember.Application.create(); // $ExpectType Application +// Ember.ApplicationInstance +new Ember.ApplicationInstance(); // $ExpectType ApplicationInstance +Ember.ApplicationInstance.create(); // $ExpectType ApplicationInstance +// TODO: Ember.ApplicationInstance.BootOptions +// Ember.Array +const a1: Ember.Array = []; +const a2: Ember.Array = {}; // $ExpectError +// Ember.ArrayProxy +new Ember.ArrayProxy([3, 3, 2]); // $ExpectType ArrayProxy +// Ember.Checkbox +const cb = new Ember.Checkbox(); // $ExpectType Checkbox +cb.tagName; // $ExpectType string +// Ember.Component +const C1 = Ember.Component.extend({ classNames: ['foo'] }); +class C2 extends Ember.Component { + classNames = ['foo']; +} +const c1 = new C1(); +const c2 = new C2(); +C1.create(); +C2.create(); +c1.didInsertElement(); +c2.didInsertElement(); +// Ember.ComputedProperty +const cp: Ember.ComputedProperty = Ember.computed('foo', { + get(): string { + return ''; + }, + set(_key: string, newVal: string): string { + return ''; + } +}); +// Ember.ContainerDebugAdapter +const cda = new Ember.ContainerDebugAdapter(); // $ExpectType ContainerDebugAdapter +// Ember.Controller +const con = new Ember.Controller(); // $ExpectType Controller +// Ember.CoreObject +const co = new Ember.CoreObject(); // $ExpectType CoreObject +// Ember.DataAdapter +const da = new Ember.DataAdapter(); // $ExpectType DataAdapter +// Ember.Debug +Ember.Debug.registerDeprecationHandler(() => {}); +Ember.Debug.registerWarnHandler(() => {}); +// Ember.DefaultResolver +const dr = new Ember.DefaultResolver(); +dr.resolve('route:index'); +dr.resolve(); // $ExpectError +// Ember.Engine +const e1 = new Ember.Engine(); +e1.register('data:foo', {}, { instantiate: false }); +// Ember.EngineInstance +const ei1 = new Ember.EngineInstance(); +ei1.lookup('data:foo'); +// Ember.Error +new Ember.Error('Halp!'); +// Ember.Evented +const oe1 = Ember.Object.extend(Ember.Evented).create(); +oe1.trigger('foo'); +oe1.on('bar', () => {}); +oe1.on('bar', { foo() {}}, () => {}); +// Ember.HashLocation +const hl = new Ember.HashLocation(); // $ExpectType HashLocation +// Ember.Helper +const h1 = Ember.Helper.extend({ + compute() { + this.recompute(); + return ''; + } +}); +// Ember.HistoryLocation +const hil = new Ember.HistoryLocation(); // $ExpectType HistoryLocation +// Ember.LinkComponent +Ember.LinkComponent.create(); // $ExpectType LinkComponent +// Ember.Mixin +Ember.Object.extend(Ember.Mixin.create({ foo: 'bar' }), { + baz() { + this.foo; // $ExpectType string + } +}); +// Ember.MutableArray +const ma1: Ember.MutableArray = [ + 'money', + 'in', + 'the', + 'bananna', + 'stand' +]; +ma1.addObject('!'); // $ExpectType string +ma1.filterBy(''); // $ExpectType NativeArray +// Ember.MutableEnumerable +// tslint:disable-next-line:prefer-const +let me1: Ember.MutableEnumerable<[string]> = null as any; +me1.compact(); // $ExpectType NativeArray<[string]> +// Ember.Namespace +const myNs = Ember.Namespace.extend({}); +// Ember.NativeArray +const na: Ember.NativeArray = Ember.A([2, 3, 4]); +na; // $ExpectType NativeArray +na.clear(); // $ExpectType NativeArray +// Ember.NoneLocation +new Ember.NoneLocation(); // $ExpectType NoneLocation +// Ember.Object +new Ember.Object(); +// Ember.ObjectProxy +new Ember.ObjectProxy(); // $ExpectType ObjectProxy +// Ember.Observable +Ember.Object.extend(Ember.Observable, {}); +// Ember.PromiseProxyMixin +Ember.Object.extend(Ember.PromiseProxyMixin, { + foo() { + this.reason; // $ExpectType any + this.isPending; // $ExpectType boolean + } +}); +// Ember.Route +new Ember.Route(); +// Ember.Router +new Ember.Router(); +// Ember.Service +new Ember.Service(); +// Ember.Test +Ember.Test; +// Ember.Test.Adapter +new Ember.Test.Adapter(); +// Ember.Test.QUnitAdapter +new Ember.Test.QUnitAdapter(); +// Ember.TextArea +new Ember.TextArea(); +// Ember.TextField +new Ember.TextField(); +// Ember.Helper +// helper +Ember.Helper.helper(([a, b]: [number, number]) => a + b); +// Ember.String +Ember.String; +// htmlSafe +Ember.String.htmlSafe('foo'); // $ExpectType SafeString +// isHTMLSafe +Ember.String.isHTMLSafe('foo'); // $ExpectType boolean +// Ember.Test +Ember.Test.checkWaiters(); // $ExpectType boolean +// checkWaiters diff --git a/types/ember/test/error.ts b/types/ember/test/error.ts index ad3c2ee8c3..b19dfe6897 100644 --- a/types/ember/test/error.ts +++ b/types/ember/test/error.ts @@ -1,6 +1,5 @@ import { assertType } from "./lib/assert"; import Ember from "ember"; -import EmberError from "@ember/error"; -assertType(EmberError); +assertType(Ember.Error); diff --git a/types/ember/test/run.ts b/types/ember/test/run.ts index 596ad5eb07..24cc32020c 100755 --- a/types/ember/test/run.ts +++ b/types/ember/test/run.ts @@ -1,12 +1,11 @@ import Ember from 'ember'; import RSVP from 'rsvp'; -import { run } from '@ember/runloop'; import { assertType } from "./lib/assert"; assertType(Ember.run.queues); function testRun() { - const r = run(() => { + const r = Ember.run(() => { // code to be executed within a RunLoop return 123; }); @@ -14,7 +13,7 @@ function testRun() { function destroyApp(application: Ember.Application) { Ember.run(application, 'destroy'); - run(application, function() { + Ember.run(application, function() { this.destroy(); }); } @@ -38,48 +37,48 @@ function testBind() { function testCancel() { const myContext = {}; - const runNext = run.next(myContext, () => { + const runNext = Ember.run.next(myContext, () => { // will not be executed }); - run.cancel(runNext); + Ember.run.cancel(runNext); - const runLater = run.later(myContext, () => { + const runLater = Ember.run.later(myContext, () => { // will not be executed }, 500); - run.cancel(runLater); + Ember.run.cancel(runLater); - const runScheduleOnce = run.scheduleOnce('afterRender', myContext, () => { + const runScheduleOnce = Ember.run.scheduleOnce('afterRender', myContext, () => { // will not be executed }); - run.cancel(runScheduleOnce); + Ember.run.cancel(runScheduleOnce); - const runOnce = run.once(myContext, () => { + const runOnce = Ember.run.once(myContext, () => { // will not be executed }); - run.cancel(runOnce); + Ember.run.cancel(runOnce); - const throttle = run.throttle(myContext, () => { + const throttle = Ember.run.throttle(myContext, () => { // will not be executed }, 1, false); - run.cancel(throttle); + Ember.run.cancel(throttle); - const debounce = run.debounce(myContext, () => { + const debounce = Ember.run.debounce(myContext, () => { // will not be executed }, 1); - run.cancel(debounce); + Ember.run.cancel(debounce); - const debounceImmediate = run.debounce(myContext, () => { + const debounceImmediate = Ember.run.debounce(myContext, () => { // will be executed since we passed in true (immediate) }, 100, true); // the 100ms delay until this method can be called again will be canceled - run.cancel(debounceImmediate); + Ember.run.cancel(debounceImmediate); } function testDebounce() { @@ -88,9 +87,9 @@ function testDebounce() { const myContext = { name: 'debounce' }; - run.debounce(runIt, 150); - run.debounce(myContext, runIt, 150); - run.debounce(myContext, runIt, 150, true); + Ember.run.debounce(runIt, 150); + Ember.run.debounce(myContext, runIt, 150); + Ember.run.debounce(myContext, runIt, 150, true); Ember.Component.extend({ searchValue: 'test', @@ -106,19 +105,19 @@ function testDebounce() { } function testBegin() { - run.begin(); + Ember.run.begin(); // code to be executed within a RunLoop - run.end(); + Ember.run.end(); } function testJoin() { - run.join(() => { + Ember.run.join(() => { // creates a new run-loop }); - run(() => { + Ember.run(() => { // creates a new run-loop - run.join(() => { + Ember.run.join(() => { // joins with the existing run-loop, and queues for invocation on // the existing run-loops action queue. }); @@ -133,14 +132,14 @@ function testJoin() { function testLater() { const myContext = {}; - run.later(myContext, () => { + Ember.run.later(myContext, () => { // code here will execute within a RunLoop in about 500ms with this == myContext }, 500); } function testNext() { const myContext = {}; - run.next(myContext, () => { + Ember.run.next(myContext, () => { // code to be executed in the next run loop, // which will be scheduled after the current one }); @@ -160,12 +159,12 @@ function testOnce() { function testSchedule() { Ember.Component.extend({ init() { - run.schedule('sync', this, () => { + Ember.run.schedule('sync', this, () => { // this will be executed in the first RunLoop queue, when bindings are synced console.log('scheduled on sync queue'); }); - run.schedule('actions', this, () => { + Ember.run.schedule('actions', this, () => { // this will be executed in the 'actions' queue, after bindings have synced. console.log('scheduled on actions queue'); }); @@ -183,12 +182,12 @@ function testScheduleOnce() { } const myContext = {}; - run(() => { - run.scheduleOnce('afterRender', myContext, sayHi); - run.scheduleOnce('afterRender', myContext, sayHi); + Ember.run(() => { + Ember.run.scheduleOnce('afterRender', myContext, sayHi); + Ember.run.scheduleOnce('afterRender', myContext, sayHi); // sayHi will only be executed once, in the afterRender queue of the RunLoop }); - run.scheduleOnce('actions', myContext, () => { + Ember.run.scheduleOnce('actions', myContext, () => { console.log('Closure'); }); } @@ -199,6 +198,6 @@ function testThrottle() { const myContext = { name: 'throttle' }; - run.throttle(runIt, 150); - run.throttle(myContext, runIt, 150); + Ember.run.throttle(runIt, 150); + Ember.run.throttle(myContext, runIt, 150); } diff --git a/types/ember/tsconfig.json b/types/ember/tsconfig.json index 7df2202cb8..8a2cec5578 100755 --- a/types/ember/tsconfig.json +++ b/types/ember/tsconfig.json @@ -18,14 +18,27 @@ "@ember/string": ["ember__string"], "@ember/engine": ["ember__engine"], "@ember/engine/*": ["ember__engine/*"], + "@ember/error": ["ember__error"], + "@ember/service": ["ember__service"], "@ember/utils": ["ember__utils"], "@ember/utils/*": ["ember__utils/*"], "@ember/array": ["ember__array"], "@ember/array/*": ["ember__array/*"], "@ember/debug": ["ember__debug"], "@ember/debug/*": ["ember__debug/*"], + "@ember/runloop": ["ember__runloop"], + "@ember/runloop/*": ["ember__runloop/*"], + "@ember/routing": ["ember__routing"], + "@ember/routing/*": ["ember__routing/*"], + "@ember/test": ["ember__test"], + "@ember/test/*": ["ember__test/*"], "@ember/object": ["ember__object"], "@ember/object/*": ["ember__object/*"], + "@ember/component": ["ember__component"], + "@ember/component/*": ["ember__component/*"], + "@ember/application": ["ember__application"], + "@ember/application/*": ["ember__application/*"], + "@ember/controller": ["ember__controller"], "@ember/polyfills": ["ember__polyfills"] }, "types": [], @@ -54,6 +67,7 @@ "test/debug.ts", "test/detect-instance.ts", "test/detect.ts", + "test/ember-module-tests.ts", "test/ember-tests.ts", "test/engine-instance.ts", "test/engine.ts", diff --git a/types/ember__application/-private/default-resolver.d.ts b/types/ember__application/-private/default-resolver.d.ts new file mode 100644 index 0000000000..85cc676e24 --- /dev/null +++ b/types/ember__application/-private/default-resolver.d.ts @@ -0,0 +1,21 @@ +import Resolver from "@ember/engine/-private/resolver"; +import Application from "@ember/application"; + +/** + * The DefaultResolver defines the default lookup rules to resolve + * container lookups before consulting the container for registered + * items: + */ +export default class DefaultResolver extends Resolver { + /** + * This method is called via the container's resolver method. + * It parses the provided `fullName` and then looks up and + * returns the appropriate template or class. + */ + resolve(fullName: string): {}; + /** + * This will be set to the Application instance when it is + * created. + */ + namespace: Application; +} diff --git a/types/ember__application/-private/event-dispatcher.d.ts b/types/ember__application/-private/event-dispatcher.d.ts new file mode 100644 index 0000000000..d70217cc5f --- /dev/null +++ b/types/ember__application/-private/event-dispatcher.d.ts @@ -0,0 +1,16 @@ +import { EventDispatcherEvents } from "@ember/application/types"; + +/** + * `Ember.EventDispatcher` handles delegating browser events to their + * corresponding `Ember.Views.` For example, when you click on a view, + * `Ember.EventDispatcher` ensures that that view's `mouseDown` method gets + * called. + */ +export default class EventDispatcher extends Object { + /** + * The set of events names (and associated handler function names) to be setup + * and dispatched by the `EventDispatcher`. Modifications to this list can be done + * at setup time, generally via the `Ember.Application.customEvents` hash. + */ + events: EventDispatcherEvents; +} diff --git a/types/ember__application/-private/registry.d.ts b/types/ember__application/-private/registry.d.ts new file mode 100644 index 0000000000..94ed25ef9a --- /dev/null +++ b/types/ember__application/-private/registry.d.ts @@ -0,0 +1,13 @@ +import { EmberClassConstructor } from "@ember/object/-private/types"; + +/** + * A registry used to store factory and option information keyed + * by type. + */ +export default class Registry { + register( + fullName: string, + factory: EmberClassConstructor, + options?: { singleton?: boolean } + ): void; +} diff --git a/types/ember__application/deprecations.d.ts b/types/ember__application/deprecations.d.ts index 608ba5c7f7..a74babd084 100644 --- a/types/ember__application/deprecations.d.ts +++ b/types/ember__application/deprecations.d.ts @@ -1,4 +1,35 @@ -import Ember from 'ember'; +/** + * Display a deprecation warning with the provided message and a stack trace + * (Chrome and Firefox only). + */ +export function deprecate( + message: string, + test: boolean, + options: { id: string; until: string } +): any; -export const deprecate: typeof Ember.deprecate; -export const deprecateFunc: typeof Ember.deprecateFunc; +/** + * @deprecated Missing deprecation options: https://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options + */ +export function deprecate( + message: string, + test: boolean, + options?: { id?: string; until?: string } +): any; + +/** + * @deprecated Missing deprecation options: https://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options + */ +export function deprecateFunc any)>( + message: string, + func: Func +): Func; + +/** + * Alias an old, deprecated method with its new counterpart. + */ +export function deprecateFunc any)>( + message: string, + options: { id: string; until: string }, + func: Func +): Func; diff --git a/types/ember__application/globals-resolver.d.ts b/types/ember__application/globals-resolver.d.ts index e51f4681ed..5cb428ad5c 100644 --- a/types/ember__application/globals-resolver.d.ts +++ b/types/ember__application/globals-resolver.d.ts @@ -1,3 +1 @@ -import Ember from 'ember'; - -export default class GlobalsResolver extends Ember.DefaultResolver { } +export { default } from '@ember/application/-private/default-resolver'; diff --git a/types/ember__application/index.d.ts b/types/ember__application/index.d.ts index cdef372444..aa1a5a1889 100644 --- a/types/ember__application/index.d.ts +++ b/types/ember__application/index.d.ts @@ -4,10 +4,133 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.8 -import Ember from 'ember'; +import Engine from '@ember/engine'; +import ApplicationInstance from '@ember/application/instance'; +import EventDispatcher from '@ember/application/-private/event-dispatcher'; +import { EventDispatcherEvents } from '@ember/application/types'; +import DefaultResolver from '@ember/application/-private/default-resolver'; +import { Router } from '@ember/routing'; +import Registry from '@ember/application/-private/registry'; -export default class Application extends Ember.Application { } -export const getOwner: typeof Ember.getOwner; -export const onLoad: typeof Ember.onLoad; -export const runLoadHooks: typeof Ember.runLoadHooks; -export const setOwner: typeof Ember.setOwner; +/** + * An instance of Ember.Application is the starting point for every Ember application. It helps to + * instantiate, initialize and coordinate the many objects that make up your app. + */ +export default class Application extends Engine { + /** + * Call advanceReadiness after any asynchronous setup logic has completed. + * Each call to deferReadiness must be matched by a call to advanceReadiness + * or the application will never become ready and routing will not begin. + */ + advanceReadiness(): void; + /** + * Use this to defer readiness until some condition is true. + * + * This allows you to perform asynchronous setup logic and defer + * booting your application until the setup has finished. + * + * However, if the setup requires a loading UI, it might be better + * to use the router for this purpose. + */ + deferReadiness(): void; + /** + * defines an injection or typeInjection + */ + inject(factoryNameOrType: string, property: string, injectionName: string): void; + /** + * This injects the test helpers into the window's scope. If a function of the + * same name has already been defined it will be cached (so that it can be reset + * if the helper is removed with `unregisterHelper` or `removeTestHelpers`). + * Any callbacks registered with `onInjectHelpers` will be called once the + * helpers have been injected. + */ + injectTestHelpers(): void; + /** + * registers a factory for later injection + * @param fullName type:name (e.g., 'model:user') + * @param factory (e.g., App.Person) + */ + register(fullName: string, factory: any): void; + /** + * This removes all helpers that have been registered, and resets and functions + * that were overridden by the helpers. + */ + removeTestHelpers(): void; + /** + * Reset the application. This is typically used only in tests. + */ + reset(): void; + /** + * This hook defers the readiness of the application, so that you can start + * the app when your tests are ready to run. It also sets the router's + * location to 'none', so that the window's location will not be modified + * (preventing both accidental leaking of state between tests and interference + * with your testing framework). + */ + setupForTesting(): void; + /** + * The DOM events for which the event dispatcher should listen. + */ + customEvents: EventDispatcherEvents; + /** + * The Ember.EventDispatcher responsible for delegating events to this application's views. + */ + eventDispatcher: EventDispatcher; + /** + * Set this to provide an alternate class to Ember.DefaultResolver + */ + resolver: DefaultResolver; + /** + * The root DOM element of the Application. This can be specified as an + * element or a jQuery-compatible selector string. + * + * This is the element that will be passed to the Application's, eventDispatcher, + * which sets up the listeners for event delegation. Every view in your application + * should be a child of the element you specify here. + */ + rootElement: HTMLElement | string; + /** + * Called when the Application has become ready. + * The call will be delayed until the DOM has become ready. + */ + ready: (...args: any[]) => any; + /** + * Application's router. + */ + Router: Router; + registry: Registry; + /** + * Initialize the application and return a promise that resolves with the `Application` + * object when the boot process is complete. + */ + boot(): Promise; + /** + * Create an ApplicationInstance for this Application. + */ + buildInstance(options?: object): ApplicationInstance; +} + +/** + * Framework objects in an Ember application (components, services, routes, etc.) + * are created via a factory and dependency injection system. Each of these + * objects is the responsibility of an "owner", which handled its + * instantiation and manages its lifetime. + */ +export function getOwner(object: any): any; +/** + * `setOwner` forces a new owner on a given object instance. This is primarily + * useful in some testing cases. + */ +export function setOwner(object: any, owner: any): void; + +/** + * Detects when a specific package of Ember (e.g. 'Ember.Application') + * has fully loaded and is available for extension. + */ +export function onLoad(name: string, callback: (...args: any[]) => any): any; + +/** + * Called when an Ember.js package (e.g Ember.Application) has finished + * loading. Triggers any callbacks registered for this event. + */ +export function runLoadHooks(name: string, object?: {}): any; diff --git a/types/ember__application/instance.d.ts b/types/ember__application/instance.d.ts index 0d01298d52..db5f37fcd5 100644 --- a/types/ember__application/instance.d.ts +++ b/types/ember__application/instance.d.ts @@ -1,3 +1,7 @@ -import Ember from 'ember'; +import EngineInstance from "@ember/engine/instance"; -export default class ApplicationInstance extends Ember.ApplicationInstance { } +/** + * The `ApplicationInstance` encapsulates all of the stateful aspects of a + * running `Application`. + */ +export default class ApplicationInstance extends EngineInstance {} diff --git a/types/ember__application/resolver.d.ts b/types/ember__application/resolver.d.ts index a218fcd3e7..326352ac49 100644 --- a/types/ember__application/resolver.d.ts +++ b/types/ember__application/resolver.d.ts @@ -1,3 +1,3 @@ -import Ember from 'ember'; +import EmberObject from '@ember/object'; -export default class Resolver extends Ember.Resolver { } +export default class Resolver extends EmberObject {} diff --git a/types/ember__application/tsconfig.json b/types/ember__application/tsconfig.json index 7be641d164..c83da0b13d 100644 --- a/types/ember__application/tsconfig.json +++ b/types/ember__application/tsconfig.json @@ -19,6 +19,8 @@ "@ember/object/*": ["ember__object/*"], "@ember/engine": ["ember__engine"], "@ember/engine/*": ["ember__engine/*"], + "@ember/routing": ["ember__routing"], + "@ember/routing/*": ["ember__routing/*"], "@ember/application": ["ember__application"], "@ember/application/*": ["ember__application/*"] }, @@ -32,6 +34,10 @@ "index.d.ts", "instance.d.ts", "resolver.d.ts", + "types.d.ts", + "-private/default-resolver.d.ts", + "-private/event-dispatcher.d.ts", + "-private/registry.d.ts", "test/application.ts", "test/deprecations.ts", "test/resolver.ts", diff --git a/types/ember__application/types.d.ts b/types/ember__application/types.d.ts new file mode 100644 index 0000000000..aa5d41877c --- /dev/null +++ b/types/ember__application/types.d.ts @@ -0,0 +1,30 @@ +export interface EventDispatcherEvents { + touchstart?: string | null; + touchmove?: string | null; + touchend?: string | null; + touchcancel?: string | null; + keydown?: string | null; + keyup?: string | null; + keypress?: string | null; + mousedown?: string | null; + mouseup?: string | null; + contextmenu?: string | null; + click?: string | null; + dblclick?: string | null; + mousemove?: string | null; + focusin?: string | null; + focusout?: string | null; + mouseenter?: string | null; + mouseleave?: string | null; + submit?: string | null; + input?: string | null; + change?: string | null; + dragstart?: string | null; + drag?: string | null; + dragenter?: string | null; + dragleave?: string | null; + dragover?: string | null; + drop?: string | null; + dragend?: string | null; + [event: string]: string | null | undefined; +} diff --git a/types/ember__component/-private/action-support.d.ts b/types/ember__component/-private/action-support.d.ts new file mode 100644 index 0000000000..6e8e41a2ab --- /dev/null +++ b/types/ember__component/-private/action-support.d.ts @@ -0,0 +1,8 @@ +import Mixin from "@ember/object/mixin"; + +interface ActionSupport { + sendAction(action: string, ...params: any[]): void; +} +declare const ActionSupport: Mixin; + +export default ActionSupport; diff --git a/types/ember__component/-private/class-names-support.d.ts b/types/ember__component/-private/class-names-support.d.ts new file mode 100644 index 0000000000..2173c22fa8 --- /dev/null +++ b/types/ember__component/-private/class-names-support.d.ts @@ -0,0 +1,25 @@ +import Mixin from "@ember/object/mixin"; + +interface ClassNamesSupport { + /** + * A list of properties of the view to apply as class names. If the property is a string value, + * the value of that string will be applied as a class name. + * + * If the value of the property is a Boolean, the name of that property is added as a dasherized + * class name. + * + * If you would prefer to use a custom value instead of the dasherized property name, you can + * pass a binding like this: `classNameBindings: ['isUrgent:urgent']` + * + * This list of properties is inherited from the component's superclasses as well. + */ + classNameBindings: string[]; + /** + * Standard CSS class names to apply to the view's outer element. This + * property automatically inherits any class names defined by the view's + * superclasses as well. + */ + classNames: string[]; +} +declare const ClassNamesSupport: Mixin; +export default ClassNamesSupport; diff --git a/types/ember__component/-private/core-view.d.ts b/types/ember__component/-private/core-view.d.ts new file mode 100644 index 0000000000..82da4d4208 --- /dev/null +++ b/types/ember__component/-private/core-view.d.ts @@ -0,0 +1,11 @@ +import EmberObject from "@ember/object"; +import Evented from "@ember/object/evented"; +import ActionHandler from "@ember/object/-private/action-handler"; + +/** + * Ember.CoreView is an abstract class that exists to give view-like behavior to both Ember's main + * view class Ember.Component and other classes that don't need the full functionality of Ember.Component. + * + * Unless you have specific needs for CoreView, you will use Ember.Component in your applications. + */ +export default class CoreView extends EmberObject.extend(Evented, ActionHandler) {} diff --git a/types/ember__component/-private/target-action-support.d.ts b/types/ember__component/-private/target-action-support.d.ts new file mode 100644 index 0000000000..8d5dc49725 --- /dev/null +++ b/types/ember__component/-private/target-action-support.d.ts @@ -0,0 +1,18 @@ +import EmberObject from "@ember/object"; + +// tslint:disable-next-line:strict-export-declare-modifiers +interface TriggerActionOptions { + action?: string; + target?: EmberObject; + actionContext?: EmberObject; +} + +/** + * Ember.TargetActionSupport is a mixin that can be included in a class to add a triggerAction method + * with semantics similar to the Handlebars {{action}} helper. In normal Ember usage, the {{action}} + * helper is usually the best choice. This mixin is most often useful when you are doing more + * complex event handling in Components. + */ +export default interface TargetActionSupport { + triggerAction(opts: TriggerActionOptions): boolean; +} diff --git a/types/ember__component/-private/text-support.d.ts b/types/ember__component/-private/text-support.d.ts new file mode 100644 index 0000000000..ee523e1473 --- /dev/null +++ b/types/ember__component/-private/text-support.d.ts @@ -0,0 +1,30 @@ +import TargetActionSupport from "@ember/component/-private/target-action-support"; +import Mixin from "@ember/object/mixin"; + +/** + * `TextSupport` is a shared mixin used by both `Ember.TextField` and + * `Ember.TextArea`. `TextSupport` adds a number of methods that allow you to + * specify a controller action to invoke when a certain event is fired on your + * text field or textarea. The specifed controller action would get the current + * value of the field passed in as the only argument unless the value of + * the field is empty. In that case, the instance of the field itself is passed + * in as the only argument. + */ +interface TextSupport extends TargetActionSupport { + // tslint:disable-next-line:ban-types + cancel(event: Function): void; + // tslint:disable-next-line:ban-types + focusIn(event: Function): void; + // tslint:disable-next-line:ban-types + focusOut(event: Function): void; + // tslint:disable-next-line:ban-types + insertNewLine(event: Function): void; + // tslint:disable-next-line:ban-types + keyPress(event: Function): void; + action: string; + bubbles: boolean; + onEvent: string; +} +declare const TextSupport: Mixin; + +export default TextSupport; diff --git a/types/ember__component/-private/view-mixin.d.ts b/types/ember__component/-private/view-mixin.d.ts new file mode 100644 index 0000000000..fe4d232b92 --- /dev/null +++ b/types/ember__component/-private/view-mixin.d.ts @@ -0,0 +1,63 @@ +import Mixin from "@ember/object/mixin"; + +interface ViewMixin { + /** + * A list of properties of the view to apply as attributes. If the property + * is a string value, the value of that string will be applied as the value + * for an attribute of the property's name. + */ + attributeBindings: string[]; + /** + * Returns the current DOM element for the view. + */ + element: Element; + /** + * Returns a jQuery object for this view's element. If you pass in a selector + * string, this method will return a jQuery object, using the current element + * as its buffer. + */ + $: JQueryStatic; + /** + * The HTML `id` of the view's element in the DOM. You can provide this + * value yourself but it must be unique (just as in HTML): + */ + elementId: string; + /** + * Tag name for the view's outer element. The tag name is only used when an + * element is first created. If you change the `tagName` for an element, you + * must destroy and recreate the view element. + */ + tagName: string; + /** + * Renders the view again. This will work regardless of whether the + * view is already in the DOM or not. If the view is in the DOM, the + * rendering process will be deferred to give bindings a chance + * to synchronize. + */ + rerender(): void; + /** + * Called when a view is going to insert an element into the DOM. + */ + willInsertElement(): void; + /** + * Called when the element of the view has been inserted into the DOM. + * Override this function to do any set up that requires an element + * in the document body. + */ + didInsertElement(): void; + /** + * Called when the view is about to rerender, but before anything has + * been torn down. This is a good opportunity to tear down any manual + * observers you have installed based on the DOM state + */ + willClearRender(): void; + /** + * Called when the element of the view is going to be destroyed. Override + * this function to do any teardown that requires an element, like removing + * event listeners. + */ + willDestroyElement(): void; +} +declare const ViewMixin: Mixin; + +export default ViewMixin; diff --git a/types/ember__component/checkbox.d.ts b/types/ember__component/checkbox.d.ts index a71ee3602e..27bfc81477 100644 --- a/types/ember__component/checkbox.d.ts +++ b/types/ember__component/checkbox.d.ts @@ -1,3 +1,8 @@ import Ember from 'ember'; +import Component from '@ember/component'; -export default class Checkbox extends Ember.Checkbox { } +/** + * The internal class used to create text inputs when the {{input}} helper is used + * with type of checkbox. See Handlebars.helpers.input for usage details. + */ +export default class Checkbox extends Component {} diff --git a/types/ember__component/helper.d.ts b/types/ember__component/helper.d.ts index e89e6eab84..9acfb40e34 100644 --- a/types/ember__component/helper.d.ts +++ b/types/ember__component/helper.d.ts @@ -1,6 +1,27 @@ -import Ember from 'ember'; +import EmberObject from "@ember/object"; + +/** + * Ember Helpers are functions that can compute values, and are used in templates. + * For example, this code calls a helper named `format-currency`: + */ +export default class Helper extends EmberObject { + /** + * In many cases, the ceremony of a full `Ember.Helper` class is not required. + * The `helper` method create pure-function helpers without instances. For + * example: + */ + static helper(helper: (params: any[], hash?: object) => any): Helper; + /** + * Override this function when writing a class-based helper. + */ + compute(params: any[], hash: object): any; + /** + * On a class-based helper, it may be useful to force a recomputation of that + * helpers value. This is akin to `rerender` on a component. + */ + recompute(): any; +} -export default class Helper extends Ember.Helper { } /** * In many cases, the ceremony of a full `Helper` class is not required. * The `helper` method create pure-function helpers without instances. For diff --git a/types/ember__component/index.d.ts b/types/ember__component/index.d.ts index 147d717e2b..1afaa371cb 100644 --- a/types/ember__component/index.d.ts +++ b/types/ember__component/index.d.ts @@ -4,6 +4,92 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.8 -import Ember from 'ember'; +/// -export default class Component extends Ember.Component { } +import CoreView from "@ember/component/-private/core-view"; +import ClassNamesSupport from "@ember/component/-private/class-names-support"; +import ViewMixin from "@ember/component/-private/view-mixin"; +import ActionSupport from "@ember/component/-private/action-support"; + +// tslint:disable-next-line:strict-export-declare-modifiers +interface TemplateFactory { + __htmlbars_inline_precompile_template_factory: any; +} + +/** + * A view that is completely isolated. Property access in its templates go to the view object + * and actions are targeted at the view object. There is no access to the surrounding context or + * outer controller; all contextual information is passed in. + */ +export default class Component extends CoreView.extend( + ViewMixin, + ActionSupport, + ClassNamesSupport +) { + // methods + readDOMAttr(name: string): string; + // properties + /** + * The WAI-ARIA role of the control represented by this view. For example, a button may have a + * role of type 'button', or a pane may have a role of type 'alertdialog'. This property is + * used by assistive software to help visually challenged users navigate rich web applications. + */ + ariaRole: string; + /** + * The HTML id of the component's element in the DOM. You can provide this value yourself but + * it must be unique (just as in HTML): + * + * If not manually set a default value will be provided by the framework. Once rendered an + * element's elementId is considered immutable and you should never change it. If you need + * to compute a dynamic value for the elementId, you should do this when the component or + * element is being instantiated: + */ + elementId: string; + /** + * If false, the view will appear hidden in DOM. + */ + isVisible: boolean; + /** + * A component may contain a layout. A layout is a regular template but supersedes the template + * property during rendering. It is the responsibility of the layout template to retrieve the + * template property from the component (or alternatively, call Handlebars.helpers.yield, + * {{yield}}) to render it in the correct location. This is useful for a component that has a + * shared wrapper, but which delegates the rendering of the contents of the wrapper to the + * template property on a subclass. + */ + layout: TemplateFactory | string; + /** + * Enables components to take a list of parameters as arguments. + */ + static positionalParams: string[] | string; + // events + /** + * Called when the attributes passed into the component have been updated. Called both during the + * initial render of a container and during a rerender. Can be used in place of an observer; code + * placed here will be executed every time any attribute updates. + */ + didReceiveAttrs(): void; + /** + * Called after a component has been rendered, both on initial render and in subsequent rerenders. + */ + didRender(): void; + /** + * Called when the component has updated and rerendered itself. Called only during a rerender, + * not during an initial render. + */ + didUpdate(): void; + /** + * Called when the attributes passed into the component have been changed. Called only during a + * rerender, not during an initial render. + */ + didUpdateAttrs(): void; + /** + * Called before a component has been rendered, both on initial render and in subsequent rerenders. + */ + willRender(): void; + /** + * Called when the component is about to update and rerender itself. Called only during a rerender, + * not during an initial render. + */ + willUpdate(): void; +} diff --git a/types/ember__component/text-area.d.ts b/types/ember__component/text-area.d.ts index 859700a2d8..788b1899ce 100644 --- a/types/ember__component/text-area.d.ts +++ b/types/ember__component/text-area.d.ts @@ -1,3 +1,8 @@ -import Ember from 'ember'; +import TextSupport from "@ember/component/-private/text-support"; +import Component from "@ember/component"; -export default class TextArea extends Ember.TextArea { } +/** + * The internal class used to create textarea element when the `{{textarea}}` + * helper is used. + */ +export default class TextArea extends Component.extend(TextSupport) {} diff --git a/types/ember__component/text-field.d.ts b/types/ember__component/text-field.d.ts index 873995224b..05d786468f 100644 --- a/types/ember__component/text-field.d.ts +++ b/types/ember__component/text-field.d.ts @@ -1,3 +1,33 @@ -import Ember from 'ember'; - -export default class TextField extends Ember.TextField { } +import Component from "@ember/component"; +import TextSupport from '@ember/component/-private/text-support'; +/** + * The internal class used to create text inputs when the `{{input}}` + * helper is used with `type` of `text`. + */ +export default class TextField extends Component.extend(TextSupport) { + /** + * The `value` attribute of the input element. As the user inputs text, this + * property is updated live. + */ + value: string; + /** + * The `type` attribute of the input element. + */ + type: string; + /** + * The `size` of the text field in characters. + */ + size: string; + /** + * The `pattern` attribute of input element. + */ + pattern: string; + /** + * The `min` attribute of input element used with `type="number"` or `type="range"`. + */ + min: string; + /** + * The `max` attribute of input element used with `type="number"` or `type="range"`. + */ + max: string; +} diff --git a/types/ember__component/tsconfig.json b/types/ember__component/tsconfig.json index 6e4de73f32..23411b5e01 100644 --- a/types/ember__component/tsconfig.json +++ b/types/ember__component/tsconfig.json @@ -17,6 +17,8 @@ "paths": { "@ember/object": ["ember__object"], "@ember/object/*": ["ember__object/*"], + "@ember/controller": ["ember__controller"], + "@ember/controller/*": ["ember__controller/*"], "@ember/component": ["ember__component"], "@ember/component/*": ["ember__component/*"] }, @@ -30,6 +32,12 @@ "text-area.d.ts", "text-field.d.ts", "helper.d.ts", + "-private/core-view.d.ts", + "-private/class-names-support.d.ts", + "-private/view-mixin.d.ts", + "-private/action-support.d.ts", + "-private/target-action-support.d.ts", + "-private/text-support.d.ts", "test/lib/assert.ts", "test/component.ts", "test/helper.ts" diff --git a/types/ember__controller/index.d.ts b/types/ember__controller/index.d.ts index f7505359b6..9fd2672323 100644 --- a/types/ember__controller/index.d.ts +++ b/types/ember__controller/index.d.ts @@ -4,10 +4,36 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.8 -import Ember from 'ember'; +import ActionHandler from '@ember/object/-private/action-handler'; +import Mixin from '@ember/object/mixin'; +import EmberObject from '@ember/object'; +import ComputedProperty from '@ember/object/computed'; -export default class Controller extends Ember.Controller { } -export const inject: typeof Ember.inject.controller; +// tslint:disable-next-line strict-export-declare-modifiers +type QueryParamTypes = 'boolean' | 'number' | 'array' | 'string'; +// tslint:disable-next-line strict-export-declare-modifiers +type QueryParamScopeTypes = 'controller' | 'model'; + +/** + * Additional methods for the Controller. + */ +export interface ControllerMixin extends ActionHandler { + replaceRoute(name: string, ...args: any[]): void; + transitionToRoute(name: string, ...args: any[]): void; + model: any; + queryParams: string | string[] | Array<{ [key: string]: { + type?: QueryParamTypes, + scope?: QueryParamScopeTypes, + as?: string + }}>; + target: object; +} +export const ControllerMixin: Mixin; +// tslint:disable-next-line:no-empty-interface +export default class Controller extends EmberObject.extend(ControllerMixin) {} +export function inject( + name: K +): ComputedProperty; // A type registry for Ember `Controller`s. Meant to be declaration-merged // so string lookups resolve to the correct type. diff --git a/types/ember__debug/data-adapter.d.ts b/types/ember__debug/data-adapter.d.ts index c3e44f9a39..cd8e691a64 100644 --- a/types/ember__debug/data-adapter.d.ts +++ b/types/ember__debug/data-adapter.d.ts @@ -1,6 +1,7 @@ import ContainerDebugAdapter from "@ember/debug/container-debug-adapter"; import EmberObject from "@ember/object"; +// tslint:disable-next-line:strict-export-declare-modifiers declare namespace DataAdapter { interface Column { name: string; @@ -25,7 +26,7 @@ declare namespace DataAdapter { * The `DataAdapter` helps a data persistence library * interface with tools that debug Ember such as Chrome and Firefox. */ -declare class DataAdapter extends EmberObject { +export default class DataAdapter extends EmberObject { /** * The container-debug-adapter which is used * to list all models. @@ -60,5 +61,3 @@ declare class DataAdapter extends EmberObject { recordsRemoved: (idx: number, count: number) => void ): () => void; } - -export default DataAdapter; diff --git a/types/ember__error/index.d.ts b/types/ember__error/index.d.ts index 40a660ae0e..3b3d2c5623 100644 --- a/types/ember__error/index.d.ts +++ b/types/ember__error/index.d.ts @@ -4,7 +4,7 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.8 -import Ember from 'ember'; - -declare const Error: typeof Ember.Error; -export default Error; +/** + * A subclass of the JavaScript Error object for use in Ember. + */ +export default ErrorConstructor; diff --git a/types/ember__object/-private/action-handler.d.ts b/types/ember__object/-private/action-handler.d.ts new file mode 100644 index 0000000000..1c98a775c5 --- /dev/null +++ b/types/ember__object/-private/action-handler.d.ts @@ -0,0 +1,28 @@ +import Mixin from "@ember/object/mixin"; + +interface ActionsHash { + [index: string]: (...params: any[]) => any; +} + +/** + * Ember.ActionHandler is available on some familiar classes including Ember.Route, + * Ember.Component, and Ember.Controller. (Internally the mixin is used by Ember.CoreView, + * Ember.ControllerMixin, and Ember.Route and available to the above classes through inheritance.) + */ +interface ActionHandler { + /** + * Triggers a named action on the ActionHandler. Any parameters supplied after the actionName + * string will be passed as arguments to the action target function. + * + * If the ActionHandler has its target property set, actions may bubble to the target. + * Bubbling happens when an actionName can not be found in the ActionHandler's actions + * hash or if the action target function returns true. + */ + send(actionName: string, ...args: any[]): void; + /** + * The collection of functions, keyed by name, available on this ActionHandler as action targets. + */ + actions: ActionsHash; +} +declare const ActionHandler: Mixin; +export default ActionHandler; diff --git a/types/ember__object/internals.d.ts b/types/ember__object/internals.d.ts index 5629b7e3bc..e920311d45 100644 --- a/types/ember__object/internals.d.ts +++ b/types/ember__object/internals.d.ts @@ -14,6 +14,7 @@ export function cacheFor( * Creates a shallow copy of the passed object. A deep copy of the object is * returned if the optional `deep` argument is `true`. */ +export function copy(obj: T, deep: true): T; export function copy(obj: any, deep?: boolean): any; /** * Returns a unique id for the object. If the object does not yet have a guid, diff --git a/types/ember__object/tsconfig.json b/types/ember__object/tsconfig.json index aa4a5ee9e2..5ed61a24d3 100644 --- a/types/ember__object/tsconfig.json +++ b/types/ember__object/tsconfig.json @@ -36,6 +36,7 @@ "proxy.d.ts", "-private/types.d.ts", "-private/copyable.d.ts", + "-private/action-handler.d.ts", "test/lib/assert.ts", "test/access-modifier.ts", "test/core.ts", diff --git a/types/ember__routing/-private/router-dsl.d.ts b/types/ember__routing/-private/router-dsl.d.ts new file mode 100644 index 0000000000..432831bc3b --- /dev/null +++ b/types/ember__routing/-private/router-dsl.d.ts @@ -0,0 +1,18 @@ +export default class RouterDSL { + constructor(name: string, options: object); + route(name: string, callback: (this: RouterDSL) => void): void; + route( + name: string, + options?: { path?: string; resetNamespace?: boolean }, + callback?: (this: RouterDSL) => void + ): void; + mount( + name: string, + options?: { + as?: string, + path?: string, + resetNamespace?: boolean, + engineInfo?: any + } + ): void; +} diff --git a/types/ember__routing/-private/transition.d.ts b/types/ember__routing/-private/transition.d.ts new file mode 100644 index 0000000000..53d06f80e8 --- /dev/null +++ b/types/ember__routing/-private/transition.d.ts @@ -0,0 +1,13 @@ +export default interface Transition { + /** + * Aborts the Transition. Note you can also implicitly abort a transition + * by initiating another transition while a previous one is underway. + */ + abort(): Transition; + /** + * Retries a previously-aborted transition (making sure to abort the + * transition if it's still active). Returns a new transition that + * represents the new attempt to transition. + */ + retry(): Transition; +} diff --git a/types/ember__routing/auto-location.d.ts b/types/ember__routing/auto-location.d.ts index 0c41a582f0..86be671620 100644 --- a/types/ember__routing/auto-location.d.ts +++ b/types/ember__routing/auto-location.d.ts @@ -1,3 +1,6 @@ -import Ember from 'ember'; +import EmberObject from "@ember/object"; -export default class AutoLocation extends Ember.AutoLocation { } +/** + * AutoLocation will select the best location option based off browser support with the priority order: history, hash, none. + */ +export default class AutoLocation extends EmberObject {} diff --git a/types/ember__routing/hash-location.d.ts b/types/ember__routing/hash-location.d.ts index d55efdc3d8..a045285fbc 100644 --- a/types/ember__routing/hash-location.d.ts +++ b/types/ember__routing/hash-location.d.ts @@ -1,3 +1,8 @@ -import Ember from 'ember'; +import EmberObject from "@ember/object"; -export default class HashLocation extends Ember.HashLocation { } +/** + * `Ember.HashLocation` implements the location API using the browser's + * hash. At present, it relies on a `hashchange` event existing in the + * browser. + */ +export default class HashLocation extends EmberObject {} diff --git a/types/ember__routing/history-location.d.ts b/types/ember__routing/history-location.d.ts index 342fe5f266..8921fdb15e 100644 --- a/types/ember__routing/history-location.d.ts +++ b/types/ember__routing/history-location.d.ts @@ -1,3 +1,7 @@ -import Ember from 'ember'; +import EmberObject from "@ember/object"; -export default class HistoryLocation extends Ember.HistoryLocation { } +/** + * Ember.HistoryLocation implements the location API using the browser's + * history.pushState API. + */ +export default class HistoryLocation extends EmberObject {} diff --git a/types/ember__routing/index.d.ts b/types/ember__routing/index.d.ts index 76953906b1..38488fa6b8 100644 --- a/types/ember__routing/index.d.ts +++ b/types/ember__routing/index.d.ts @@ -6,3 +6,9 @@ export { default as Route } from '@ember/routing/route'; export { default as Router } from '@ember/routing/router'; +import RouterService from '@ember/routing/router-service'; + +// tslint:disable-next-line:strict-export-declare-modifiers +interface Registry { + 'router': RouterService; +} diff --git a/types/ember__routing/link-component.d.ts b/types/ember__routing/link-component.d.ts index 5fbec30c21..42d89754f5 100644 --- a/types/ember__routing/link-component.d.ts +++ b/types/ember__routing/link-component.d.ts @@ -1,3 +1,39 @@ -import Ember from 'ember'; +import Component from "@ember/component"; -export default class LinkComponent extends Ember.LinkComponent { } +/** + * `Ember.LinkComponent` renders an element whose `click` event triggers a + * transition of the application's instance of `Ember.Router` to + * a supplied route by name. + */ +export default class LinkComponent extends Component { + /** + * Used to determine when this `LinkComponent` is active. + */ + currentWhen: any; + /** + * Sets the `title` attribute of the `LinkComponent`'s HTML element. + */ + title: string | null; + /** + * Sets the `rel` attribute of the `LinkComponent`'s HTML element. + */ + rel: string | null; + /** + * Sets the `tabindex` attribute of the `LinkComponent`'s HTML element. + */ + tabindex: string | null; + /** + * Sets the `target` attribute of the `LinkComponent`'s HTML element. + */ + target: string | null; + /** + * The CSS class to apply to `LinkComponent`'s element when its `active` + * property is `true`. + */ + activeClass: string; + /** + * Determines whether the `LinkComponent` will trigger routing via + * the `replaceWith` routing strategy. + */ + replace: boolean; +} diff --git a/types/ember__routing/location.d.ts b/types/ember__routing/location.d.ts index 507c920f46..2adbfc5662 100644 --- a/types/ember__routing/location.d.ts +++ b/types/ember__routing/location.d.ts @@ -1,4 +1,13 @@ -import Ember from 'ember'; - -export const Location: typeof Ember.Location; +/** + * Ember.Location returns an instance of the correct implementation of + * the `location` API. + */ +declare const Location: { + /** + * This is deprecated in favor of using the container to lookup the location + * implementation as desired. + * @deprecated Use the container to lookup the location implementation that you need. + */ + create(options?: {}): any; +}; export default Location; diff --git a/types/ember__routing/none-location.d.ts b/types/ember__routing/none-location.d.ts index 3c9d41d8ce..22934d7cec 100644 --- a/types/ember__routing/none-location.d.ts +++ b/types/ember__routing/none-location.d.ts @@ -1,3 +1,9 @@ -import Ember from 'ember'; +import EmberObject from "@ember/object"; -export default class NoneLocation extends Ember.NoneLocation { } +/** + * Ember.NoneLocation does not interact with the browser. It is useful for + * testing, or when you need to manage state with your Router, but temporarily + * don't want it to muck with the URL (for example when you embed your + * application in a larger page). + */ +export default class NoneLocation extends EmberObject {} diff --git a/types/ember__routing/route.d.ts b/types/ember__routing/route.d.ts index 67209d2b66..118bd1f1b5 100644 --- a/types/ember__routing/route.d.ts +++ b/types/ember__routing/route.d.ts @@ -1,3 +1,286 @@ -import Ember from 'ember'; +import EmberObject from "@ember/object"; +import ActionHandler from "@ember/object/-private/action-handler"; +import Transition from "@ember/routing/-private/transition"; +import Evented from "@ember/object/evented"; +import { RenderOptions, RouteQueryParam } from "@ember/routing/types"; +import Controller, { Registry as ControllerRegistry } from '@ember/controller'; -export default class Route extends Ember.Route { } +/** + * The `Ember.Route` class is used to define individual routes. Refer to + * the [routing guide](http://emberjs.com/guides/routing/) for documentation. + */ +export default class Route extends EmberObject.extend(ActionHandler, Evented) { + // methods + /** + * This hook is called after this route's model has resolved. + * It follows identical async/promise semantics to `beforeModel` + * but is provided the route's resolved model in addition to + * the `transition`, and is therefore suited to performing + * logic that can only take place after the model has already + * resolved. + */ + afterModel(resolvedModel: any, transition: Transition): any; + + /** + * This hook is the first of the route entry validation hooks + * called when an attempt is made to transition into a route + * or one of its children. It is called before `model` and + * `afterModel`, and is appropriate for cases when: + * 1) A decision can be made to redirect elsewhere without + * needing to resolve the model first. + * 2) Any async operations need to occur first before the + * model is attempted to be resolved. + * This hook is provided the current `transition` attempt + * as a parameter, which can be used to `.abort()` the transition, + * save it for a later `.retry()`, or retrieve values set + * on it from a previous hook. You can also just call + * `this.transitionTo` to another route to implicitly + * abort the `transition`. + * You can return a promise from this hook to pause the + * transition until the promise resolves (or rejects). This could + * be useful, for instance, for retrieving async code from + * the server that is required to enter a route. + */ + beforeModel(transition: Transition): any; + + /** + * Returns the controller for a particular route or name. + * The controller instance must already have been created, either through entering the + * associated route or using `generateController`. + */ + controllerFor(name: K): ControllerRegistry[K]; + + /** + * Disconnects a view that has been rendered into an outlet. + */ + disconnectOutlet(options: string | { outlet?: string; parentView?: string }): void; + + /** + * A hook you can implement to convert the URL into the model for + * this route. + */ + model(params: {}, transition: Transition): any; + + /** + * Returns the model of a parent (or any ancestor) route + * in a route hierarchy. During a transition, all routes + * must resolve a model object, and if a route + * needs access to a parent route's model in order to + * resolve a model (or just reuse the model from a parent), + * it can call `this.modelFor(theNameOfParentRoute)` to + * retrieve it. + */ + modelFor(name: string): {}; + + /** + * Retrieves parameters, for current route using the state.params + * variable and getQueryParamsFor, using the supplied routeName. + */ + paramsFor(name: string): {}; + + /** + * Refresh the model on this route and any child routes, firing the + * `beforeModel`, `model`, and `afterModel` hooks in a similar fashion + * to how routes are entered when transitioning in from other route. + * The current route params (e.g. `article_id`) will be passed in + * to the respective model hooks, and if a different model is returned, + * `setupController` and associated route hooks will re-fire as well. + * An example usage of this method is re-querying the server for the + * latest information using the same parameters as when the route + * was first entered. + * Note that this will cause `model` hooks to fire even on routes + * that were provided a model object when the route was initially + * entered. + */ + redirect(): Transition; + + /** + * Refresh the model on this route and any child routes, firing the + * `beforeModel`, `model`, and `afterModel` hooks in a similar fashion + * to how routes are entered when transitioning in from other route. + * The current route params (e.g. `article_id`) will be passed in + * to the respective model hooks, and if a different model is returned, + * `setupController` and associated route hooks will re-fire as well. + * An example usage of this method is re-querying the server for the + * latest information using the same parameters as when the route + * was first entered. + * Note that this will cause `model` hooks to fire even on routes + * that were provided a model object when the route was initially + * entered. + */ + refresh(): Transition; + + /** + * `render` is used to render a template into a region of another template + * (indicated by an `{{outlet}}`). `render` is used both during the entry + * phase of routing (via the `renderTemplate` hook) and later in response to + * user interaction. + */ + render(name: string, options?: RenderOptions): void; + + /** + * A hook you can use to render the template for the current route. + * This method is called with the controller for the current route and the + * model supplied by the `model` hook. By default, it renders the route's + * template, configured with the controller for the route. + * This method can be overridden to set up and render additional or + * alternative templates. + */ + renderTemplate(controller: Controller, model: {}): void; + + /** + * Transition into another route while replacing the current URL, if possible. + * This will replace the current history entry instead of adding a new one. + * Beside that, it is identical to `transitionTo` in all other respects. See + * 'transitionTo' for additional information regarding multiple models. + */ + replaceWith(name: string, ...args: any[]): Transition; + + /** + * A hook you can use to reset controller values either when the model + * changes or the route is exiting. + */ + resetController(controller: Controller, isExiting: boolean, transition: any): void; + + /** + * Sends an action to the router, which will delegate it to the currently active + * route hierarchy per the bubbling rules explained under actions. + */ + send(name: string, ...args: any[]): void; + + /** + * A hook you can implement to convert the route's model into parameters + * for the URL. + * + * The default `serialize` method will insert the model's `id` into the + * route's dynamic segment (in this case, `:post_id`) if the segment contains '_id'. + * If the route has multiple dynamic segments or does not contain '_id', `serialize` + * will return `Ember.getProperties(model, params)` + * This method is called when `transitionTo` is called with a context + * in order to populate the URL. + */ + serialize(model: {}, params: string[]): string | object; + + /** + * A hook you can use to setup the controller for the current route. + * This method is called with the controller for the current route and the + * model supplied by the `model` hook. + * By default, the `setupController` hook sets the `model` property of + * the controller to the `model`. + * If you implement the `setupController` hook in your Route, it will + * prevent this default behavior. If you want to preserve that behavior + * when implementing your `setupController` function, make sure to call + * `_super` + */ + setupController(controller: Controller, model: {}): void; + + /** + * Transition the application into another route. The route may + * be either a single route or route path + */ + transitionTo(name: string, ...object: any[]): Transition; + + /** + * The name of the view to use by default when rendering this routes template. + * When rendering a template, the route will, by default, determine the + * template and view to use from the name of the route itself. If you need to + * define a specific view, set this property. + * This is useful when multiple routes would benefit from using the same view + * because it doesn't require a custom `renderTemplate` method. + */ + transitionTo(name: string, ...object: any[]): Transition; + + // https://emberjs.com/api/ember/3.2/classes/Route/methods/intermediateTransitionTo?anchor=intermediateTransitionTo + /** + * Perform a synchronous transition into another route without attempting to resolve promises, + * update the URL, or abort any currently active asynchronous transitions + * (i.e. regular transitions caused by transitionTo or URL changes). + * + * @param name the name of the route or a URL + * @param object the model(s) or identifier(s) to be used while + * transitioning to the route. + * @returns the Transition object associated with this attempted transition + */ + intermediateTransitionTo(name: string, ...object: any[]): Transition; + + // properties + /** + * The controller associated with this route. + */ + controller: Controller; + + /** + * The name of the controller to associate with this route. + * By default, Ember will lookup a route's controller that matches the name + * of the route (i.e. `App.PostController` for `App.PostRoute`). However, + * if you would like to define a specific controller to use, you can do so + * using this property. + * This is useful in many ways, as the controller specified will be: + * * p assed to the `setupController` method. + * * used as the controller for the view being rendered by the route. + * * returned from a call to `controllerFor` for the route. + */ + controllerName: string; + + /** + * Configuration hash for this route's queryParams. + */ + queryParams: { [key: string]: RouteQueryParam }; + + /** + * The name of the route, dot-delimited + */ + routeName: string; + + /** + * The name of the template to use by default when rendering this routes + * template. + * This is similar with `viewName`, but is useful when you just want a custom + * template without a view. + */ + templateName: string; + + // events + /** + * This hook is executed when the router enters the route. It is not executed + * when the model for the route changes. + */ + activate(): void; + + /** + * This hook is executed when the router completely exits this route. It is + * not executed when the model for the route changes. + */ + deactivate(): void; + + /** + * The didTransition action is fired after a transition has successfully been + * completed. This occurs after the normal model hooks (beforeModel, model, + * afterModel, setupController) have resolved. The didTransition action has + * no arguments, however, it can be useful for tracking page views or resetting + * state on the controller. + */ + didTransition(): void; + + /** + * When attempting to transition into a route, any of the hooks may return a promise + * that rejects, at which point an error action will be fired on the partially-entered + * routes, allowing for per-route error handling logic, or shared error handling logic + * defined on a parent route. + */ + error(error: any, transition: Transition): void; + + /** + * The loading action is fired on the route when a route's model hook returns a + * promise that is not already resolved. The current Transition object is the first + * parameter and the route that triggered the loading event is the second parameter. + */ + loading(transition: Transition, route: Route): void; + + /** + * The willTransition action is fired at the beginning of any attempted transition + * with a Transition object as the sole argument. This action can be used for aborting, + * redirecting, or decorating the transition from the currently active routes. + */ + willTransition(transition: Transition): void; +} diff --git a/types/ember__routing/router-service.d.ts b/types/ember__routing/router-service.d.ts index d243abc316..decc36af34 100644 --- a/types/ember__routing/router-service.d.ts +++ b/types/ember__routing/router-service.d.ts @@ -1,3 +1,215 @@ -import { RouterService } from 'ember'; +import Transition from '@ember/routing/-private/transition'; +import Service from '@ember/service'; -export default class extends RouterService { } +// tslint:disable-next-line:strict-export-declare-modifiers +type RouteModel = object | string | number; + +// https://emberjs.com/api/ember/2.18/classes/RouterService +/** + * The Router service is the public API that provides component/view layer access to the router. + */ +export default class RouterService extends Service { + // + /** + * Name of the current route. + * This property represent the logical name of the route, + * which is comma separated. + * For the following router: + * ```app/router.js + * Router.map(function() { + * this.route('about'); + * this.route('blog', function () { + * this.route('post', { path: ':post_id' }); + * }); + * }); + * ``` + * It will return: + * * `index` when you visit `/` + * * `about` when you visit `/about` + * * `blog.index` when you visit `/blog` + * * `blog.post` when you visit `/blog/some-post-id` + */ + readonly currentRouteName: string; + // + /** + * Current URL for the application. + * This property represent the URL path for this route. + * For the following router: + * ```app/router.js + * Router.map(function() { + * this.route('about'); + * this.route('blog', function () { + * this.route('post', { path: ':post_id' }); + * }); + * }); + * ``` + * It will return: + * * `/` when you visit `/` + * * `/about` when you visit `/about` + * * `/blog` when you visit `/blog` + * * `/blog/some-post-id` when you visit `/blog/some-post-id` + */ + readonly currentURL: string; + // + /** + * Determines whether a route is active. + * + * @param routeName the name of the route + * @param models the model(s) or identifier(s) to be used while + * transitioning to the route + * @param options optional hash with a queryParams property containing a + * mapping of query parameters + */ + isActive(routeName: string, options?: { queryParams: object }): boolean; + isActive( + routeName: string, + models: RouteModel, + options?: { queryParams: object } + ): boolean; + isActive( + routeName: string, + modelsA: RouteModel, + modelsB: RouteModel, + options?: { queryParams: object } + ): boolean; + isActive( + routeName: string, + modelsA: RouteModel, + modelsB: RouteModel, + modelsC: RouteModel, + options?: { queryParams: object } + ): boolean; + isActive( + routeName: string, + modelsA: RouteModel, + modelsB: RouteModel, + modelsC: RouteModel, + modelsD: RouteModel, + options?: { queryParams: object } + ): boolean; + + // https://emberjs.com/api/ember/2.18/classes/RouterService/methods/isActive?anchor=replaceWith + /** + * Transition into another route while replacing the current URL, if + * possible. The route may be either a single route or route path. + * + * @param routeNameOrUrl the name of the route or a URL + * @param models the model(s) or identifier(s) to be used while + * transitioning to the route. + * @param options optional hash with a queryParams property + * containing a mapping of query parameters + * @returns the Transition object associated with this attempted transition + */ + replaceWith( + routeNameOrUrl: string, + options?: { queryParams: object } + ): Transition; + replaceWith( + routeNameOrUrl: string, + models: RouteModel, + options?: { queryParams: object } + ): Transition; + replaceWith( + routeNameOrUrl: string, + modelsA: RouteModel, + modelsB: RouteModel, + options?: { queryParams: object } + ): Transition; + replaceWith( + routeNameOrUrl: string, + modelsA: RouteModel, + modelsB: RouteModel, + modelsC: RouteModel, + options?: { queryParams: object } + ): Transition; + replaceWith( + routeNameOrUrl: string, + modelsA: RouteModel, + modelsB: RouteModel, + modelsC: RouteModel, + modelsD: RouteModel, + options?: { queryParams: object } + ): Transition; + + // https://emberjs.com/api/ember/2.18/classes/RouterService/methods/isActive?anchor=transitionTo + /** + * Transition the application into another route. The route may be + * either a single route or route path + * + * @param routeNameOrUrl the name of the route or a URL + * @param models the model(s) or identifier(s) to be used while + * transitioning to the route. + * @param options optional hash with a queryParams property + * containing a mapping of query parameters + * @returns the Transition object associated with this attempted transition + */ + transitionTo( + routeNameOrUrl: string, + options?: { queryParam: object } + ): Transition; + transitionTo( + routeNameOrUrl: string, + models: RouteModel, + options?: { queryParams: object } + ): Transition; + transitionTo( + routeNameOrUrl: string, + modelsA: RouteModel, + modelsB: RouteModel, + options?: { queryParams: object } + ): Transition; + transitionTo( + routeNameOrUrl: string, + modelsA: RouteModel, + modelsB: RouteModel, + modelsC: RouteModel, + options?: { queryParams: object } + ): Transition; + transitionTo( + routeNameOrUrl: string, + modelsA: RouteModel, + modelsB: RouteModel, + modelsC: RouteModel, + modelsD: RouteModel, + options?: { queryParams: object } + ): Transition; + + // https://emberjs.com/api/ember/2.18/classes/RouterService/methods/isActive?anchor=urlFor + /** + * Generate a URL based on the supplied route name. + * + * @param routeName the name of the route or a URL + * @param models the model(s) or identifier(s) to be used while + * transitioning to the route. + * @param options optional hash with a queryParams property containing + * a mapping of query parameters + * @returns the string representing the generated URL + */ + urlFor(routeName: string, options?: { queryParams: object }): string; + urlFor( + routeName: string, + models: RouteModel, + options?: { queryParams: object } + ): string; + urlFor( + routeName: string, + modelsA: RouteModel, + modelsB: RouteModel, + options?: { queryParams: object } + ): string; + urlFor( + routeName: string, + modelsA: RouteModel, + modelsB: RouteModel, + modelsC: RouteModel, + options?: { queryParams: object } + ): string; + urlFor( + routeName: string, + modelsA: RouteModel, + modelsB: RouteModel, + modelsC: RouteModel, + modelsD: RouteModel, + options?: { queryParams: object } + ): string; +} diff --git a/types/ember__routing/router.d.ts b/types/ember__routing/router.d.ts index d29fe2a21d..6e6012f241 100644 --- a/types/ember__routing/router.d.ts +++ b/types/ember__routing/router.d.ts @@ -1,3 +1,51 @@ -import Ember from 'ember'; +import EmberObject from "@ember/object"; +import Evented from "@ember/object/evented"; +import RouterDSL from "@ember/routing/-private/router-dsl"; +import Transition from "@ember/routing/-private/transition"; +import RouterService from "@ember/routing/router-service"; -export default class EmberRouter extends Ember.Router { } +/** + * The `Ember.Router` class manages the application state and URLs. Refer to + * the [routing guide](http://emberjs.com/guides/routing/) for documentation. + */ +export default class Router extends EmberObject.extend(Evented) { + /** + * The `Router.map` function allows you to define mappings from URLs to routes + * in your application. These mappings are defined within the + * supplied callback function using `this.route`. + */ + static map(callback: (this: RouterDSL) => void): void; + /** + * The `location` property determines the type of URL's that your + * application will use. + */ + location: string; + /** + * Represents the URL of the root of the application, often '/'. This prefix is + * assumed on all routes defined on this router. + */ + rootURL: string; + /** + * Handles updating the paths and notifying any listeners of the URL + * change. + */ + didTransition(): any; + /** + * Handles notifying any listeners of an impending URL + * change. + */ + willTransition(): any; + /** + * Transition the application into another route. The route may + * be either a single route or route path: + */ + transitionTo(name: string, options?: {}): Transition; + transitionTo(name: string, ...models: any[]): Transition; + transitionTo(name: string, options: {}): Transition; +} + +declare module '@ember/service' { + interface Registry { + 'router': RouterService; + } +} diff --git a/types/ember__routing/test/route.ts b/types/ember__routing/test/route.ts index df96f585bf..7e2279d8c4 100755 --- a/types/ember__routing/test/route.ts +++ b/types/ember__routing/test/route.ts @@ -1,21 +1,21 @@ import Route from '@ember/routing/route'; import Array from '@ember/array'; -import Ember from 'ember'; // currently needed for Transition import EmberObject from '@ember/object'; import Controller from '@ember/controller'; +import Transition from '@ember/routing/-private/transition'; class Post extends EmberObject {} interface Posts extends Array {} Route.extend({ - beforeModel(transition: Ember.Transition) { + beforeModel(transition: Transition) { this.transitionTo('someOtherRoute'); }, }); Route.extend({ - afterModel(posts: Posts, transition: Ember.Transition) { + afterModel(posts: Posts, transition: Transition) { if (posts.length === 1) { this.transitionTo('post.show', posts.firstObject); } @@ -39,7 +39,7 @@ Route.extend({ }, }); -Ember.Route.extend({ +Route.extend({ model() { return this.modelFor('post'); }, @@ -61,7 +61,7 @@ Route.extend({ }); Route.extend({ - renderTemplate(controller: Ember.Controller, model: {}) { + renderTemplate(controller: Controller, model: {}) { this.render('posts', { view: 'someView', // the template to render, referenced by name into: 'application', // the template to render into, referenced by name @@ -73,7 +73,7 @@ Route.extend({ }); Route.extend({ - resetController(controller: Ember.Controller, isExiting: boolean, transition: boolean) { + resetController(controller: Controller, isExiting: boolean, transition: boolean) { if (isExiting) { // controller.set('page', 1); } diff --git a/types/ember__routing/test/router.ts b/types/ember__routing/test/router.ts index 760e9ed5bc..be1c16d821 100755 --- a/types/ember__routing/test/router.ts +++ b/types/ember__routing/test/router.ts @@ -1,7 +1,9 @@ -import Ember from 'ember'; import { assertType } from './lib/assert'; +import Router from '@ember/routing/router'; +import Service, { inject as service } from '@ember/service'; +import EmberObject, { get } from '@ember/object'; -const AppRouter = Ember.Router.extend({ +const AppRouter = Router.extend({ }); AppRouter.map(function() { @@ -24,31 +26,31 @@ AppRouter.map(function() { this.mount('my-engine', { as: 'some-other-engine', path: '/some-other-engine'}); }); -const RouterServiceConsumer = Ember.Service.extend({ - router: Ember.inject.service('router'), +const RouterServiceConsumer = Service.extend({ + router: service('router'), currentRouteName() { - const x: string = Ember.get(this, 'router').currentRouteName; + const x: string = get(this, 'router').currentRouteName; }, currentURL() { - const x: string = Ember.get(this, 'router').currentURL; + const x: string = get(this, 'router').currentURL; }, transitionWithoutModel() { - Ember.get(this, 'router') + get(this, 'router') .transitionTo('some-route'); }, transitionWithModel() { - const model = Ember.Object.create(); - Ember.get(this, 'router') + const model = EmberObject.create(); + get(this, 'router') .transitionTo('some.other.route', model); }, transitionWithMultiModel() { - const model = Ember.Object.create(); - Ember.get(this, 'router') + const model = EmberObject.create(); + get(this, 'router') .transitionTo('some.other.route', model, model); }, transitionWithModelAndOptions() { - const model = Ember.Object.create(); - Ember.get(this, 'router') + const model = EmberObject.create(); + get(this, 'router') .transitionTo('index', model, { queryParams: { search: 'ember' }}); } }); diff --git a/types/ember__routing/tsconfig.json b/types/ember__routing/tsconfig.json index cdb6a2a2fb..a3f936580a 100644 --- a/types/ember__routing/tsconfig.json +++ b/types/ember__routing/tsconfig.json @@ -15,10 +15,16 @@ "../" ], "paths": { + "@ember/service": ["ember__service"], "@ember/object": ["ember__object"], "@ember/object/*": ["ember__object/*"], "@ember/array": ["ember__array"], "@ember/array/*": ["ember__array/*"], + "@ember/service": ["ember__service"], + "@ember/service/*": ["ember__service/*"], + "@ember/component": ["ember__component"], + "@ember/component/*": ["ember__component/*"], + "@ember/controller": ["ember__controller"], "@ember/routing": ["ember__routing"], "@ember/routing/*": ["ember__routing/*"] }, @@ -37,6 +43,9 @@ "route.d.ts", "router-service.d.ts", "router.d.ts", + "types.d.ts", + "-private/router-dsl.d.ts", + "-private/transition.d.ts", "test/lib/assert.ts", "test/route.ts", "test/router.ts" diff --git a/types/ember__routing/types.d.ts b/types/ember__routing/types.d.ts new file mode 100644 index 0000000000..b60a4dc0c6 --- /dev/null +++ b/types/ember__routing/types.d.ts @@ -0,0 +1,13 @@ +export interface RenderOptions { + into?: string; + controller?: string; + model?: any; + outlet?: string; + view?: string; +} + +export interface RouteQueryParam { + refreshModel?: boolean; + replace?: boolean; + as?: string; +} diff --git a/types/ember__runloop/-private/types.d.ts b/types/ember__runloop/-private/types.d.ts new file mode 100644 index 0000000000..7d3bcfc61b --- /dev/null +++ b/types/ember__runloop/-private/types.d.ts @@ -0,0 +1,8 @@ +export type RunMethod = ((this: Target, ...args: any[]) => Ret) | keyof Target; +export type EmberRunQueues = + | 'sync' + | 'actions' + | 'routerTransitions' + | 'render' + | 'afterRender' + | 'destroy'; diff --git a/types/ember__runloop/ember__runloop-tests.ts b/types/ember__runloop/ember__runloop-tests.ts index 132d687bbd..cf9cfd7db1 100644 --- a/types/ember__runloop/ember__runloop-tests.ts +++ b/types/ember__runloop/ember__runloop-tests.ts @@ -1,9 +1,8 @@ -import Ember from 'ember'; -import RSVP from 'rsvp'; import { run } from '@ember/runloop'; +import EmberObject from '@ember/object'; -Ember.run.queues; // $ExpectType EmberRunQueues[] -const queues: string[] = Ember.run.queues; +run.queues; // $ExpectType EmberRunQueues[] +const queues: string[] = run.queues; function testRun() { run(() => { // $ExpectType number @@ -11,8 +10,8 @@ function testRun() { return 123; }); - function destroyApp(application: Ember.Application) { - Ember.run(application, 'destroy'); + function destroyApp(application: EmberObject) { + run(application, 'destroy'); run(application, function() { this.destroy(); }); @@ -20,9 +19,9 @@ function testRun() { } function testBind() { - Ember.Component.extend({ + EmberObject.extend({ init() { - const bound = Ember.run.bind(this, this.setupEditor); + const bound = run.bind(this, this.setupEditor); bound(); }, @@ -91,14 +90,14 @@ function testDebounce() { run.debounce(myContext, runIt, 150); run.debounce(myContext, runIt, 150, true); - Ember.Component.extend({ + EmberObject.extend({ searchValue: 'test', fetchResults(value: string) {}, actions: { handleTyping() { // the fetchResults function is passed into the component from its parent - Ember.run.debounce(this, this.get('fetchResults'), this.get('searchValue'), 250); + run.debounce(this, this.get('fetchResults'), this.get('searchValue'), 250); } } }); @@ -123,11 +122,9 @@ function testJoin() { }); }); - new RSVP.Promise((resolve) => { - Ember.run.later(() => { - resolve({ msg: 'Hold Your Horses' }); - }, 3000); - }); + run.later(() => { + console.log({ msg: 'Hold Your Horses' }); + }, 3000); } function testLater() { @@ -146,9 +143,9 @@ function testNext() { } function testOnce() { - Ember.Component.extend({ + EmberObject.extend({ init() { - Ember.run.once(this, 'processFullName'); + run.once(this, 'processFullName'); }, processFullName() { @@ -157,7 +154,7 @@ function testOnce() { } function testSchedule() { - Ember.Component.extend({ + EmberObject.extend({ init() { run.schedule('sync', this, () => { // this will be executed in the first RunLoop queue, when bindings are synced @@ -171,7 +168,7 @@ function testSchedule() { } }); - Ember.run.schedule('actions', () => { + run.schedule('actions', () => { // Do more things }); } diff --git a/types/ember__runloop/index.d.ts b/types/ember__runloop/index.d.ts index acc8c3ad8a..f1deeb9d17 100644 --- a/types/ember__runloop/index.d.ts +++ b/types/ember__runloop/index.d.ts @@ -4,18 +4,326 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.8 -import Ember from 'ember'; +import { RunMethod, EmberRunQueues } from "@ember/runloop/-private/types"; +import { EmberRunTimer } from "@ember/runloop/types"; -export const begin: typeof Ember.run.begin; -export const bind: typeof Ember.run.bind; -export const cancel: typeof Ember.run.cancel; -export const debounce: typeof Ember.run.debounce; -export const end: typeof Ember.run.end; -export const join: typeof Ember.run.join; -export const later: typeof Ember.run.later; -export const next: typeof Ember.run.next; -export const once: typeof Ember.run.once; -export const run: typeof Ember.run; -export const schedule: typeof Ember.run.schedule; -export const scheduleOnce: typeof Ember.run.scheduleOnce; -export const throttle: typeof Ember.run.throttle; +// tslint:disable-next-line:strict-export-declare-modifiers +export const run: { + /** + * Runs the passed target and method inside of a RunLoop, ensuring any + * deferred actions including bindings and views updates are flushed at the + * end. + */ + (method: (...args: any[]) => Ret): Ret; + (target: Target, method: RunMethod): Ret; + /** + * If no run-loop is present, it creates a new one. If a run loop is + * present it will queue itself to run on the existing run-loops action + * queue. + */ + join(method: (...args: any[]) => Ret, ...args: any[]): Ret | undefined; + join( + target: Target, + method: RunMethod, + ...args: any[] + ): Ret | undefined; + /** + * Allows you to specify which context to call the specified function in while + * adding the execution of that function to the Ember run loop. This ability + * makes this method a great way to asynchronously integrate third-party libraries + * into your Ember application. + */ + bind( + target: Target, + method: RunMethod, + ...args: any[] + ): (...args: any[]) => Ret; + /** + * Begins a new RunLoop. Any deferred actions invoked after the begin will + * be buffered until you invoke a matching call to `run.end()`. This is + * a lower-level way to use a RunLoop instead of using `run()`. + */ + begin(): void; + /** + * Ends a RunLoop. This must be called sometime after you call + * `run.begin()` to flush any deferred actions. This is a lower-level way + * to use a RunLoop instead of using `run()`. + */ + end(): void; + /** + * Adds the passed target/method and any optional arguments to the named + * queue to be executed at the end of the RunLoop. If you have not already + * started a RunLoop when calling this method one will be started for you + * automatically. + */ + schedule( + queue: EmberRunQueues, + target: Target, + method: RunMethod, + ...args: any[] + ): EmberRunTimer; + schedule( + queue: EmberRunQueues, + method: (args: any[]) => any, + ...args: any[] + ): EmberRunTimer; + /** + * Invokes the passed target/method and optional arguments after a specified + * period of time. The last parameter of this method must always be a number + * of milliseconds. + */ + later(method: (...args: any[]) => any, wait: number): EmberRunTimer; + later( + target: Target, + method: RunMethod, + wait: number + ): EmberRunTimer; + later( + target: Target, + method: RunMethod, + arg0: any, + wait: number + ): EmberRunTimer; + later( + target: Target, + method: RunMethod, + arg0: any, + arg1: any, + wait: number + ): EmberRunTimer; + later( + target: Target, + method: RunMethod, + arg0: any, + arg1: any, + arg2: any, + wait: number + ): EmberRunTimer; + later( + target: Target, + method: RunMethod, + arg0: any, + arg1: any, + arg2: any, + arg3: any, + wait: number + ): EmberRunTimer; + later( + target: Target, + method: RunMethod, + arg0: any, + arg1: any, + arg2: any, + arg3: any, + arg4: any, + wait: number + ): EmberRunTimer; + later( + target: Target, + method: RunMethod, + arg0: any, + arg1: any, + arg2: any, + arg3: any, + arg4: any, + arg5: any, + wait: number + ): EmberRunTimer; + /** + * Schedule a function to run one time during the current RunLoop. This is equivalent + * to calling `scheduleOnce` with the "actions" queue. + */ + once( + target: Target, + method: RunMethod, + ...args: any[] + ): EmberRunTimer; + /** + * Schedules a function to run one time in a given queue of the current RunLoop. + * Calling this method with the same queue/target/method combination will have + * no effect (past the initial call). + */ + scheduleOnce( + queue: EmberRunQueues, + target: Target, + method: RunMethod, + ...args: any[] + ): EmberRunTimer; + /** + * Schedules an item to run from within a separate run loop, after + * control has been returned to the system. This is equivalent to calling + * `run.later` with a wait time of 1ms. + */ + next( + target: Target, + method: RunMethod, + ...args: any[] + ): EmberRunTimer; + /** + * Cancels a scheduled item. Must be a value returned by `run.later()`, + * `run.once()`, `run.scheduleOnce()`, `run.next()`, `run.debounce()`, or + * `run.throttle()`. + */ + cancel(timer: EmberRunTimer): boolean; + /** + * Delay calling the target method until the debounce period has elapsed + * with no additional debounce calls. If `debounce` is called again before + * the specified time has elapsed, the timer is reset and the entire period + * must pass again before the target method is called. + */ + debounce( + method: (...args: any[]) => any, + wait: number, + immediate?: boolean + ): EmberRunTimer; + debounce( + target: Target, + method: RunMethod, + wait: number, + immediate?: boolean + ): EmberRunTimer; + debounce( + target: Target, + method: RunMethod, + arg0: any, + wait: number, + immediate?: boolean + ): EmberRunTimer; + debounce( + target: Target, + method: RunMethod, + arg0: any, + arg1: any, + wait: number, + immediate?: boolean + ): EmberRunTimer; + debounce( + target: Target, + method: RunMethod, + arg0: any, + arg1: any, + arg2: any, + wait: number, + immediate?: boolean + ): EmberRunTimer; + debounce( + target: Target, + method: RunMethod, + arg0: any, + arg1: any, + arg2: any, + arg3: any, + wait: number, + immediate?: boolean + ): EmberRunTimer; + debounce( + target: Target, + method: RunMethod, + arg0: any, + arg1: any, + arg2: any, + arg3: any, + arg4: any, + wait: number, + immediate?: boolean + ): EmberRunTimer; + debounce( + target: Target, + method: RunMethod, + arg0: any, + arg1: any, + arg2: any, + arg3: any, + arg4: any, + arg5: any, + wait: number, + immediate?: boolean + ): EmberRunTimer; + /** + * Ensure that the target method is never called more frequently than + * the specified spacing period. The target method is called immediately. + */ + throttle( + method: (...args: any[]) => any, + spacing: number, + immediate?: boolean + ): EmberRunTimer; + throttle( + target: Target, + method: RunMethod, + spacing: number, + immediate?: boolean + ): EmberRunTimer; + throttle( + target: Target, + method: RunMethod, + arg0: any, + spacing: number, + immediate?: boolean + ): EmberRunTimer; + throttle( + target: Target, + method: RunMethod, + arg0: any, + arg1: any, + spacing: number, + immediate?: boolean + ): EmberRunTimer; + throttle( + target: Target, + method: RunMethod, + arg0: any, + arg1: any, + arg2: any, + spacing: number, + immediate?: boolean + ): EmberRunTimer; + throttle( + target: Target, + method: RunMethod, + arg0: any, + arg1: any, + arg2: any, + arg3: any, + spacing: number, + immediate?: boolean + ): EmberRunTimer; + throttle( + target: Target, + method: RunMethod, + arg0: any, + arg1: any, + arg2: any, + arg3: any, + arg4: any, + spacing: number, + immediate?: boolean + ): EmberRunTimer; + throttle( + target: Target, + method: RunMethod, + arg0: any, + arg1: any, + arg2: any, + arg3: any, + arg4: any, + arg5: any, + spacing: number, + immediate?: boolean + ): EmberRunTimer; + + queues: EmberRunQueues[]; +}; + +export const begin: typeof run.begin; +export const bind: typeof run.bind; +export const cancel: typeof run.cancel; +export const debounce: typeof run.debounce; +export const end: typeof run.end; +export const join: typeof run.join; +export const later: typeof run.later; +export const next: typeof run.next; +export const once: typeof run.once; +export const schedule: typeof run.schedule; +export const scheduleOnce: typeof run.scheduleOnce; +export const throttle: typeof run.throttle; diff --git a/types/ember__runloop/tsconfig.json b/types/ember__runloop/tsconfig.json index 3ece4d5f92..d06cb5216c 100644 --- a/types/ember__runloop/tsconfig.json +++ b/types/ember__runloop/tsconfig.json @@ -17,9 +17,8 @@ "paths": { "@ember/object": ["ember__object"], "@ember/object/*": ["ember__object/*"], - "@ember/engine": ["ember__engine"], - "@ember/engine/*": ["ember__engine/*"], - "@ember/runloop": ["ember__runloop"] + "@ember/runloop": ["ember__runloop"], + "@ember/runloop/*": ["ember__runloop/*"] }, "types": [], "noEmit": true, @@ -27,6 +26,8 @@ }, "files": [ "index.d.ts", + "types.d.ts", + "-private/types.d.ts", "ember__runloop-tests.ts" ] } diff --git a/types/ember__runloop/types.d.ts b/types/ember__runloop/types.d.ts new file mode 100644 index 0000000000..2aeaa44726 --- /dev/null +++ b/types/ember__runloop/types.d.ts @@ -0,0 +1,3 @@ +export interface EmberRunTimer { + __ember_run_timer_brand__: boolean; +} diff --git a/types/ember__service/index.d.ts b/types/ember__service/index.d.ts index fa5d687441..4d89a87d01 100644 --- a/types/ember__service/index.d.ts +++ b/types/ember__service/index.d.ts @@ -4,10 +4,18 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.8 -import Ember from 'ember'; +import EmberObject from '@ember/object'; +import ComputedProperty from '@ember/object/computed'; -export default class Service extends Ember.Service { } -export const inject: typeof Ember.inject.service; +export default class Service extends EmberObject {} +/** + * Creates a property that lazily looks up a service in the container. There + * are no restrictions as to what objects a service can be injected into. + */ +export function inject(): ComputedProperty; +export function inject( + name: K +): ComputedProperty; // A type registry for Ember `Service`s. Meant to be declaration-merged so // string lookups resolve to the correct type. diff --git a/types/ember__test-helpers/index.d.ts b/types/ember__test-helpers/index.d.ts index bd7720e3b1..8a3d6f0ef9 100644 --- a/types/ember__test-helpers/index.d.ts +++ b/types/ember__test-helpers/index.d.ts @@ -7,6 +7,7 @@ // TypeScript Version: 2.8 /// +/// declare module '@ember/test-helpers' { // DOM Interaction Helpers diff --git a/types/ember__test-helpers/tsconfig.json b/types/ember__test-helpers/tsconfig.json index 31f47f69cb..18e1faee35 100644 --- a/types/ember__test-helpers/tsconfig.json +++ b/types/ember__test-helpers/tsconfig.json @@ -19,6 +19,9 @@ "paths": { "@ember/engine": ["ember__engine"], "@ember/engine/*": ["ember__engine/*"], + "@ember/error": ["ember__error"], + "@ember/application": ["ember__application"], + "@ember/application/*": ["ember__application/*"], "@ember/object": ["ember__object"], "@ember/object/*": ["ember__object/*"], "@ember/test-helpers": ["ember__test-helpers"] diff --git a/types/ember__test/adapter.d.ts b/types/ember__test/adapter.d.ts index 5f312cf381..0ecdf064a8 100644 --- a/types/ember__test/adapter.d.ts +++ b/types/ember__test/adapter.d.ts @@ -1,2 +1,20 @@ -import Ember from 'ember'; -export default class TestAdapter extends Ember.Test.Adapter { } +/** + * The primary purpose of this class is to create hooks that can be implemented + * by an adapter for various test frameworks. + */ +export default class Adapter { + /** + * This callback will be called whenever an async operation is about to start. + */ + asyncStart(): any; + /** + * This callback will be called whenever an async operation has completed. + */ + asyncEnd(): any; + /** + * Override this method with your testing framework's false assertion. + * This function is called whenever an exception occurs causing the testing + * promise to fail. + */ + exception(error: string): any; +} diff --git a/types/ember__test/index.d.ts b/types/ember__test/index.d.ts index 94bc312566..b63f2d983e 100644 --- a/types/ember__test/index.d.ts +++ b/types/ember__test/index.d.ts @@ -4,9 +4,50 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.8 -import Ember from 'ember'; -export const registerAsyncHelper: typeof Ember.Test.registerAsyncHelper; -export const registerHelper: typeof Ember.Test.registerHelper; -export const registerWaiter: typeof Ember.Test.registerWaiter; -export const unregisterHelper: typeof Ember.Test.unregisterHelper; -export const unregisterWaiter: typeof Ember.Test.unregisterWaiter; +import Application from '@ember/application'; + +/** + * `registerHelper` is used to register a test helper that will be injected + * when `App.injectTestHelpers` is called. + */ +export function registerHelper( + name: string, + helperMethod: (app: Application, ...args: any[]) => any, + options?: object +): any; +/** + * `registerAsyncHelper` is used to register an async test helper that will be injected + * when `App.injectTestHelpers` is called. + */ +export function registerAsyncHelper( + name: string, + helperMethod: (app: Application, ...args: any[]) => any +): void; + +/** + * Remove a previously added helper method. + */ +export function unregisterHelper(name: string): void; + +/** + * This allows ember-testing to play nicely with other asynchronous + * events, such as an application that is waiting for a CSS3 + * transition or an IndexDB transaction. The waiter runs periodically + * after each async helper (i.e. `click`, `andThen`, `visit`, etc) has executed, + * until the returning result is truthy. After the waiters finish, the next async helper + * is executed and the process repeats. + */ +export function registerWaiter(callback: () => boolean): any; +export function registerWaiter( + context: Context, + callback: (this: Context) => boolean +): any; +/** + * `unregisterWaiter` is used to unregister a callback that was + * registered with `registerWaiter`. + */ +export function unregisterWaiter(callback: () => boolean): any; +export function unregisterWaiter( + context: Context, + callback: (this: Context) => boolean +): any; diff --git a/types/ember__test/tsconfig.json b/types/ember__test/tsconfig.json index 89f8c76b60..e5405575cc 100644 --- a/types/ember__test/tsconfig.json +++ b/types/ember__test/tsconfig.json @@ -15,6 +15,10 @@ "../" ], "paths": { + "@ember/engine": ["ember__engine"], + "@ember/engine/*": ["ember__engine/*"], + "@ember/application": ["ember__application"], + "@ember/application/*": ["ember__application/*"], "@ember/test": ["ember__test"], "@ember/test/*": ["ember__test/*"] }, diff --git a/types/expo/expo-tests.tsx b/types/expo/expo-tests.tsx index ac1c6e3452..1858faa549 100644 --- a/types/expo/expo-tests.tsx +++ b/types/expo/expo-tests.tsx @@ -40,7 +40,8 @@ import { Location, Updates, MediaLibrary, - Haptic + Haptic, + Constants } from 'expo'; const reverseGeocode: Promise = Location.reverseGeocodeAsync({ @@ -874,3 +875,22 @@ Haptic.notification(Haptic.NotificationType.Error); Haptic.selection(); // #endregion + +// #region Constants +async () => { + const appOwnerShip = Constants.appOwnership; + const expoVersion = Constants.expoVersion; + const installationId = Constants.installationId; + const deviceId = Constants.deviceId; + const deviceName = Constants.deviceName; + const deviceYearClass = Constants.deviceYearClass; + const isDevice = Constants.isDevice; + const platform = Constants.platform; + const sessionId = Constants.sessionId; + const statusBarHeight = Constants.statusBarHeight; + const systemFonts = Constants.systemFonts; + const manifest = Constants.manifest; + const linkingUri = Constants.linkingUri; + const userAgent: string = await Constants.getWebViewUserAgentAsync(); +}; +// #endregion diff --git a/types/expo/index.d.ts b/types/expo/index.d.ts index 1376dea57c..36afc712ab 100644 --- a/types/expo/index.d.ts +++ b/types/expo/index.d.ts @@ -877,6 +877,7 @@ export class Camera extends Component { export namespace Constants { const appOwnership: 'expo' | 'standalone' | 'guest'; const expoVersion: string; + const installationId: string; const deviceId: string; const deviceName: string; const deviceYearClass: number; @@ -991,6 +992,8 @@ export namespace Constants { } const manifest: Manifest; const linkingUri: string; + + function getWebViewUserAgentAsync(): Promise; } /** diff --git a/types/firefox-webext-browser/firefox-webext-browser-tests.ts b/types/firefox-webext-browser/firefox-webext-browser-tests.ts index a2d9f0bda0..26ae079172 100644 --- a/types/firefox-webext-browser/firefox-webext-browser-tests.ts +++ b/types/firefox-webext-browser/firefox-webext-browser-tests.ts @@ -6,8 +6,6 @@ browser.runtime.getManifest(); // $ExpectType WebExtensionManifest browser.test; // $ExpectError browser.manifest; // $ExpectError browser._manifest; // $ExpectError -browser._manifest.WebExtensionLangpackManifest; // $ExpectError -browser._manifest.NativeManifest; // $ExpectError // browser.runtime const port = browser.runtime.connect(); diff --git a/types/firefox-webext-browser/index.d.ts b/types/firefox-webext-browser/index.d.ts index 47035f4f87..d9e9e8df7c 100644 --- a/types/firefox-webext-browser/index.d.ts +++ b/types/firefox-webext-browser/index.d.ts @@ -1,9 +1,9 @@ -// Type definitions for WebExtension Development in FireFox 58.0 +// Type definitions for WebExtension Development in FireFox 63.0 // Project: https://developer.mozilla.org/en-US/Add-ons/WebExtensions -// Definitions by: Jacob Bom +// Definitions by: Jasmin Bom // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.9 -// Generated using script at github.com/bomjacob/definitelytyped-firefox-webext-browser +// Generated using script at github.com/jsmnbom/definitelytyped-firefox-webext-browser interface WebExtEventBase any, TCallback> { addListener: TAddListener; @@ -105,46 +105,14 @@ declare namespace browser._manifest { type Permission = string | OptionalPermission | _Permission; - /** Represents a protocol handler definition. */ - interface ProtocolHandler { - /** - * A user-readable title string for the protocol handler. This will be displayed to the user in interface - * objects as needed. - */ - name: string; - /** - * The protocol the site wishes to handle, specified as a string. For example, you can register to handle SMS - * text message links by registering to handle the "sms" scheme. - */ - protocol: string | _ProtocolHandlerProtocol; - /** - * The URL of the handler, as a string. This string should include "%s" as a placeholder which will be replaced - * with the escaped URL of the document to be handled. This URL might be a true URL, or it could be a phone - * number, email address, or so forth. - */ - uriTemplate: ExtensionURL | HttpURL; - } - /** Represents a WebExtension manifest.json file */ interface WebExtensionManifest { + experiment_apis?: experiments.ExperimentAPI; /** A list of protocol handler definitions. */ protocol_handlers?: ProtocolHandler[]; default_locale?: string; - manifest_version: number; minimum_chrome_version?: string; minimum_opera_version?: string; - applications?: { - gecko?: FirefoxSpecificProperties; - }; - browser_specific_settings?: { - gecko?: FirefoxSpecificProperties; - }; - name: string; - short_name?: string; - description?: string; - author?: string; - version: string; - homepage_url?: string; icons?: { [key: number]: string; }; @@ -171,7 +139,8 @@ declare namespace browser._manifest { name?: string; url?: string; }; - theme?: ThemeType; + hidden?: boolean; + theme_experiment?: ThemeExperiment; browser_action?: { default_title?: string; default_icon?: IconPath; @@ -231,12 +200,16 @@ declare namespace browser._manifest { default_icon?: IconPath; default_popup?: string; browser_style?: boolean; + show_matches?: MatchPattern[]; + hide_matches?: MatchPatternRestricted[]; }; sidebar_action?: { default_title?: string; default_icon?: IconPath; browser_style?: boolean; default_panel: string; + /** Whether or not the sidebar is opened at install. Default is `true`. */ + open_at_install?: boolean; }; chrome_url_overrides?: { newtab?: ExtensionURL; @@ -245,6 +218,110 @@ declare namespace browser._manifest { /** @deprecated Unsupported on Firefox at this time. */ history?: ExtensionURL; }; + manifest_version: number; + applications?: { + gecko?: FirefoxSpecificProperties; + }; + browser_specific_settings?: { + gecko?: FirefoxSpecificProperties; + }; + name: string; + short_name?: string; + description?: string; + author?: string; + version: string; + homepage_url?: string; + } + + /** Represents a protocol handler definition. */ + interface ProtocolHandler { + /** + * A user-readable title string for the protocol handler. This will be displayed to the user in interface + * objects as needed. + */ + name: string; + /** + * The protocol the site wishes to handle, specified as a string. For example, you can register to handle SMS + * text message links by registering to handle the "sms" scheme. + */ + protocol: string | _ProtocolHandlerProtocol; + /** + * The URL of the handler, as a string. This string should include "%s" as a placeholder which will be replaced + * with the escaped URL of the document to be handled. This URL might be a true URL, or it could be a phone + * number, email address, or so forth. + */ + uriTemplate: ExtensionURL | HttpURL; + } + + /** Common properties for all manifest.json files */ + interface ManifestBase { + manifest_version: number; + applications?: { + gecko?: FirefoxSpecificProperties; + }; + browser_specific_settings?: { + gecko?: FirefoxSpecificProperties; + }; + name: string; + short_name?: string; + description?: string; + author?: string; + version: string; + homepage_url?: string; + } + + /** Represents a WebExtension language pack manifest.json file */ + interface WebExtensionLangpackManifest { + homepage_url?: string; + langpack_id: string; + languages: { + [key: string]: { + chrome_resources: { + [key: string]: ExtensionURL | { + [key: string]: ExtensionURL; + }; + }; + version: string; + }; + }; + sources?: { + [key: string]: { + base_path: ExtensionURL; + paths?: string[]; + }; + }; + manifest_version: number; + applications?: { + gecko?: FirefoxSpecificProperties; + }; + browser_specific_settings?: { + gecko?: FirefoxSpecificProperties; + }; + name: string; + short_name?: string; + description?: string; + author?: string; + version: string; + } + + /** Represents a WebExtension dictionary manifest.json file */ + interface WebExtensionDictionaryManifest { + homepage_url?: string; + dictionaries: { + [key: string]: string; + }; + manifest_version: number; + applications?: { + gecko?: FirefoxSpecificProperties; + }; + browser_specific_settings?: { + gecko?: FirefoxSpecificProperties; + }; + name: string; + short_name?: string; + description?: string; + author?: string; + version: string; } interface ThemeIcons { @@ -275,7 +352,16 @@ declare namespace browser._manifest { strict_max_version?: string; } - type MatchPattern = string | _MatchPattern; + type MatchPattern = MatchPatternRestricted | MatchPatternUnestricted | _MatchPattern; + + /** Same as MatchPattern above, but excludes */ + type MatchPatternRestricted = string; + + /** + * Mostly unrestricted match patterns for privileged add-ons. This should technically be rejected for unprivileged + * add-ons, but, reasons. The MatchPattern class will still refuse privileged schemes for those extensions. + */ + type MatchPatternUnestricted = string; /** Same as MatchPattern above, but includes moz-extension protocol */ type MatchPatternInternal = string | _MatchPatternInternal; @@ -291,7 +377,7 @@ declare namespace browser._manifest { exclude_globs?: string[]; /** The list of CSS files to inject */ css?: ExtensionURL[]; - /** The list of CSS files to inject */ + /** The list of JS files to inject */ js?: ExtensionURL[]; /** * If allFrames is `true`, implies that the JavaScript or CSS should be injected into all frames of current @@ -324,6 +410,29 @@ declare namespace browser._manifest { /** @deprecated Event pages are not currently supported. This will run as a persistent background page. */ type PersistentBackgroundProperty = boolean; + /** Represents a native manifest file */ + type NativeManifest = { + name: string; + description: string; + path: string; + type: "pkcs11" | "stdio"; + allowed_extensions: ExtensionID[]; + } | { + name: ExtensionID; + description: string; + data: any; + type: "storage"; + }; + + type ThemeColor = string | [number, number, number] | [number, number, number, number]; + + interface ThemeExperiment { + stylesheet?: ExtensionURL; + images?: string; + colors?: string; + properties?: string; + } + interface ThemeType { images?: { additional_backgrounds?: ImageDataOrExtensionURL[]; @@ -331,18 +440,44 @@ declare namespace browser._manifest { theme_frame?: ImageDataOrExtensionURL; }; colors?: { - accentcolor?: string; - frame?: number[]; - tab_text?: number[]; - textcolor?: string; - toolbar?: string; - toolbar_text?: string; - bookmark_text?: string; - toolbar_field?: string; - toolbar_field_text?: string; - toolbar_top_separator?: string; - toolbar_bottom_separator?: string; - toolbar_vertical_separator?: string; + tab_selected?: ThemeColor; + accentcolor?: ThemeColor; + frame?: ThemeColor; + frame_inactive?: ThemeColor; + textcolor?: ThemeColor; + tab_background_text?: ThemeColor; + tab_background_separator?: ThemeColor; + tab_loading?: ThemeColor; + tab_text?: ThemeColor; + tab_line?: ThemeColor; + toolbar?: ThemeColor; + toolbar_text?: ThemeColor; + bookmark_text?: ThemeColor; + toolbar_field?: ThemeColor; + toolbar_field_text?: ThemeColor; + toolbar_field_border?: ThemeColor; + toolbar_field_separator?: ThemeColor; + toolbar_top_separator?: ThemeColor; + toolbar_bottom_separator?: ThemeColor; + toolbar_vertical_separator?: ThemeColor; + icons?: ThemeColor; + icons_attention?: ThemeColor; + button_background_hover?: ThemeColor; + button_background_active?: ThemeColor; + popup?: ThemeColor; + popup_text?: ThemeColor; + popup_border?: ThemeColor; + toolbar_field_focus?: ThemeColor; + toolbar_field_text_focus?: ThemeColor; + toolbar_field_border_focus?: ThemeColor; + popup_highlight?: ThemeColor; + popup_highlight_text?: ThemeColor; + ntp_background?: ThemeColor; + ntp_text?: ThemeColor; + sidebar?: ThemeColor; + sidebar_text?: ThemeColor; + sidebar_highlight?: ThemeColor; + sidebar_highlight_text?: ThemeColor; }; icons?: { back?: ExtensionURL; @@ -432,11 +567,23 @@ declare namespace browser._manifest { }; } + /** Contents of manifest.json for a static theme */ + interface ThemeManifest { + theme: ThemeType; + default_locale?: string; + theme_experiment?: ThemeExperiment; + icons?: { + [key: number]: string; + }; + } + type KeyName = string; type _OptionalPermission = - "browserSettings" + "browserSettings" | "cookies" + | "downloads" + | "downloads.open" | "clipboardRead" | "clipboardWrite" | "geolocation" @@ -449,13 +596,14 @@ declare namespace browser._manifest { | "bookmarks" | "find" | "history" + | "search" | "activeTab" - | "tabs"; + | "tabs" + | "tabHide"; type _Permission = - "contextualIdentities" - | "downloads" - | "downloads.open" + "contextualIdentities" + | "dns" | "identity" | "management" | "alarms" @@ -465,6 +613,7 @@ declare namespace browser._manifest { | "privacy" | "proxy" | "nativeMessaging" + | "telemetry" | "theme" | "browsingData" | "devtools" @@ -474,11 +623,24 @@ declare namespace browser._manifest { | "pkcs11" | "sessions"; + type _WebExtensionManifestIncognito = "spanning"; + + /** Defines the location the browserAction will appear by default. The default location is navbar. */ + type _WebExtensionManifestBrowserActionDefaultArea = + "navbar" + | "menupanel" + | "tabstrip" + | "personaltoolbar"; + type _ProtocolHandlerProtocol = - "bitcoin" + "bitcoin" + | "dat" + | "dweb" | "geo" | "gopher" | "im" + | "ipfs" + | "ipns" | "irc" | "ircs" | "magnet" @@ -489,6 +651,7 @@ declare namespace browser._manifest { | "sip" | "sms" | "smsto" + | "ssb" | "ssh" | "tel" | "urn" @@ -496,21 +659,12 @@ declare namespace browser._manifest { | "wtai" | "xmpp"; - type _WebExtensionManifestIncognito = "spanning"; - - /** Defines the location the browserAction will appear by default. The default location is navbar. */ - type _WebExtensionManifestBrowserActionDefaultArea = - "navbar" - | "menupanel" - | "tabstrip" - | "personaltoolbar"; - type _MatchPattern = ""; type _MatchPatternInternal = ""; type _ThemeTypeAdditionalBackgroundsAlignment = - "bottom" + "bottom" | "center" | "left" | "right" @@ -526,7 +680,7 @@ declare namespace browser._manifest { | "right top"; type _ThemeTypeAdditionalBackgroundsTiling = - "no-repeat" + "no-repeat" | "repeat" | "repeat-x" | "repeat-y"; @@ -541,13 +695,15 @@ declare namespace browser._manifest { */ declare namespace browser.browserSettings { /* browserSettings types */ - /** How images should be animated in the browser. */ type ImageAnimationBehavior = - "normal" + "normal" | "none" | "once"; + /** After which mouse event context menus should popup. */ + type ContextMenuMouseEvent = "mouseup" | "mousedown"; + /* browserSettings properties */ /** Allows or disallows pop-up windows from opening in response to user events. */ const allowPopupsForUserEvents: types.Setting; @@ -555,6 +711,15 @@ declare namespace browser.browserSettings { /** Enables or disables the browser cache. */ const cacheEnabled: types.Setting; + /** This boolean setting controls whether the selected tab can be closed with a double click. */ + const closeTabsByDoubleClick: types.Setting; + + /** + * Controls after which mouse event context menus popup. This setting's value is of type ContextMenuMouseEvent, + * which has possible values of `mouseup` and `mousedown`. + */ + const contextMenuShowEvent: types.Setting; + /** Returns the value of the overridden home page. Read-only. */ const homepageOverride: types.Setting; @@ -567,8 +732,30 @@ declare namespace browser.browserSettings { /** Returns the value of the overridden new tab page. Read-only. */ const newTabPageOverride: types.Setting; + /** + * Controls where new tabs are opened. `afterCurrent` will open all new tabs next to the current tab, + * `relatedAfterCurrent` will open only related tabs next to the current tab, and `atEnd` will open all tabs at the + * end of the tab strip. The default is `relatedAfterCurrent`. + */ + const newTabPosition: types.Setting; + + /** This boolean setting controls whether bookmarks are opened in the current tab or in a new tab. */ + const openBookmarksInNewTabs: types.Setting; + + /** This boolean setting controls whether search results are opened in the current tab or in a new tab. */ + const openSearchResultsInNewTabs: types.Setting; + + /** This boolean setting controls whether urlbar results are opened in the current tab or in a new tab. */ + const openUrlbarResultsInNewTabs: types.Setting; + /** Disables webAPI notifications. */ const webNotificationsDisabled: types.Setting; + + /** This setting controls whether the user-chosen colors override the page's colors. */ + const overrideDocumentColors: types.Setting; + + /** This setting controls whether the document's fonts are used. */ + const useDocumentFonts: types.Setting; } /** @@ -595,6 +782,51 @@ declare namespace browser.clipboard { function setImageData(imageData: ArrayBuffer, imageType: _SetImageData): Promise; } +/** Not allowed in: Content scripts, Devtools pages */ +declare namespace browser.contentScripts { + /* contentScripts types */ + type ExtensionFileOrCode = { + file: _manifest.ExtensionURL; + } | { + code: string; + }; + + /** Details of a content script registered programmatically */ + interface RegisteredContentScriptOptions { + matches: _manifest.MatchPattern[]; + excludeMatches?: _manifest.MatchPattern[]; + includeGlobs?: string[]; + excludeGlobs?: string[]; + /** The list of CSS files to inject */ + css?: ExtensionFileOrCode[]; + /** The list of JS files to inject */ + js?: ExtensionFileOrCode[]; + /** + * If allFrames is `true`, implies that the JavaScript or CSS should be injected into all frames of current + * page. By default, it's `false` and is only injected into the top frame. + */ + allFrames?: boolean; + /** + * If matchAboutBlank is true, then the code is also injected in about:blank and about:srcdoc frames if your + * extension has access to its parent document. Code cannot be inserted in top-level about:-frames. By default + * it is `false`. + */ + matchAboutBlank?: boolean; + /** The soonest that the JavaScript or CSS will be injected into the tab. Defaults to "document_idle". */ + runAt?: extensionTypes.RunAt; + } + + /** An object that represents a content script registered programmatically */ + interface RegisteredContentScript { + /** Unregister a content script registered programmatically */ + unregister(): Promise; + } + + /* contentScripts functions */ + /** Register a content script programmatically */ + function register(contentScriptOptions: RegisteredContentScriptOptions): Promise; +} + /** * Use the `browser.contextualIdentities` API to query and modify contextual identity, also called as containers. * @@ -698,6 +930,16 @@ declare namespace browser.contextualIdentities { */ declare namespace browser.cookies { /* cookies types */ + /** + * A cookie's 'SameSite' state (https://tools.ietf.org/html/draft-west-first-party-cookies). 'no_restriction' + * corresponds to a cookie set without a 'SameSite' attribute, 'lax' to 'SameSite=Lax', and 'strict' to + * 'SameSite=Strict'. + */ + type SameSiteStatus = + "no_restriction" + | "lax" + | "strict"; + /** Represents information about an HTTP cookie. */ interface Cookie { /** The name of the cookie. */ @@ -718,6 +960,8 @@ declare namespace browser.cookies { secure: boolean; /** True if the cookie is marked as HttpOnly (i.e. the cookie is inaccessible to client-side scripts). */ httpOnly: boolean; + /** The cookie's same-site status (i.e. whether the cookie is sent with cross-site requests). */ + sameSite: SameSiteStatus; /** True if the cookie is a session cookie, as opposed to a persistent cookie with an expiration date. */ session: boolean; /** @@ -727,6 +971,8 @@ declare namespace browser.cookies { expirationDate?: number; /** The ID of the cookie store containing this cookie, as provided in getAllCookieStores(). */ storeId: string; + /** The first-party domain of the cookie. */ + firstPartyDomain: string; } /** @@ -751,7 +997,7 @@ declare namespace browser.cookies { * "overwrite". Plan your response accordingly. */ type OnChangedCause = - "evicted" + "evicted" | "expired" | "explicit" | "expired_overwrite" @@ -778,6 +1024,11 @@ declare namespace browser.cookies { * cookie store will be used. */ storeId?: string; + /** + * The first-party domain which the cookie to retrieve is associated. This attribute is required if First-Party + * Isolation is enabled. + */ + firstPartyDomain?: string; }): Promise; /** @@ -804,6 +1055,12 @@ declare namespace browser.cookies { * used. */ storeId?: string; + /** + * Restricts the retrieved cookies to those whose first-party domains match this one. This attribute is + * required if First-Party Isolation is enabled. To not filter by a specific first-party domain, use `null` or + * `undefined`. + */ + firstPartyDomain?: string; }): Promise; /** @@ -829,6 +1086,8 @@ declare namespace browser.cookies { secure?: boolean; /** Whether the cookie should be marked as HttpOnly. Defaults to false. */ httpOnly?: boolean; + /** The cookie's same-site status. */ + sameSite?: SameSiteStatus; /** * The expiration date of the cookie as the number of seconds since the UNIX epoch. If omitted, the cookie * becomes a session cookie. @@ -839,6 +1098,10 @@ declare namespace browser.cookies { * execution context's cookie store. */ storeId?: string; + /** + * The first-party domain of the cookie. This attribute is required if First-Party Isolation is enabled. + */ + firstPartyDomain?: string; }): Promise; /** @@ -858,6 +1121,11 @@ declare namespace browser.cookies { * the current execution context's cookie store. */ storeId?: string; + /** + * The first-party domain associated with the cookie. This attribute is required if First-Party Isolation is + * enabled. + */ + firstPartyDomain?: string; }): Promise<{ /** The URL associated with the cookie that's been removed. */ url: string; @@ -865,6 +1133,8 @@ declare namespace browser.cookies { name: string; /** The ID of the cookie store from which the cookie was removed. */ storeId: string; + /** The first-party domain associated with the cookie that's been removed. */ + firstPartyDomain: string; } | undefined>; /** Lists all existing cookie stores. */ @@ -887,6 +1157,46 @@ declare namespace browser.cookies { }) => void>; } +/** + * Asynchronous DNS API + * + * Permissions: `dns` + * + * Not allowed in: Content scripts, Devtools pages + */ +declare namespace browser.dns { + /* dns types */ + /** An object encapsulating a DNS Record. */ + interface DNSRecord { + /** + * The canonical hostname for this record. this value is empty if the record was not fetched with the + * 'canonical_name' flag. + */ + canonicalName?: string; + /** Record retreived with TRR. */ + isTRR: string; + addresses: string[]; + } + + type ResolveFlags = _ResolveFlags[]; + + type _ResolveFlags = + "allow_name_collisions" + | "bypass_cache" + | "canonical_name" + | "disable_ipv4" + | "disable_ipv6" + | "disable_trr" + | "offline" + | "priority_low" + | "priority_medium" + | "speculate"; + + /* dns functions */ + /** Resolves a hostname to a DNS record. */ + function resolve(hostname: string, flags?: ResolveFlags): Promise; +} + /** * Permissions: `downloads` * @@ -895,12 +1205,12 @@ declare namespace browser.cookies { declare namespace browser.downloads { /* downloads types */ type FilenameConflictAction = - "uniquify" + "uniquify" | "overwrite" | "prompt"; type InterruptReason = - "FILE_FAILED" + "FILE_FAILED" | "FILE_ACCESS_DENIED" | "FILE_NO_SPACE" | "FILE_NAME_TOO_LONG" @@ -940,7 +1250,7 @@ declare namespace browser.downloads { * These string constants will never change, however the set of DangerTypes may change. */ type DangerType = - "file" + "file" | "url" | "content" | "uncommon" @@ -960,7 +1270,7 @@ declare namespace browser.downloads { * These string constants will never change, however the set of States may change. */ type State = - "in_progress" + "in_progress" | "interrupted" | "complete"; @@ -1085,9 +1395,7 @@ declare namespace browser.downloads { } /** The HTTP method to use if the URL uses the HTTP[S] protocol. */ - type _DownloadMethod = - "GET" - | "POST"; + type _DownloadMethod = "GET" | "POST"; /* downloads functions */ /** @@ -1400,6 +1708,45 @@ declare namespace browser.events { } } +/** Not allowed in: Content scripts, Devtools pages */ +declare namespace browser.experiments { + /* experiments types */ + interface ExperimentAPI { + schema: ExperimentURL; + parent?: { + events?: APIEvents; + paths?: APIPaths; + script: ExperimentURL; + scopes?: APIParentScope[]; + }; + child?: { + paths: APIPaths; + script: ExperimentURL; + scopes: APIChildScope[]; + }; + } + + type ExperimentURL = string; + + type APIPaths = APIPath[]; + + type APIPath = string[]; + + type APIEvents = APIEvent[]; + + type APIEvent = "startup"; + + type APIParentScope = + "addon_parent" + | "content_parent" + | "devtools_parent"; + + type APIChildScope = + "addon_child" + | "content_child" + | "devtools_child"; +} + /** * The `browser.extension` API has utilities that can be used by any extension page. It includes support for exchanging * messages between an extension and its content scripts or between extensions, as described in detail in Message @@ -1407,10 +1754,9 @@ declare namespace browser.events { */ declare namespace browser.extension { /* extension types */ - /** The type of extension view. */ type ViewType = - "tab" + "tab" | "popup" | "sidebar"; @@ -1507,11 +1853,8 @@ declare namespace browser.extension { */ declare namespace browser.extensionTypes { /* extensionTypes types */ - /** The format of an image. */ - type ImageFormat = - "jpeg" - | "png"; + type ImageFormat = "jpeg" | "png"; /** Details about the format and quality of an image. */ interface ImageDetails { @@ -1527,14 +1870,12 @@ declare namespace browser.extensionTypes { /** The soonest that the JavaScript or CSS will be injected into the tab. */ type RunAt = - "document_start" + "document_start" | "document_end" | "document_idle"; /** The origin of the CSS to inject, this affects the cascading order (priority) of the stylesheet. */ - type CSSOrigin = - "user" - | "author"; + type CSSOrigin = "user" | "author"; /** * Details of the script or CSS to inject. Either the code or the file property must be set, but both may not be @@ -1679,13 +2020,13 @@ declare namespace browser.identity { /** Starts an auth flow at the specified URL. */ function launchWebAuthFlow(details: { - url: string; + url: _manifest.HttpURL; interactive?: boolean; }): Promise; /** * Generates a redirect URL to be used in |launchWebAuthFlow|. - * @param [ path] The path appended to the end of the generated URL. + * @param [path] The path appended to the end of the generated URL. */ function getRedirectURL(path?: string): string; @@ -1706,9 +2047,7 @@ declare namespace browser.identity { */ declare namespace browser.idle { /* idle types */ - type IdleState = - "active" - | "idle"; + type IdleState = "active" | "idle"; /* idle functions */ /** @@ -1756,14 +2095,10 @@ declare namespace browser.management { } /** A reason the item is disabled. */ - type ExtensionDisabledReason = - "unknown" - | "permissions_increase"; + type ExtensionDisabledReason = "unknown" | "permissions_increase"; - /** The type of this extension. Will always be 'extension'. */ - type ExtensionType = - "extension" - | "theme"; + /** The type of this extension, 'extension' or 'theme'. */ + type ExtensionType = "extension" | "theme"; /** * How the extension was installed. One of @@ -1773,7 +2108,7 @@ declare namespace browser.management { * `other`: The extension was installed by other means. */ type ExtensionInstallType = - "development" + "development" | "normal" | "sideload" | "other"; @@ -1798,7 +2133,7 @@ declare namespace browser.management { enabled: boolean; /** A reason the item is disabled. */ disabledReason?: ExtensionDisabledReason; - /** The type of this extension. Will always return 'extension'. */ + /** The type of this extension, 'extension' or 'theme'. */ type: ExtensionType; /** The URL of the homepage of this extension. */ homepageUrl?: string; @@ -1831,6 +2166,16 @@ declare namespace browser.management { */ function get(id: _manifest.ExtensionID): Promise; + /** Installs and enables a theme extension from the given url. */ + function install(options: { + /** URL pointing to the XPI file on addons.mozilla.org or similar. */ + url: _manifest.HttpURL; + /** A hash of the XPI file, using sha256 or stronger. */ + hash?: string; + }): Promise<{ + id: _manifest.ExtensionID; + } | undefined>; + /** * Returns information about the calling extension. Note: This function can be used without requesting the * 'management' permission in the manifest. @@ -1877,14 +2222,12 @@ declare namespace browser.management { declare namespace browser.notifications { /* notifications types */ type TemplateType = - "basic" + "basic" | "image" | "list" | "progress"; - type PermissionLevel = - "granted" - | "denied"; + type PermissionLevel = "granted" | "denied"; interface NotificationItem { /** Title of one item of a list notification. */ @@ -2111,10 +2454,9 @@ declare namespace browser.privacy { */ declare namespace browser.privacy.network { /* privacy.network types */ - /** The IP handling policy of WebRTC. */ type IPHandlingPolicy = - "default" + "default" | "default_public_and_private_interfaces" | "default_public_interface_only" | "disable_non_proxied_udp"; @@ -2163,13 +2505,27 @@ declare namespace browser.privacy.services { */ declare namespace browser.privacy.websites { /* privacy.websites types */ - /** The mode for tracking protection. */ type TrackingProtectionModeOption = - "always" + "always" | "never" | "private_browsing"; + /** The settings for cookies. */ + interface CookieConfig { + /** The type of cookies to allow. */ + behavior?: _CookieConfigBehavior; + /** Whether to create all cookies as nonPersistent (i.e., session) cookies. */ + nonPersistentCookies?: boolean; + } + + /** The type of cookies to allow. */ + type _CookieConfigBehavior = + "allow_all" + | "reject_all" + | "reject_third_party" + | "allow_visited"; + /* privacy.websites properties */ /** * If disabled, the browser blocks third-party sites from setting cookies. The value of this preference is of type @@ -2221,6 +2577,12 @@ declare namespace browser.privacy.websites { * TrackingProtectionModeOption, defaulting to `private_browsing_only`. */ const trackingProtectionMode: types.Setting; + + /** + * Allow users to specify the default settings for allowing cookies, as well as whether all cookies should be + * created as non-persistent cookies. This setting's value is of type CookieConfig. + */ + const cookieConfig: types.Setting; } /** @@ -2232,6 +2594,83 @@ declare namespace browser.privacy.websites { * Not allowed in: Content scripts, Devtools pages */ declare namespace browser.proxy { + /* proxy types */ + /** An object which describes proxy settings. */ + interface ProxyConfig { + /** The type of proxy to use. */ + proxyType?: _ProxyConfigProxyType; + /** The address of the http proxy, can include a port. */ + http?: string; + /** Use the http proxy server for all protocols. */ + httpProxyAll?: boolean; + /** The address of the ftp proxy, can include a port. */ + ftp?: string; + /** The address of the ssl proxy, can include a port. */ + ssl?: string; + /** The address of the socks proxy, can include a port. */ + socks?: string; + /** The version of the socks proxy. */ + socksVersion?: number; + /** A list of hosts which should not be proxied. */ + passthrough?: string; + /** A URL to use to configure the proxy. */ + autoConfigUrl?: string; + /** Do not prompt for authentication if password is saved. */ + autoLogin?: boolean; + /** Proxy DNS when using SOCKS v5. */ + proxyDNS?: boolean; + } + + /** The type of proxy to use. */ + type _ProxyConfigProxyType = + "none" + | "autoDetect" + | "system" + | "manual" + | "autoConfig"; + + type _ProxyOnRequestEvent void> = WebExtEventBase<(callback: T, filter: webRequest.RequestFilter, extraInfoSpec?: Array<"requestHeaders">) => void, T>; + + /* proxy properties */ + /** Configures proxy settings. This setting's value is an object of type ProxyConfig. */ + const settings: types.Setting; + /* proxy functions */ /** Registers the proxy script for the extension. */ function register(url: string): Promise; @@ -2246,7 +2685,13 @@ declare namespace browser.proxy { function registerProxyScript(url: string): Promise; /* proxy events */ + /** Fired when proxy data is needed for a request. */ + const onRequest: _ProxyOnRequestEvent; + /** Notifies about proxy script errors. */ + const onError: WebExtEvent<(error: object) => void>; + + /** Please use `proxy.onError`. */ const onProxyError: WebExtEvent<(error: object) => void>; } @@ -2262,10 +2707,10 @@ declare namespace browser.runtime { /** An object which allows two way communication with other pages. */ interface Port { name: string; - disconnect(): void; + disconnect: () => void; onDisconnect: events.Event; onMessage: events.Event; - postMessage(message: object): void; + postMessage: (message: object) => void; /** This property will **only** be present on ports passed to onConnect/onConnectExternal listeners. */ sender?: MessageSender; } @@ -2300,7 +2745,7 @@ declare namespace browser.runtime { /** The operating system the browser is running on. */ type PlatformOs = - "mac" + "mac" | "win" | "android" | "cros" @@ -2309,7 +2754,7 @@ declare namespace browser.runtime { /** The machine's processor architecture. */ type PlatformArch = - "arm" + "arm" | "x86-32" | "x86-64"; @@ -2340,13 +2785,13 @@ declare namespace browser.runtime { /** Result of the update check. */ type RequestUpdateCheckStatus = - "throttled" + "throttled" | "no_update" | "update_available"; /** The reason that this event is being dispatched. */ type OnInstalledReason = - "install" + "install" | "update" | "browser_update"; @@ -2357,7 +2802,7 @@ declare namespace browser.runtime { * the enterprise policy. */ type OnRestartRequiredReason = - "app_update" + "app_update" | "os_update" | "periodic"; @@ -2700,9 +3145,133 @@ declare namespace browser.storage { } /** - * The theme API allows customizing of visual elements of the browser. + * Use the `browser.telemetry` API to send telemetry data to the Mozilla Telemetry service. Restricted to Mozilla + * privileged webextensions. * - * Permissions: `theme` + * Permissions: `telemetry`, `mozillaAddons` + * + * Not allowed in: Content scripts, Devtools pages + */ +declare namespace browser.telemetry { + /* telemetry types */ + /** + * Type of scalar: 'count' for numeric values, 'string' for string values, 'boolean' for boolean values. Maps to + * `nsITelemetry.SCALAR_TYPE_*`. + */ + type ScalarType = + "count" + | "string" + | "boolean"; + + /** Represents registration data for a Telemetry scalar. */ + interface ScalarData { + kind: ScalarType; + /** True if this is a keyed scalar. */ + keyed?: boolean; + /** True if this data should be recorded on release. */ + record_on_release?: boolean; + /** + * True if this scalar entry is expired. This allows recording it without error, but it will be discarded. + */ + expired?: boolean; + } + + /** Represents registration data for a Telemetry event. */ + interface EventData { + /** List of methods for this event entry. */ + methods: string[]; + /** List of objects for this event entry. */ + objects: string[]; + /** List of allowed extra keys for this event entry. */ + extra_keys: string[]; + /** True if this data should be recorded on release. */ + record_on_release?: boolean; + /** + * True if this event entry is expired. This allows recording it without error, but it will be discarded. + */ + expired?: boolean; + } + + /* telemetry functions */ + /** + * Submits a custom ping to the Telemetry back-end. See `submitExternalPing` inside TelemetryController.jsm for + * more details. + * @param type The type of the ping. + * @param message The data payload for the ping. + * @param options Options object. + */ + function submitPing(type: string, message: any, options: { + /** True if the ping should contain the client id. */ + addClientId?: boolean; + /** True if the ping should contain the environment data. */ + addEnvironment?: boolean; + /** Set to override the environment data. */ + overrideEnvironment?: any; + /** If true, send the ping using the PingSender. */ + usePingSender?: boolean; + }): Promise; + + /** Checks if Telemetry is enabled. */ + function canUpload(): Promise; + + /** + * Adds the value to the given scalar. + * @param name The scalar name. + * @param value The numeric value to add to the scalar. Only unsigned integers supported. + */ + function scalarAdd(name: string, value: number): Promise; + + /** + * Sets the named scalar to the given value. Throws if the value type doesn't match the scalar type. + * @param name The scalar name + * @param value The value to set the scalar to + */ + function scalarSet(name: string, value: string | boolean | number | object): Promise; + + /** + * Sets the scalar to the maximum of the current and the passed value + * @param name The scalar name. + * @param value The numeric value to set the scalar to. Only unsigned integers supported. + */ + function scalarSetMaximum(name: string, value: number): Promise; + + /** + * Record an event in Telemetry. Throws when trying to record an unknown event. + * @param category The category name. + * @param method The method name. + * @param object The object name. + * @param [value] An optional string value to record. + * @param [extra] An optional object of the form (string -> string). It should only contain registered extra keys. + */ + function recordEvent(category: string, method: string, object: string, value?: number, extra?: string): Promise; + + /** + * Register new scalars to record them from addons. See nsITelemetry.idl for more details. + * @param category The unique category the scalars are registered in. + * @param data An object that contains registration data for multiple scalars. Each property name is the scalar + * name, and the corresponding property value is an object of ScalarData type. + */ + function registerScalars(category: string, data: ScalarData): Promise; + + /** + * Register new events to record them from addons. See nsITelemetry.idl for more details. + * @param category The unique category the events are registered in. + * @param data An object that contains registration data for 1+ events. Each property name is the category name, + * and the corresponding property value is an object of EventData type. + */ + function registerEvents(category: string, data: EventData): Promise; + + /** + * Enable recording of events in a category. Events default to recording disabled. This allows to toggle recording + * for all events in the specified category. + * @param category The category name. + * @param enabled Whether recording is enabled for events in that category. + */ + function setEventRecordingEnabled(category: string, enabled: boolean): Promise; +} + +/** + * The theme API allows customizing of visual elements of the browser. * * Not allowed in: Content scripts, Devtools pages */ @@ -2764,13 +3333,23 @@ declare namespace browser.topSites { url: string; /** The title of the page. */ title?: string; + /** Data URL for the favicon, if available. */ + favicon?: string; } /* topSites functions */ /** Gets a list of top sites. */ function get(options?: { - /** Which providers to get top sites from. Possible values are "places" and "activityStream". */ + /** @deprecated Please use the other options to tune the results received from topSites. */ providers?: string[]; + /** The number of top sites to return, defaults to the value used by Firefox */ + limit?: number; + /** Limit the result to a single top site link per domain */ + onePerDomain?: boolean; + /** Include sites that the user has blocked from appearing on the Firefox new tab. */ + includeBlocked?: boolean; + /** Include sites favicon if available. */ + includeFavicon?: boolean; }): Promise; } @@ -2781,7 +3360,6 @@ declare namespace browser.topSites { */ declare namespace browser.types { /* types types */ - /** * The scope of the Setting. One of * @@ -2796,7 +3374,7 @@ declare namespace browser.types { * Only `regular` is supported by Firefox at this time. */ type SettingScope = - "regular" + "regular" | "regular_only" | "incognito_persistent" | "incognito_session_only"; @@ -2810,7 +3388,7 @@ declare namespace browser.types { * * `controlled_by_this_extension`: controlled by this extension */ type LevelOfControl = - "not_controllable" + "not_controllable" | "controlled_by_other_extensions" | "controllable_by_this_extension" | "controlled_by_this_extension"; @@ -2887,14 +3465,13 @@ declare namespace browser.types { */ declare namespace browser.webNavigation { /* webNavigation types */ - /** * Cause of the navigation. The same transition types as defined in the history API are used. These are the same * transition types as defined in the history API except with `"start_page"` in place of `"auto_toplevel"` (for * backwards compatibility). */ type TransitionType = - "link" + "link" | "typed" | "auto_bookmark" | "auto_subframe" @@ -2907,7 +3484,7 @@ declare namespace browser.webNavigation { | "keyword_generated"; type TransitionQualifier = - "client_redirect" + "client_redirect" | "server_redirect" | "forward_back" | "from_address_bar"; @@ -3221,7 +3798,7 @@ declare namespace browser.webNavigation { declare namespace browser.webRequest { /* webRequest types */ type ResourceType = - "main_frame" + "main_frame" | "sub_frame" | "stylesheet" | "script" @@ -3240,24 +3817,19 @@ declare namespace browser.webRequest { | "csp_report" | "imageset" | "web_manifest" + | "speculative" | "other"; - type OnBeforeRequestOptions = - "blocking" - | "requestBody"; + type OnBeforeRequestOptions = "blocking" | "requestBody"; - type OnBeforeSendHeadersOptions = - "requestHeaders" - | "blocking"; + type OnBeforeSendHeadersOptions = "requestHeaders" | "blocking"; type OnSendHeadersOptions = "requestHeaders"; - type OnHeadersReceivedOptions = - "blocking" - | "responseHeaders"; + type OnHeadersReceivedOptions = "blocking" | "responseHeaders"; type OnAuthRequiredOptions = - "responseHeaders" + "responseHeaders" | "blocking" | "asyncBlocking"; @@ -3309,6 +3881,12 @@ declare namespace browser.webRequest { * redirect will be issued using the GET method. */ redirectUrl?: string; + /** + * Only used as a response to the onBeforeRequest event. If set, the original request is prevented from being + * sent/completed and is instead upgraded to a secure request. If any extension returns `redirectUrl` during + * onBeforeRequest, `upgradeToSecure` will have no affect. + */ + upgradeToSecure?: boolean; /** * Only used as a response to the onBeforeSendHeaders event. If set, the request is made with these request * headers instead. @@ -3330,6 +3908,75 @@ declare namespace browser.webRequest { }; } + /** Contains the certificate properties of the request if it is a secure request. */ + interface CertificateInfo { + subject: string; + issuer: string; + /** Contains start and end timestamps. */ + validity: { + start: number; + end: number; + }; + fingerprint: { + sha1: string; + sha256: string; + }; + serialNumber: string; + isBuiltInRoot: boolean; + subjectPublicKeyInfoDigest: { + sha256: string; + }; + rawDER?: number[]; + } + + type CertificateTransparencyStatus = + "not_applicable" + | "policy_compliant" + | "policy_not_enough_scts" + | "policy_not_diverse_scts"; + + type TransportWeaknessReasons = "cipher"; + + /** Contains the security properties of the request (ie. SSL/TLS information). */ + interface SecurityInfo { + state: _SecurityInfoState; + /** Error message if state is "broken" */ + errorMessage?: string; + /** Protocol version if state is "secure" */ + protocolVersion?: _SecurityInfoProtocolVersion; + /** The cipher suite used in this request if state is "secure". */ + cipherSuite?: string; + /** The key exchange algorithm used in this request if state is "secure". */ + keaGroupName?: string; + /** The signature scheme used in this request if state is "secure". */ + signatureSchemeName?: string; + /** + * Certificate data if state is "secure". Will only contain one entry unless `certificateChain` is passed as an + * option. + */ + certificates: CertificateInfo[]; + /** The domain name does not match the certificate domain. */ + isDomainMismatch?: boolean; + isExtendedValidation?: boolean; + /** + * The certificate is either expired or is not yet valid. See `CertificateInfo.validity` for start and end + * dates. + */ + isNotValidAtThisTime?: boolean; + isUntrusted?: boolean; + /** + * Certificate transparency compliance per RFC 6962\. See `https://www.certificate-transparency.org/what-is-ct` + * for more information. + */ + certificateTransparencyStatus?: CertificateTransparencyStatus; + /** True if host uses Strict Transport Security and state is "secure". */ + hsts?: boolean; + /** True if host uses Public Key Pinning and state is "secure". */ + hpkp?: string; + /** list of reasons that cause the request to be considered weak, if state is "weak" */ + weaknessReasons?: TransportWeaknessReasons[]; + } + /** Contains data uploaded in a URL request. */ interface UploadData { /** An ArrayBuffer with a copy of the data. */ @@ -3338,6 +3985,20 @@ declare namespace browser.webRequest { file?: string; } + type _SecurityInfoState = + "insecure" + | "weak" + | "broken" + | "secure"; + + /** Protocol version if state is "secure" */ + type _SecurityInfoProtocolVersion = + "TLSv1" + | "TLSv1.1" + | "TLSv1.2" + | "TLSv1.3" + | "unknown"; + type _WebRequestOnBeforeRequestEvent; + /* webRequest events */ /** * Fired when a request is about to occur. @@ -3798,7 +4469,6 @@ declare namespace browser.webRequest { */ declare namespace browser.bookmarks { /* bookmarks types */ - /** * Indicates the reason why this node is unmodifiable. The `managed` value indicates that this node was configured * by the system administrator or by the custodian of a supervised user. Omitted if the node can be modified by the @@ -3807,7 +4477,10 @@ declare namespace browser.bookmarks { type BookmarkTreeNodeUnmodifiable = "managed"; /** Indicates the type of a BookmarkTreeNode, which can be one of bookmark, folder or separator. */ - type BookmarkTreeNodeType = "bookmark" | "folder" | "separator"; + type BookmarkTreeNodeType = + "bookmark" + | "folder" + | "separator"; /** * A node (either a bookmark or a folder) in the bookmark tree. Child nodes are ordered within their parent folder. @@ -3958,19 +4631,6 @@ declare namespace browser.bookmarks { const onChildrenReordered: WebExtEvent<(id: string, reorderInfo: { childIds: string[]; }) => void> | undefined; - - /** - * Fired when a bookmark import session is begun. Expensive observers should ignore onCreated updates until - * onImportEnded is fired. Observers should still handle other notifications immediately. - * @deprecated Unsupported on Firefox at this time. - */ - const onImportBegan: WebExtEvent<() => void> | undefined; - - /** - * Fired when a bookmark import session is ended. - * @deprecated Unsupported on Firefox at this time. - */ - const onImportEnded: WebExtEvent<() => void> | undefined; } /** @@ -3983,32 +4643,66 @@ declare namespace browser.bookmarks { */ declare namespace browser.browserAction { /* browserAction types */ + /** + * Specifies to which tab or window the value should be set, or from which one it should be retrieved. If no tab + * nor window is specified, the global value is set or retrieved. + */ + interface Details { + /** + * When setting a value, it will be specific to the specified tab, and will automatically reset when the tab + * navigates. When getting, specifies the tab to get the value from; if there is no tab-specific value, the + * window one will be inherited. + */ + tabId?: number; + /** + * When setting a value, it will be specific to the specified window. When getting, specifies the window to get + * the value from; if there is no window-specific value, the global one will be inherited. + */ + windowId?: number; + } + type ColorArray = [number, number, number, number]; /** Pixel data for an image. Must be an ImageData object (for example, from a `canvas` element). */ type ImageDataType = object/*ImageData*/; + /** + * An array of four integers in the range [0,255] that make up the RGBA color of the badge. For example, opaque red + * is `[255, 0, 0, 255]`. Can also be a string with a CSS value, with opaque red being `#FF0000` or `#F00`. + */ + type ColorValue = string | ColorArray | null; + /* browserAction functions */ - /** Sets the title of the browser action. This shows up in the tooltip. */ + /** + * Sets the title of the browser action. This shows up in the tooltip. + * @param details Specifies to which tab or window the value should be set, or from which one it should be + * retrieved. If no tab nor window is specified, the global value is set or retrieved. + */ function setTitle(details: { /** The string the browser action should display when moused over. */ - title: string; - /** Limits the change to when a particular tab is selected. Automatically resets when the tab is closed. */ + title: string | null; + /** + * When setting a value, it will be specific to the specified tab, and will automatically reset when the tab + * navigates. When getting, specifies the tab to get the value from; if there is no tab-specific value, the + * window one will be inherited. + */ tabId?: number; + /** + * When setting a value, it will be specific to the specified window. When getting, specifies the window to get + * the value from; if there is no window-specific value, the global one will be inherited. + */ + windowId?: number; }): Promise; /** Gets the title of the browser action. */ - function getTitle(details: { - /** - * Specify the tab to get the title from. If no tab is specified, the non-tab-specific title is returned. - */ - tabId?: number; - }): Promise; + function getTitle(details: Details): Promise; /** * Sets the icon for the browser action. The icon can be specified either as the path to an image file or as the * pixel data from a canvas element, or as dictionary of either one of those. Either the **path** or the * **imageData** property must be specified. + * @param details Specifies to which tab or window the value should be set, or from which one it should be + * retrieved. If no tab nor window is specified, the global value is set or retrieved. */ function setIcon(details: { /** @@ -4031,64 +4725,115 @@ declare namespace browser.browserAction { path?: string | { [key: number]: string; }; - /** Limits the change to when a particular tab is selected. Automatically resets when the tab is closed. */ - tabId?: number; - }): Promise; - - /** Sets the html document to be opened as a popup when the user clicks on the browser action's icon. */ - function setPopup(details: { - /** Limits the change to when a particular tab is selected. Automatically resets when the tab is closed. */ - tabId?: number; - /** The html file to show in a popup. If set to the empty string (''), no popup is shown. */ - popup: string; - }): Promise; - - /** Gets the html document set as the popup for this browser action. */ - function getPopup(details: { /** - * Specify the tab to get the popup from. If no tab is specified, the non-tab-specific popup is returned. + * When setting a value, it will be specific to the specified tab, and will automatically reset when the tab + * navigates. When getting, specifies the tab to get the value from; if there is no tab-specific value, the + * window one will be inherited. */ tabId?: number; - }): Promise; - - /** Sets the badge text for the browser action. The badge is displayed on top of the icon. */ - function setBadgeText(details: { - /** Any number of characters can be passed, but only about four can fit in the space. */ - text: string; - /** Limits the change to when a particular tab is selected. Automatically resets when the tab is closed. */ - tabId?: number; + /** + * When setting a value, it will be specific to the specified window. When getting, specifies the window to get + * the value from; if there is no window-specific value, the global one will be inherited. + */ + windowId?: number; }): Promise; /** - * Gets the badge text of the browser action. If no tab is specified, the non-tab-specific badge text is returned. + * Sets the html document to be opened as a popup when the user clicks on the browser action's icon. + * @param details Specifies to which tab or window the value should be set, or from which one it should be + * retrieved. If no tab nor window is specified, the global value is set or retrieved. */ - function getBadgeText(details: { + function setPopup(details: { + /** The html file to show in a popup. If set to the empty string (''), no popup is shown. */ + popup: string | null; /** - * Specify the tab to get the badge text from. If no tab is specified, the non-tab-specific badge text is - * returned. + * When setting a value, it will be specific to the specified tab, and will automatically reset when the tab + * navigates. When getting, specifies the tab to get the value from; if there is no tab-specific value, the + * window one will be inherited. */ tabId?: number; - }): Promise; - - /** Sets the background color for the badge. */ - function setBadgeBackgroundColor(details: { /** - * An array of four integers in the range [0,255] that make up the RGBA color of the badge. For example, opaque - * red is `[255, 0, 0, 255]`. Can also be a string with a CSS value, with opaque red being `#FF0000` or `#F00`. + * When setting a value, it will be specific to the specified window. When getting, specifies the window to get + * the value from; if there is no window-specific value, the global one will be inherited. */ - color: string | ColorArray; - /** Limits the change to when a particular tab is selected. Automatically resets when the tab is closed. */ - tabId?: number; + windowId?: number; }): Promise; - /** Gets the background color of the browser action. */ - function getBadgeBackgroundColor(details: { + /** Gets the html document set as the popup for this browser action. */ + function getPopup(details: Details): Promise; + + /** + * Sets the badge text for the browser action. The badge is displayed on top of the icon. + * @param details Specifies to which tab or window the value should be set, or from which one it should be + * retrieved. If no tab nor window is specified, the global value is set or retrieved. + */ + function setBadgeText(details: { + /** Any number of characters can be passed, but only about four can fit in the space. */ + text: string | null; /** - * Specify the tab to get the badge background color from. If no tab is specified, the non-tab-specific badge - * background color is returned. + * When setting a value, it will be specific to the specified tab, and will automatically reset when the tab + * navigates. When getting, specifies the tab to get the value from; if there is no tab-specific value, the + * window one will be inherited. */ tabId?: number; - }): Promise; + /** + * When setting a value, it will be specific to the specified window. When getting, specifies the window to get + * the value from; if there is no window-specific value, the global one will be inherited. + */ + windowId?: number; + }): Promise; + + /** + * Gets the badge text of the browser action. If no tab nor window is specified is specified, the global badge text + * is returned. + */ + function getBadgeText(details: Details): Promise; + + /** + * Sets the background color for the badge. + * @param details Specifies to which tab or window the value should be set, or from which one it should be + * retrieved. If no tab nor window is specified, the global value is set or retrieved. + */ + function setBadgeBackgroundColor(details: { + color: ColorValue; + /** + * When setting a value, it will be specific to the specified tab, and will automatically reset when the tab + * navigates. When getting, specifies the tab to get the value from; if there is no tab-specific value, the + * window one will be inherited. + */ + tabId?: number; + /** + * When setting a value, it will be specific to the specified window. When getting, specifies the window to get + * the value from; if there is no window-specific value, the global one will be inherited. + */ + windowId?: number; + }): Promise; + + /** Gets the background color of the browser action badge. */ + function getBadgeBackgroundColor(details: Details): Promise; + + /** + * Sets the text color for the badge. + * @param details Specifies to which tab or window the value should be set, or from which one it should be + * retrieved. If no tab nor window is specified, the global value is set or retrieved. + */ + function setBadgeTextColor(details: { + color: ColorValue; + /** + * When setting a value, it will be specific to the specified tab, and will automatically reset when the tab + * navigates. When getting, specifies the tab to get the value from; if there is no tab-specific value, the + * window one will be inherited. + */ + tabId?: number; + /** + * When setting a value, it will be specific to the specified window. When getting, specifies the window to get + * the value from; if there is no window-specific value, the global one will be inherited. + */ + windowId?: number; + }): Promise; + + /** Gets the text color of the browser action badge. */ + function getBadgeTextColor(details: Details): Promise; /** * Enables the browser action for a tab. By default, browser actions are enabled. @@ -4102,6 +4847,9 @@ declare namespace browser.browserAction { */ function disable(tabId?: number): Promise; + /** Checks whether the browser action is enabled. */ + function isEnabled(details: Details): Promise; + /** Opens the extension popup window in the active window. */ function openPopup(): Promise; @@ -4270,6 +5018,24 @@ declare namespace browser.commands { } /* commands functions */ + /** + * Update the details of an already defined command. + * @param detail The new description for the command. + */ + function update(detail: { + /** The name of the command. */ + name: string; + /** The new description for the command. */ + description?: string; + shortcut?: _manifest.KeyName; + }): Promise; + + /** + * Reset a command's details to what is specified in the manifest. + * @param name The name of the command. + */ + function reset(name: string): Promise; + /** Returns all the registered extension commands for this extension and their shortcut (if active). */ function getAll(): Promise; @@ -4279,7 +5045,7 @@ declare namespace browser.commands { } /** - * Permissions: `devtools` + * Manifest keys: `devtools_page` * * Allowed in: Devtools pages only */ @@ -4425,19 +5191,15 @@ declare namespace browser.devtools.network { } /* devtools.network functions */ - /** - * Returns HAR log that contains all known network requests. - * @deprecated Unsupported on Firefox at this time. - */ + /** Returns HAR log that contains all known network requests. */ function getHAR(): Promise; /* devtools.network events */ /** * Fired when a network request is finished and all request data are available. * @param request Description of a network request in the form of a HAR entry. See HAR specification for details. - * @deprecated Unsupported on Firefox at this time. */ - const onRequestFinished: WebExtEvent<(request: Request) => void> | undefined; + const onRequestFinished: WebExtEvent<(request: Request) => void>; /** * Fired when the inspected window navigates to a new page. @@ -4575,6 +5337,8 @@ declare namespace browser.devtools.panels { onClicked: WebExtEvent<() => void>; } + type _Create = ""; + /* devtools.panels properties */ /** Elements panel. */ const elements: ElementsPanel; @@ -4589,10 +5353,11 @@ declare namespace browser.devtools.panels { /** * Creates an extension panel. * @param title Title that is displayed next to the extension icon in the Developer Tools toolbar. - * @param iconPath Path of the panel's icon relative to the extension directory. + * @param iconPath Path of the panel's icon relative to the extension directory, or an empty string to use the + * default extension icon as the panel icon. * @param pagePath Path of the panel's HTML page relative to the extension directory. */ - function create(title: string, iconPath: string, pagePath: string): Promise; + function create(title: string, iconPath: _manifest.ExtensionURL | _Create, pagePath: _manifest.ExtensionURL): Promise; /** * Specifies the function to be called when the user clicks a resource link in the Developer Tools window. To unset @@ -4695,16 +5460,19 @@ declare namespace browser.find { declare namespace browser.geckoProfiler { /* geckoProfiler types */ type ProfilerFeature = - "java" + "java" | "js" | "leaf" | "mainthreadio" | "memory" | "privacy" - | "restyle" + | "responsiveness" + | "screenshots" + | "seqstyle" | "stackwalk" | "tasktracer" - | "threads"; + | "threads" + | "trackopts"; /* geckoProfiler functions */ /** Starts the profiler with the specified settings. */ @@ -4768,10 +5536,9 @@ declare namespace browser.geckoProfiler { */ declare namespace browser.history { /* history types */ - /** The transition type for this visit from its referrer. */ type TransitionType = - "link" + "link" | "typed" | "auto_bookmark" | "auto_subframe" @@ -4902,18 +5669,15 @@ declare namespace browser.history { * your context menu additions apply to, such as images, hyperlinks, and pages. * * Permissions: `contextMenus` - * - * Not allowed in: Content scripts, Devtools pages */ declare namespace browser.contextMenus { /* contextMenus types */ - /** * The different contexts a menu can appear in. Specifying 'all' is equivalent to the combination of all other * contexts except for 'tab' and 'tools_menu'. */ type ContextType = - "all" + "all" | "page" | "frame" | "selection" @@ -4924,13 +5688,14 @@ declare namespace browser.contextMenus { | "video" | "audio" | "launcher" + | "bookmark" | "browser_action" | "page_action" | "tab"; /** The type of menu item. */ type ItemType = - "normal" + "normal" | "checkbox" | "radio" | "separator"; @@ -4966,12 +5731,19 @@ declare namespace browser.contextMenus { wasChecked?: boolean; /** A flag indicating the state of a checkbox or radio item after it is clicked. */ checked?: boolean; + /** The id of the bookmark where the context menu was clicked, if it was on a bookmark. */ + bookmarkId: string; /** An array of keyboard modifiers that were held while the menu item was clicked. */ modifiers: _OnClickDataModifiers[]; + /** + * An identifier of the clicked element, if any. Use menus.getTargetElement in the page to find the + * corresponding element. + */ + targetElementId?: number; } type _OnClickDataModifiers = - "Shift" + "Shift" | "Alt" | "Command" | "Ctrl" @@ -5017,6 +5789,8 @@ declare namespace browser.contextMenus { checked?: boolean; /** List of contexts this menu item will appear in. Defaults to ['page'] if not specified. */ contexts?: ContextType[]; + /** Whether the item is visible in the menu. */ + visible?: boolean; /** * A function that will be called back when the menu item is clicked. Event pages cannot use this; instead, * they should register a listener for `contextMenus.onClicked`. @@ -5024,7 +5798,7 @@ declare namespace browser.contextMenus { * @param tab The details of the tab where the click took place. Note: this parameter only present for * extensions. */ - onclick?: (info: menusInternal.OnClickData, tab: tabs.Tab) => void; + onclick?: (info: OnClickData, tab: tabs.Tab) => void; /** The ID of a parent menu item; this makes the item a child of a previously added item. */ parentId?: number | string; /** @@ -5056,11 +5830,13 @@ declare namespace browser.contextMenus { title?: string; checked?: boolean; contexts?: ContextType[]; + /** Whether the item is visible in the menu. */ + visible?: boolean; /** * @param tab The details of the tab where the click took place. Note: this parameter only present for * extensions. */ - onclick?: (info: menusInternal.OnClickData, tab: tabs.Tab) => void; + onclick?: (info: OnClickData, tab: tabs.Tab) => void; /** Note: You cannot change an item to be a child of one of its own descendants. */ parentId?: number | string; documentUrlPatterns?: string[]; @@ -5077,6 +5853,20 @@ declare namespace browser.contextMenus { /** Removes all context menu items added by this extension. */ function removeAll(): Promise; + /** + * Updates the extension items in the shown menu, including changes that have been made since the menu was shown. + * Has no effect if the menu is hidden. Rebuilding a shown menu is an expensive operation, only invoke this method + * when necessary. + */ + function refresh(): Promise; + + /** + * Retrieve the element that was associated with a recent contextmenu event. + * @param targetElementId The identifier of the clicked element, available as info.targetElementId in the + * menus.onShown, onClicked or onclick event. + */ + function getTargetElement(targetElementId: number): object/*Element*/ | void; + /* contextMenus events */ /** * Fired when a context menu item is clicked. @@ -5085,25 +5875,49 @@ declare namespace browser.contextMenus { * parameter will be missing. */ const onClicked: WebExtEvent<(info: OnClickData, tab?: tabs.Tab) => void>; + + /** + * Fired when a menu is shown. The extension can add, modify or remove menu items and call menus.refresh() to + * update the menu. + * @param info Information about the context of the menu action and the created menu items. For more information + * about each property, see OnClickData. The following properties are only set if the extension has host + * permissions for the given context: linkUrl, linkText, srcUrl, pageUrl, frameUrl, selectionText. + * @param tab The details of the tab where the menu was opened. + */ + const onShown: WebExtEvent<(info: { + /** A list of IDs of the menu items that were shown. */ + menuIds: number | string[]; + /** A list of all contexts that apply to the menu. */ + contexts: ContextType[]; + editable: boolean; + mediaType: string; + linkUrl?: string; + linkText?: string; + srcUrl?: string; + pageUrl?: string; + frameUrl?: string; + selectionText?: string; + targetElementId?: number; + }, tab: tabs.Tab) => void>; + + /** Fired when a menu is hidden. This event is only fired if onShown has fired before. */ + const onHidden: WebExtEvent<() => void>; } /** * Use the browser.menus API to add items to the browser's menus. You can choose what types of objects your context * menu additions apply to, such as images, hyperlinks, and pages. * - * Permissions: `menus` - * - * Not allowed in: Content scripts, Devtools pages + * Permissions: `menus`, `menus` */ declare namespace browser.menus { /* menus types */ - /** * The different contexts a menu can appear in. Specifying 'all' is equivalent to the combination of all other * contexts except for 'tab' and 'tools_menu'. */ type ContextType = - "all" + "all" | "page" | "frame" | "selection" @@ -5114,6 +5928,7 @@ declare namespace browser.menus { | "video" | "audio" | "launcher" + | "bookmark" | "browser_action" | "page_action" | "tab" @@ -5121,7 +5936,7 @@ declare namespace browser.menus { /** The type of menu item. */ type ItemType = - "normal" + "normal" | "checkbox" | "radio" | "separator"; @@ -5157,12 +5972,19 @@ declare namespace browser.menus { wasChecked?: boolean; /** A flag indicating the state of a checkbox or radio item after it is clicked. */ checked?: boolean; + /** The id of the bookmark where the context menu was clicked, if it was on a bookmark. */ + bookmarkId: string; /** An array of keyboard modifiers that were held while the menu item was clicked. */ modifiers: _OnClickDataModifiers[]; + /** + * An identifier of the clicked element, if any. Use menus.getTargetElement in the page to find the + * corresponding element. + */ + targetElementId?: number; } type _OnClickDataModifiers = - "Shift" + "Shift" | "Alt" | "Command" | "Ctrl" @@ -5208,6 +6030,8 @@ declare namespace browser.menus { checked?: boolean; /** List of contexts this menu item will appear in. Defaults to ['page'] if not specified. */ contexts?: ContextType[]; + /** Whether the item is visible in the menu. */ + visible?: boolean; /** * A function that will be called back when the menu item is clicked. Event pages cannot use this; instead, * they should register a listener for `contextMenus.onClicked`. @@ -5215,7 +6039,7 @@ declare namespace browser.menus { * @param tab The details of the tab where the click took place. Note: this parameter only present for * extensions. */ - onclick?: (info: menusInternal.OnClickData, tab: tabs.Tab) => void; + onclick?: (info: OnClickData, tab: tabs.Tab) => void; /** The ID of a parent menu item; this makes the item a child of a previously added item. */ parentId?: number | string; /** @@ -5247,11 +6071,13 @@ declare namespace browser.menus { title?: string; checked?: boolean; contexts?: ContextType[]; + /** Whether the item is visible in the menu. */ + visible?: boolean; /** * @param tab The details of the tab where the click took place. Note: this parameter only present for * extensions. */ - onclick?: (info: menusInternal.OnClickData, tab: tabs.Tab) => void; + onclick?: (info: OnClickData, tab: tabs.Tab) => void; /** Note: You cannot change an item to be a child of one of its own descendants. */ parentId?: number | string; documentUrlPatterns?: string[]; @@ -5268,6 +6094,20 @@ declare namespace browser.menus { /** Removes all context menu items added by this extension. */ function removeAll(): Promise; + /** + * Updates the extension items in the shown menu, including changes that have been made since the menu was shown. + * Has no effect if the menu is hidden. Rebuilding a shown menu is an expensive operation, only invoke this method + * when necessary. + */ + function refresh(): Promise; + + /** + * Retrieve the element that was associated with a recent contextmenu event. + * @param targetElementId The identifier of the clicked element, available as info.targetElementId in the + * menus.onShown, onClicked or onclick event. + */ + function getTargetElement(targetElementId: number): object/*Element*/ | void; + /* menus events */ /** * Fired when a context menu item is clicked. @@ -5276,46 +6116,33 @@ declare namespace browser.menus { * parameter will be missing. */ const onClicked: WebExtEvent<(info: OnClickData, tab?: tabs.Tab) => void>; -} -/** - * Use the `browser.contextMenus` API to add items to the browser's context menu. You can choose what types of objects - * your context menu additions apply to, such as images, hyperlinks, and pages. - * - * Not allowed in: Content scripts, Devtools pages - */ -declare namespace browser.menusInternal { - /* menusInternal types */ - /** Information sent when a context menu item is clicked. */ - interface OnClickData { - /** The ID of the menu item that was clicked. */ - menuItemId: number | string; - /** The parent ID, if any, for the item clicked. */ - parentMenuItemId?: number | string; - /** - * One of 'image', 'video', or 'audio' if the context menu was activated on one of these types of elements. - */ - mediaType?: string; - /** If the element is a link, the URL it points to. */ - linkUrl?: string; - /** Will be present for elements with a 'src' URL. */ - srcUrl?: string; - /** - * The URL of the page where the menu item was clicked. This property is not set if the click occured in a - * context where there is no current page, such as in a launcher context menu. - */ - pageUrl?: string; - /** The URL of the frame of the element where the context menu was clicked, if it was in a frame. */ - frameUrl?: string; - /** The text for the context selection, if any. */ - selectionText?: string; - /** A flag indicating whether the element is editable (text input, textarea, etc.). */ + /** + * Fired when a menu is shown. The extension can add, modify or remove menu items and call menus.refresh() to + * update the menu. + * @param info Information about the context of the menu action and the created menu items. For more information + * about each property, see OnClickData. The following properties are only set if the extension has host + * permissions for the given context: linkUrl, linkText, srcUrl, pageUrl, frameUrl, selectionText. + * @param tab The details of the tab where the menu was opened. + */ + const onShown: WebExtEvent<(info: { + /** A list of IDs of the menu items that were shown. */ + menuIds: number | string[]; + /** A list of all contexts that apply to the menu. */ + contexts: ContextType[]; editable: boolean; - /** A flag indicating the state of a checkbox or radio item before it was clicked. */ - wasChecked?: boolean; - /** A flag indicating the state of a checkbox or radio item after it is clicked. */ - checked?: boolean; - } + mediaType: string; + linkUrl?: string; + linkText?: string; + srcUrl?: string; + pageUrl?: string; + frameUrl?: string; + selectionText?: string; + targetElementId?: number; + }, tab: tabs.Tab) => void>; + + /** Fired when a menu is hidden. This event is only fired if onShown has fired before. */ + const onHidden: WebExtEvent<() => void>; } /** @@ -5327,10 +6154,9 @@ declare namespace browser.menusInternal { */ declare namespace browser.omnibox { /* omnibox types */ - /** The style type. */ type DescriptionStyleType = - "url" + "url" | "match" | "dim"; @@ -5340,7 +6166,7 @@ declare namespace browser.omnibox { * should take place in a new selected tab. */ type OnInputEnteredDisposition = - "currentTab" + "currentTab" | "newForegroundTab" | "newBackgroundTab"; @@ -5455,12 +6281,18 @@ declare namespace browser.pageAction { */ function hide(tabId: number): Promise; + /** Checks whether the page action is shown. */ + function isShown(details: { + /** Specify the tab to get the shownness from. */ + tabId: number; + }): Promise; + /** Sets the title of the page action. This is displayed in a tooltip over the page action. */ function setTitle(details: { /** The id of the tab for which you want to modify the page action. */ tabId: number; /** The tooltip string. */ - title: string; + title: string | null; }): void; /** Gets the title of the page action. */ @@ -5504,7 +6336,7 @@ declare namespace browser.pageAction { /** The id of the tab for which you want to modify the page action. */ tabId: number; /** The html file to show in a popup. If set to the empty string (''), no popup is shown. */ - popup: string; + popup: string | null; }): void; /** Gets the html document set as the popup for this page action. */ @@ -5553,6 +6385,38 @@ declare namespace browser.pkcs11 { }>; } +/** + * Use browser.search to interact with search engines. + * + * Permissions: `search` + * + * Not allowed in: Content scripts, Devtools pages + */ +declare namespace browser.search { + /* search types */ + /** An object encapsulating a search engine */ + interface SearchEngine { + name: string; + isDefault: boolean; + alias?: string; + favIconUrl?: string; + } + + /* search functions */ + /** Gets a list of search engines. */ + function get(): Promise; + + /** Perform a search. */ + function search(searchProperties: { + /** Terms to search for. */ + query: string; + /** Search engine to use. Uses the default if not specified. */ + engine?: string; + /** The ID of the tab for the search results. If not specified, a new tab is created. */ + tabId?: number; + }): Promise; +} + /** * Use the `browser.sessions` API to query and restore tabs and windows from a browsing session. * @@ -5695,17 +6559,23 @@ declare namespace browser.sidebarAction { /** Sets the title of the sidebar action. This shows up in the tooltip. */ function setTitle(details: { /** The string the sidebar action should display when moused over. */ - title: string; + title: string | null; /** Sets the sidebar title for the tab specified by tabId. Automatically resets when the tab is closed. */ tabId?: number; + /** Sets the sidebar title for the window specified by windowId. */ + windowId?: number; }): Promise; /** Gets the title of the sidebar action. */ function getTitle(details: { /** - * Specify the tab to get the title from. If no tab is specified, the non-tab-specific title is returned. + * Specify the tab to get the title from. If no tab nor window is specified, the global title is returned. */ tabId?: number; + /** + * Specify the window to get the title from. If no tab nor window is specified, the global title is returned. + */ + windowId?: number; }): Promise; /** @@ -5734,6 +6604,8 @@ declare namespace browser.sidebarAction { path?: string; /** Sets the sidebar icon for the tab specified by tabId. Automatically resets when the tab is closed. */ tabId?: number; + /** Sets the sidebar icon for the window specified by windowId. */ + windowId?: number; }): Promise; /** @@ -5742,16 +6614,22 @@ declare namespace browser.sidebarAction { function setPanel(details: { /** Sets the sidebar url for the tab specified by tabId. Automatically resets when the tab is closed. */ tabId?: number; + /** Sets the sidebar url for the window specified by windowId. */ + windowId?: number; /** The url to the html file to show in a sidebar. If set to the empty string (''), no sidebar is shown. */ - panel: string; + panel: string | null; }): Promise; /** Gets the url to the html document set as the panel for this sidebar action. */ function getPanel(details: { /** - * Specify the tab to get the sidebar from. If no tab is specified, the non-tab-specific sidebar is returned. + * Specify the tab to get the panel from. If no tab nor window is specified, the global panel is returned. */ tabId?: number; + /** + * Specify the window to get the panel from. If no tab nor window is specified, the global panel is returned. + */ + windowId?: number; }): Promise; /** Opens the extension sidebar in the active window. */ @@ -5759,6 +6637,12 @@ declare namespace browser.sidebarAction { /** Closes the extension sidebar in the active window if the sidebar belongs to the extension. */ function close(): Promise; + + /** Checks whether the sidebar action is open. */ + function isOpen(details: { + /** Specify the window to get the openness from. */ + windowId?: number; + }): Promise; } /** @@ -5769,14 +6653,13 @@ declare namespace browser.sidebarAction { */ declare namespace browser.tabs { /* tabs types */ - /** An event that caused a muted state change. */ type MutedInfoReason = /** A user input action has set/overridden the muted state. */ - "user" -/** Tab capture started, forcing a muted state change. */ + "user" + /** Tab capture started, forcing a muted state change. */ | "capture" -/** An extension, identified by the extensionId field, set the muted state. */ + /** An extension, identified by the extensionId field, set the muted state. */ | "extension"; /** Tab muted state and the reason for the last state change. */ @@ -5795,6 +6678,19 @@ declare namespace browser.tabs { extensionId?: string; } + /** Tab sharing state for screen, microphone and camera. */ + interface SharingState { + /** + * If the tab is sharing the screen the value will be one of "Screen", "Window", or "Application", or undefined + * if not screen sharing. + */ + screen?: string; + /** True if the tab is using the camera. */ + camera: boolean; + /** True if the tab is using the microphone. */ + microphone: boolean; + } + interface Tab { /** * The ID of the tab. Tab IDs are unique within a browser session. Under some circumstances a Tab may not be @@ -5855,6 +6751,8 @@ declare namespace browser.tabs { width?: number; /** The height of the tab in pixels. */ height?: number; + /** True if the tab is hidden. */ + hidden?: boolean; /** The session ID used to uniquely identify a Tab obtained from the `sessions` API. */ sessionId?: string; /** The CookieStoreId used for the tab. */ @@ -5863,6 +6761,10 @@ declare namespace browser.tabs { isArticle?: boolean; /** Whether the document in the tab is being rendered in reader mode. */ isInReaderMode?: boolean; + /** Current tab sharing state for screen, microphone and camera. */ + sharingState?: SharingState; + /** Whether the tab is drawing attention. */ + attention?: boolean; } /** @@ -5871,7 +6773,7 @@ declare namespace browser.tabs { */ type ZoomSettingsMode = /** Zoom changes are handled automatically by the browser. */ - "automatic" + "automatic" /** * Overrides the automatic handling of zoom changes. The `onZoomChange` event will still be dispatched, and it * is the responsibility of the extension to listen for this event and manually scale the page. This mode does @@ -5895,7 +6797,7 @@ declare namespace browser.tabs { * navigating to other pages in the same origin, they will all be zoomed to the same zoom factor. The * `per-origin` scope is only available in the `automatic` mode. */ - | "per-origin" + "per-origin" /** * Zoom changes only take effect in this tab, and zoom changes in other tabs will not affect the zooming of * this tab. Also, `per-tab` zoom changes are reset on navigation; navigating a tab will always load pages with @@ -5921,6 +6823,12 @@ declare namespace browser.tabs { /** The page settings including: orientation, scale, background, margins, headers, footers. */ interface PageSettings { + /** The page size unit: 0 = inches, 1 = millimeters. Default: 0. */ + paperSizeUnit?: number; + /** The paper width in paper size units. Default: 8.5. */ + paperWidth?: number; + /** The paper height in paper size units. Default: 11.0. */ + paperHeight?: number; /** The page content orientation: 0 = portrait, 1 = landscape. Default: 0. */ orientation?: number; /** The page content scaling factor: 1.0 = 100% = normal size. Default: 1.0. */ @@ -5931,12 +6839,22 @@ declare namespace browser.tabs { showBackgroundColors?: boolean; /** Whether the page background images should be shown. Default: false. */ showBackgroundImages?: boolean; - /** The page size unit: 0 = inches, 1 = millimeters. Default: 0. */ - paperSizeUnit?: number; - /** The paper width in paper size units. Default: 8.5. */ - paperWidth?: number; - /** The paper height in paper size units. Default: 11.0. */ - paperHeight?: number; + /** The spacing between the left header/footer and the left edge of the paper (inches). Default: 0. */ + edgeLeft?: number; + /** The spacing between the right header/footer and the right edge of the paper (inches). Default: 0. */ + edgeRight?: number; + /** The spacing between the top of the headers and the top edge of the paper (inches). Default: 0 */ + edgeTop?: number; + /** The spacing between the bottom of the footers and the bottom edge of the paper (inches). Default: 0. */ + edgeBottom?: number; + /** The margin between the page content and the left edge of the paper (inches). Default: 0.5. */ + marginLeft?: number; + /** The margin between the page content and the right edge of the paper (inches). Default: 0.5. */ + marginRight?: number; + /** The margin between the page content and the top edge of the paper (inches). Default: 0.5. */ + marginTop?: number; + /** The margin between the page content and the bottom edge of the paper (inches). Default: 0.5. */ + marginBottom?: number; /** The text for the page's left header. Default: '&T'. */ headerLeft?: string; /** The text for the page's center header. Default: ''. */ @@ -5949,29 +6867,88 @@ declare namespace browser.tabs { footerCenter?: string; /** The text for the page's right footer. Default: '&D'. */ footerRight?: string; - /** The margin between the page content and the left edge of the paper (inches). Default: 0.5. */ - marginLeft?: number; - /** The margin between the page content and the right edge of the paper (inches). Default: 0.5. */ - marginRight?: number; - /** The margin between the page content and the top edge of the paper (inches). Default: 0.5. */ - marginTop?: number; - /** The margin between the page content and the bottom edge of the paper (inches). Default: 0.5. */ - marginBottom?: number; } /** Whether the tabs have completed loading. */ - type TabStatus = - "loading" - | "complete"; + type TabStatus = "loading" | "complete"; /** The type of window. */ type WindowType = - "normal" + "normal" | "popup" | "panel" | "app" | "devtools"; + /** Event names supported in onUpdated. */ + type UpdatePropertyName = + "attention" + | "audible" + | "discarded" + | "favIconUrl" + | "hidden" + | "isarticle" + | "isArticle" + | "mutedInfo" + | "pinned" + | "sharingState" + | "status" + | "title"; + + /** An object describing filters to apply to tabs.onUpdated events. */ + interface UpdateFilter { + /** + * A list of URLs or URL patterns. Events that cannot match any of the URLs will be filtered out. Filtering + * with urls requires the `"tabs"` or `"activeTab"` permission. + */ + urls?: string[]; + /** A list of property names. Events that do not match any of the names will be filtered out. */ + properties?: UpdatePropertyName[]; + tabId?: number; + windowId?: number; + } + + type _QueryScreen = + "Screen" + | "Window" + | "Application"; + + type _TabsOnUpdatedEvent