mirror of
https://github.com/gosticks/DefinitelyTyped.git
synced 2026-08-16 23:10:29 +00:00
Merge pull request #28282 from mike-north/new-cp-mapping
[@types/ember] rewrite computed property unwrapping to use infer
This commit is contained in:
Vendored
+2
-2
@@ -1,10 +1,10 @@
|
||||
// Type definitions for ember-data 2.14
|
||||
// Type definitions for ember-data 3.0
|
||||
// Project: https://github.com/emberjs/data
|
||||
// Definitions by: Derek Wickern <https://github.com/dwickern>
|
||||
// Mike North <https://github.com/mike-north>
|
||||
// Chris Krycho <https://github.com/chriskrycho>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
// TypeScript Version: 2.8
|
||||
|
||||
declare module 'ember-data' {
|
||||
import Ember from 'ember';
|
||||
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
import { DS } from "ember-data";
|
||||
|
||||
export default DS.Adapter;
|
||||
export { AdapterRegistry } from 'ember-data';
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import DS from 'ember-data';
|
||||
|
||||
declare const AdapterError: typeof DS.AdapterError;
|
||||
declare const InvalidError: typeof DS.InvalidError;
|
||||
declare const UnauthorizedError: typeof DS.UnauthorizedError;
|
||||
declare const ForbiddenError: typeof DS.ForbiddenError;
|
||||
declare const NotFoundError: typeof DS.NotFoundError;
|
||||
declare const ConflictError: typeof DS.ConflictError;
|
||||
declare const ServerError: typeof DS.ServerError;
|
||||
declare const TimeoutError: typeof DS.TimeoutError;
|
||||
declare const AbortError: typeof DS.AbortError;
|
||||
declare const errorsHashToArray: typeof DS.errorsHashToArray;
|
||||
declare const errorsArrayToHash: typeof DS.errorsArrayToHash;
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import DS from 'ember-data';
|
||||
export default DS.JSONAPIAdapter;
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import DS from 'ember-data';
|
||||
export default DS.RESTAdapter;
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import DS from 'ember-data';
|
||||
export default DS.attr;
|
||||
Vendored
+2121
File diff suppressed because it is too large
Load Diff
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
import { DS } from 'ember-data';
|
||||
|
||||
export default DS.Model;
|
||||
export { ModelRegistry } from 'ember-data';
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import DS from 'ember-data';
|
||||
|
||||
declare const hasMany: typeof DS.hasMany;
|
||||
declare const belongsTo: typeof DS.belongsTo;
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
import DS from 'ember-data';
|
||||
|
||||
export default DS.Serializer;
|
||||
export { SerializerRegistry } from 'ember-data';
|
||||
@@ -0,0 +1,3 @@
|
||||
import DS from 'ember-data';
|
||||
|
||||
export default DS.EmbeddedRecordsMixin;
|
||||
@@ -0,0 +1,3 @@
|
||||
import DS from 'ember-data';
|
||||
|
||||
export default DS.JSONAPISerializer;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import DS from 'ember-data';
|
||||
|
||||
export default DS.JSONSerializer;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import DS from 'ember-data';
|
||||
|
||||
export default DS.RESTSerializer;
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
import DS from 'ember-data';
|
||||
|
||||
export default DS.Store;
|
||||
@@ -0,0 +1,120 @@
|
||||
import Ember from 'ember';
|
||||
import DS from 'ember-data';
|
||||
|
||||
class Session extends Ember.Service {}
|
||||
declare module '@ember/service' {
|
||||
interface Registry { 'session': Session; }
|
||||
}
|
||||
|
||||
const JsonApi = DS.JSONAPIAdapter.extend({
|
||||
// Application specific overrides go here
|
||||
});
|
||||
|
||||
const Customized = DS.JSONAPIAdapter.extend({
|
||||
host: 'https://api.example.com',
|
||||
namespace: 'api/v1',
|
||||
headers: {
|
||||
'API_KEY': 'secret key',
|
||||
'ANOTHER_HEADER': 'Some header value'
|
||||
}
|
||||
});
|
||||
|
||||
const AuthTokenHeader = DS.JSONAPIAdapter.extend({
|
||||
session: Ember.inject.service('session'),
|
||||
headers: Ember.computed('session.authToken', function() {
|
||||
return {
|
||||
'API_KEY': this.get('session.authToken'),
|
||||
'ANOTHER_HEADER': 'Some header value'
|
||||
};
|
||||
})
|
||||
});
|
||||
|
||||
const UseAjax = DS.JSONAPIAdapter.extend({
|
||||
query(store: DS.Store, type: string, query: object) {
|
||||
const url = 'https://api.example.com/my-api';
|
||||
return this.ajax(url, 'POST', {
|
||||
param: 'foo'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const UseAjaxOptions = DS.JSONAPIAdapter.extend({
|
||||
query(store: DS.Store, type: string, query: object) {
|
||||
const url = 'https://api.example.com/my-api';
|
||||
const options = this.ajaxOptions(url, 'DELETE', {
|
||||
foo: 'bar'
|
||||
});
|
||||
return Ember.$.ajax(url, {
|
||||
...options
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const UseAjaxOptionsWithOptionalThirdParams = DS.JSONAPIAdapter.extend({
|
||||
query(store: DS.Store, type: string, query: object) {
|
||||
const url = 'https://api.example.com/my-api';
|
||||
const options = this.ajaxOptions(url, 'DELETE');
|
||||
return Ember.$.ajax(url, {
|
||||
...options
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
declare module 'ember-data' {
|
||||
interface ModelRegistry {
|
||||
'rootModel': any;
|
||||
'super-user': any;
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/emberjs/data/blob/c9d8212c857ca78218ad98d11621819b38dba98f/tests/unit/adapters/build-url-mixin/build-url-test.js
|
||||
const BuildURLAdapter = DS.RESTAdapter.extend({
|
||||
worksWithOnlyModelNameAndId() {
|
||||
this.buildURL('rootModel', 1);
|
||||
},
|
||||
|
||||
worksWithFindRecord() {
|
||||
this.buildURL('super-user', 1, {} as any, 'findRecord');
|
||||
},
|
||||
|
||||
worksWithFindAll() {
|
||||
this.buildURL('super-user', null, {} as any, 'findAll');
|
||||
},
|
||||
|
||||
worksWithQueryStub() {
|
||||
this.buildURL('super-user', null, null, 'query', { limit: 10 });
|
||||
},
|
||||
|
||||
worksWithQueryRecord() {
|
||||
this.buildURL('super-user', null, null, 'queryRecord', { companyId: 10 });
|
||||
},
|
||||
|
||||
worksWithFindMany() {
|
||||
this.buildURL('super-user', [1, 2, 3], null, 'findMany');
|
||||
},
|
||||
|
||||
worksWithFindHasMany() {
|
||||
this.buildURL('super-user', 1, {} as any, 'findHasMany');
|
||||
},
|
||||
|
||||
worksWithFindBelongsTo() {
|
||||
this.buildURL('super-user', 1, {} as any, 'findBelongsTo');
|
||||
},
|
||||
|
||||
worksWithCreateRecord() {
|
||||
this.buildURL('super-user', 1, {} as any, 'createRecord');
|
||||
},
|
||||
|
||||
worksWithUpdateRecord() {
|
||||
this.buildURL('super-user', 1, {} as any, 'updateRecord');
|
||||
},
|
||||
|
||||
worksWithDeleteRecord() {
|
||||
this.buildURL('super-user', 1, {} as any, 'deleteRecord');
|
||||
},
|
||||
|
||||
worksWithUnknownRequestType() {
|
||||
this.buildURL('super-user', 1, null, 'unknown');
|
||||
this.buildURL('super-user', null, null, 'unknown');
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
import DS from 'ember-data';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
declare const store: DS.Store;
|
||||
|
||||
class Folder extends DS.Model {
|
||||
name = DS.attr('string');
|
||||
children = DS.hasMany('folder', { inverse: 'parent' });
|
||||
parent = DS.belongsTo('folder', { inverse: 'children' });
|
||||
}
|
||||
|
||||
declare module 'ember-data' {
|
||||
interface ModelRegistry {
|
||||
folder: Folder;
|
||||
}
|
||||
}
|
||||
|
||||
const folder = Folder.create();
|
||||
assertType<Folder>(folder.get('parent'));
|
||||
assertType<string>(folder.get('parent').get('name'));
|
||||
folder.get('parent').then(parent => {
|
||||
assertType<Folder>(parent);
|
||||
assertType<string>(parent.get('name'));
|
||||
folder.set('parent', parent);
|
||||
});
|
||||
|
||||
folder.set('parent', folder);
|
||||
folder.set('parent', folder.get('parent'));
|
||||
folder.set('parent', store.findRecord('folder', 3));
|
||||
@@ -0,0 +1,106 @@
|
||||
import Ember from 'ember';
|
||||
import DS from 'ember-data';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
const { AdapterError } = DS;
|
||||
|
||||
// https://emberjs.com/api/ember-data/2.16/classes/DS.AdapterError
|
||||
const MaintenanceError = DS.AdapterError.extend({
|
||||
message: 'Down for maintenance.',
|
||||
});
|
||||
const maintenanceError = new MaintenanceError();
|
||||
assertType<DS.AdapterError>(maintenanceError);
|
||||
|
||||
// https://emberjs.com/api/ember-data/2.16/classes/DS.InvalidError
|
||||
const anInvalidError = new DS.InvalidError([
|
||||
{
|
||||
detail: 'Must be unique',
|
||||
source: { pointer: '/data/attributes/title' },
|
||||
},
|
||||
{
|
||||
detail: 'Must not be blank',
|
||||
source: { pointer: '/data/attributes/content' },
|
||||
},
|
||||
]);
|
||||
|
||||
// https://emberjs.com/api/ember-data/2.16/classes/DS.TimeoutError
|
||||
const { TimeoutError } = DS;
|
||||
const timedOut = Ember.Route.extend({
|
||||
actions: {
|
||||
error(error: any, transition: any) {
|
||||
if (error instanceof TimeoutError) {
|
||||
// alert the user
|
||||
alert('Are you still connected to the internet?');
|
||||
return;
|
||||
}
|
||||
|
||||
// ...other error handling logic
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// This is technically private, but publicly exposed for APIs to use. We just
|
||||
// check that it is a proper subclass of `AdapterError`.
|
||||
// https://emberjs.com/api/ember-data/2.16/classes/DS.AbortError
|
||||
// https://github.com/emberjs/data/blob/v2.16.0/addon/-private/adapters/errors.js#L206-L216
|
||||
const { AbortError } = DS;
|
||||
assertType<typeof AdapterError>(AbortError);
|
||||
|
||||
// https://emberjs.com/api/ember-data/2.16/classes/DS.UnauthorizedError
|
||||
const { UnauthorizedError } = DS;
|
||||
assertType<typeof AdapterError>(UnauthorizedError);
|
||||
const unauthorized = Ember.Route.extend({
|
||||
actions: {
|
||||
error(error: any, transition: any) {
|
||||
if (error instanceof UnauthorizedError) {
|
||||
// go to the sign in route
|
||||
this.transitionTo('login');
|
||||
return;
|
||||
}
|
||||
|
||||
// ...other error handling logic
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// This is technically private, but publicly exposed for APIs to use. We just
|
||||
// check that it is a proper subclass of `AdapterError`.
|
||||
// https://emberjs.com/api/ember-data/2.16/classes/DS.ForbiddenError
|
||||
// https://github.com/emberjs/data/blob/v2.16.0/addon/-private/adapters/errors.js#L253-L263
|
||||
const { ForbiddenError } = DS;
|
||||
assertType<typeof AdapterError>(ForbiddenError);
|
||||
|
||||
// https://emberjs.com/api/ember-data/2.16/classes/DS.NotFoundError
|
||||
const { NotFoundError } = DS;
|
||||
assertType<typeof AdapterError>(NotFoundError);
|
||||
const notFound = Ember.Route.extend({
|
||||
model(params: { post_id: string }): any {
|
||||
return this.get('store').findRecord('post', params.post_id);
|
||||
},
|
||||
|
||||
actions: {
|
||||
error(error: any, transition: any): any {
|
||||
if (error instanceof NotFoundError) {
|
||||
// redirect to a list of all posts instead
|
||||
this.transitionTo('posts');
|
||||
} else {
|
||||
// otherwise let the error bubble
|
||||
return true;
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// This is technically private, but publicly exposed for APIs to use. We just
|
||||
// check that it is a proper subclass of `AdapterError`.
|
||||
// https://emberjs.com/api/ember-data/2.16/classes/DS.ConflictError
|
||||
// https://github.com/emberjs/data/blob/v2.16.0/addon/-private/adapters/errors.js#L303-L313
|
||||
const { ConflictError } = DS;
|
||||
assertType<typeof AdapterError>(ConflictError);
|
||||
|
||||
// This is technically private, but publicly exposed for APIs to use. We just
|
||||
// check that it is a proper subclass of `AdapterError`.
|
||||
// https://emberjs.com/api/ember-data/2.16/classes/DS.ServerError
|
||||
// https://github.com/emberjs/data/blob/v2.16.0/addon/-private/adapters/errors.js#L315-L323
|
||||
const { ServerError } = DS;
|
||||
assertType<typeof AdapterError>(ServerError);
|
||||
@@ -0,0 +1,61 @@
|
||||
import Ember from 'ember';
|
||||
import DS from 'ember-data';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
class BlogComment extends DS.Model {
|
||||
text = DS.attr('string');
|
||||
}
|
||||
|
||||
declare module 'ember-data' {
|
||||
interface ModelRegistry {
|
||||
'blog-comment': BlogComment;
|
||||
}
|
||||
}
|
||||
|
||||
class BlogPost extends DS.Model {
|
||||
title = DS.attr('string');
|
||||
commentsAsync = DS.hasMany('blog-comment');
|
||||
commentsSync = DS.hasMany('blog-comment', { async: false });
|
||||
}
|
||||
|
||||
const blogPost = BlogPost.create();
|
||||
|
||||
assertType<DS.PromiseArray<BlogComment>>(blogPost.get('commentsSync').reload());
|
||||
assertType<BlogComment>(blogPost.get('commentsSync').createRecord());
|
||||
|
||||
const comment = blogPost.get('commentsSync').get('firstObject');
|
||||
assertType<BlogComment | undefined>(comment);
|
||||
if (comment) {
|
||||
assertType<string>(comment.get('text'));
|
||||
}
|
||||
|
||||
assertType<DS.PromiseArray<BlogComment>>(blogPost.get('commentsAsync').reload());
|
||||
assertType<BlogComment>(blogPost.get('commentsAsync').createRecord());
|
||||
assertType<BlogComment | undefined>(blogPost.get('commentsAsync').get('firstObject'));
|
||||
|
||||
const commentAsync = blogPost.get('commentsAsync').get('firstObject');
|
||||
assertType<BlogComment | undefined>(commentAsync);
|
||||
if (commentAsync) {
|
||||
assertType<string>(commentAsync.get('text'));
|
||||
}
|
||||
assertType<boolean>(blogPost.get('commentsAsync').get('isFulfilled'));
|
||||
|
||||
blogPost.get('commentsAsync').then(comments => {
|
||||
assertType<BlogComment | undefined>(comments.get('firstObject'));
|
||||
assertType<string>(comments.get('firstObject')!.get('text'));
|
||||
});
|
||||
|
||||
blogPost.set('commentsAsync', blogPost.get('commentsAsync'));
|
||||
blogPost.set('commentsAsync', Ember.A());
|
||||
blogPost.set('commentsAsync', Ember.A([ comment! ]));
|
||||
|
||||
class PaymentMethod extends DS.Model {}
|
||||
declare module 'ember-data' {
|
||||
interface ModelRegistry {
|
||||
'payment-method': PaymentMethod;
|
||||
}
|
||||
}
|
||||
|
||||
class Polymorphic extends DS.Model {
|
||||
paymentMethods = DS.hasMany('payment-method', { polymorphic: true });
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import Ember from 'ember';
|
||||
import DS from 'ember-data';
|
||||
|
||||
class MyModel extends DS.Model {}
|
||||
|
||||
declare module 'ember-data' {
|
||||
interface ModelRegistry {
|
||||
'my-model': MyModel;
|
||||
}
|
||||
}
|
||||
|
||||
Ember.Route.extend({
|
||||
model(): any {
|
||||
return this.store.findAll('my-model');
|
||||
}
|
||||
});
|
||||
|
||||
Ember.Controller.extend({
|
||||
actions: {
|
||||
create(): any {
|
||||
return this.store.createRecord('my-model');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Ember.DataAdapter.extend({
|
||||
test() {
|
||||
this.store.findRecord('my-model', 123);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,2 @@
|
||||
/** Static assertion that `value` has type `T` */
|
||||
export declare function assertType<T>(value: T): void;
|
||||
@@ -0,0 +1,37 @@
|
||||
import Ember from 'ember';
|
||||
import DS, { ChangedAttributes } from 'ember-data';
|
||||
import { assertType } from "./lib/assert";
|
||||
|
||||
const Person = DS.Model.extend({
|
||||
firstName: DS.attr(),
|
||||
lastName: DS.attr(),
|
||||
title: DS.attr({ defaultValue: "The default" }),
|
||||
title2: DS.attr({ defaultValue: () => "The default" }),
|
||||
|
||||
fullName: Ember.computed('firstName', 'lastName', function() {
|
||||
return `${this.get('firstName')} ${this.get('lastName')}`;
|
||||
})
|
||||
});
|
||||
|
||||
const User = DS.Model.extend({
|
||||
username: DS.attr('string'),
|
||||
email: DS.attr('string'),
|
||||
verified: DS.attr('boolean', { defaultValue: false }),
|
||||
canBeNull: DS.attr('boolean', { allowNull: true }),
|
||||
createdAt: DS.attr('date', {
|
||||
defaultValue() { return new Date(); }
|
||||
})
|
||||
});
|
||||
|
||||
const user = User.create({ username: 'dwickern' });
|
||||
assertType<string>(user.get('id'));
|
||||
assertType<string>(user.get('username'));
|
||||
assertType<boolean>(user.get('verified'));
|
||||
assertType<Date>(user.get('createdAt'));
|
||||
|
||||
user.serialize();
|
||||
user.serialize({ includeId: true });
|
||||
user.serialize({ includeId: true });
|
||||
|
||||
const attributes = user.changedAttributes();
|
||||
assertType<ChangedAttributes>(attributes);
|
||||
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Tests for the Ember-Data "module API" introduced in v2.3
|
||||
* @see https://www.emberjs.com/blog/2016/01/12/ember-data-2-3-released.html#toc_importing-modules
|
||||
*/
|
||||
import DS from 'ember-data';
|
||||
// Adapters
|
||||
import Adapter from 'ember-data/adapter';
|
||||
import JSONAPIAdapter from 'ember-data/adapters/json-api';
|
||||
import RESTAdapter from 'ember-data/adapters/rest';
|
||||
// Serializers
|
||||
import Serializer from 'ember-data/serializer';
|
||||
import RESTSerializer from 'ember-data/serializers/rest';
|
||||
import JSONSerializer from 'ember-data/serializers/json';
|
||||
import JSONAPISerializer from 'ember-data/serializers/json-api';
|
||||
|
||||
// Model
|
||||
import Model from 'ember-data/model';
|
||||
// Model - attr
|
||||
import attr from 'ember-data/attr';
|
||||
// Model - relationships
|
||||
import { hasMany, belongsTo } from 'ember-data/relationships';
|
||||
|
||||
// Transforms
|
||||
import BooleanTransform from 'ember-data/transforms/boolean';
|
||||
import StringTransform from 'ember-data/transforms/string';
|
||||
import NumberTransform from 'ember-data/transforms/number';
|
||||
import DateTransform from 'ember-data/transforms/date';
|
||||
import Transform from 'ember-data/transforms/transform';
|
||||
|
||||
// Store
|
||||
import Store from 'ember-data/store';
|
||||
|
||||
// Errors
|
||||
import * as EDErrors from 'ember-data/adapters/errors';
|
||||
|
||||
import { assertType } from "./lib/assert";
|
||||
|
||||
// ADAPTERS
|
||||
// - identity
|
||||
assertType<typeof DS.Adapter>(Adapter);
|
||||
assertType<typeof DS.RESTAdapter>(RESTAdapter);
|
||||
assertType<typeof DS.JSONAPIAdapter>(JSONAPIAdapter);
|
||||
// - inheritance
|
||||
assertType<typeof DS.Adapter>(RESTAdapter);
|
||||
assertType<typeof DS.RESTAdapter>(JSONAPIAdapter);
|
||||
|
||||
// SERIALIZERS
|
||||
// - identity
|
||||
assertType<typeof DS.Serializer>(Serializer);
|
||||
assertType<typeof DS.RESTSerializer>(RESTSerializer);
|
||||
assertType<typeof DS.JSONSerializer>(JSONSerializer);
|
||||
assertType<typeof DS.JSONAPISerializer>(JSONAPISerializer);
|
||||
// - inheritance
|
||||
assertType<typeof DS.Serializer>(JSONSerializer);
|
||||
assertType<typeof DS.JSONSerializer>(RESTSerializer);
|
||||
assertType<typeof DS.JSONSerializer>(JSONAPISerializer);
|
||||
|
||||
// MODEL
|
||||
// - identity
|
||||
assertType<typeof DS.Model>(Model);
|
||||
// - attributes
|
||||
assertType<typeof DS.attr>(attr);
|
||||
// - relationships
|
||||
assertType<typeof DS.hasMany>(hasMany);
|
||||
assertType<typeof DS.belongsTo>(belongsTo);
|
||||
|
||||
// TRANSFORMS
|
||||
// - identity
|
||||
assertType<typeof DS.BooleanTransform>(BooleanTransform);
|
||||
assertType<typeof DS.NumberTransform>(NumberTransform);
|
||||
assertType<typeof DS.StringTransform>(StringTransform);
|
||||
assertType<typeof DS.DateTransform>(DateTransform);
|
||||
assertType<typeof DS.Transform>(Transform);
|
||||
|
||||
// STORE
|
||||
// - identity
|
||||
assertType<typeof DS.Store>(Store);
|
||||
|
||||
// ERRORS
|
||||
// - identity
|
||||
assertType<typeof DS.AdapterError>(EDErrors.AdapterError);
|
||||
assertType<typeof DS.InvalidError>(EDErrors.InvalidError);
|
||||
assertType<typeof DS.UnauthorizedError>(EDErrors.UnauthorizedError);
|
||||
assertType<typeof DS.ForbiddenError>(EDErrors.ForbiddenError);
|
||||
assertType<typeof DS.NotFoundError>(EDErrors.NotFoundError);
|
||||
assertType<typeof DS.ConflictError>(EDErrors.ConflictError);
|
||||
assertType<typeof DS.ServerError>(EDErrors.ServerError);
|
||||
assertType<typeof DS.TimeoutError>(EDErrors.TimeoutError);
|
||||
assertType<typeof DS.AbortError>(EDErrors.AbortError);
|
||||
assertType<typeof DS.errorsHashToArray>(EDErrors.errorsHashToArray);
|
||||
assertType<typeof DS.errorsArrayToHash>(EDErrors.errorsArrayToHash);
|
||||
@@ -0,0 +1,44 @@
|
||||
import DS from 'ember-data';
|
||||
import { assertType } from "./lib/assert";
|
||||
|
||||
declare const store: DS.Store;
|
||||
|
||||
class User extends DS.Model {
|
||||
username = DS.attr('string');
|
||||
}
|
||||
|
||||
declare module 'ember-data' {
|
||||
interface ModelRegistry {
|
||||
user: User;
|
||||
}
|
||||
}
|
||||
|
||||
let userRef = store.getReference('user', 1);
|
||||
|
||||
// get the record of the reference (null if not yet available)
|
||||
let user = userRef.value();
|
||||
if (user !== null) {
|
||||
assertType<User>(user);
|
||||
}
|
||||
|
||||
// get the identifier of the reference
|
||||
if (userRef.remoteType() === 'id') {
|
||||
let id = userRef.id();
|
||||
assertType<string>(id);
|
||||
}
|
||||
|
||||
// load user (via store.find)
|
||||
userRef.load().then(user => {
|
||||
assertType<User>(user);
|
||||
});
|
||||
|
||||
// or trigger a reload
|
||||
userRef.reload().then(user => {
|
||||
assertType<User>(user);
|
||||
});
|
||||
|
||||
// provide data for reference
|
||||
userRef.push({ id: 1, username: '@user' }).then(function(user) {
|
||||
assertType<User>(user);
|
||||
userRef.value() === user;
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
import Ember from 'ember';
|
||||
import DS from 'ember-data';
|
||||
|
||||
declare const store: DS.Store;
|
||||
|
||||
const Person = DS.Model.extend({
|
||||
children: DS.hasMany('folder', { inverse: 'parent' }),
|
||||
parent: DS.belongsTo('folder', { inverse: 'children' })
|
||||
});
|
||||
|
||||
const Polymorphic = DS.Model.extend({
|
||||
paymentMethods: DS.hasMany('payment-method', { polymorphic: true })
|
||||
});
|
||||
|
||||
Polymorphic.eachRelationship(() => '');
|
||||
Polymorphic.eachRelationship(() => '', {});
|
||||
Polymorphic.eachRelationship((n, meta) => {
|
||||
let s: string = n;
|
||||
let m: 'belongsTo' | 'hasMany' = meta.kind;
|
||||
});
|
||||
let p = Polymorphic.create();
|
||||
p.eachRelationship(() => '');
|
||||
p.eachRelationship(() => '', {});
|
||||
p.eachRelationship((n, meta) => {
|
||||
let s: string = n;
|
||||
let m: 'belongsTo' | 'hasMany' = meta.kind;
|
||||
});
|
||||
|
||||
class Comment extends DS.Model {
|
||||
author = DS.attr('string');
|
||||
}
|
||||
|
||||
class Series extends DS.Model {
|
||||
title = DS.attr('string');
|
||||
}
|
||||
|
||||
class RelationalPost extends DS.Model {
|
||||
title = DS.attr('string');
|
||||
tag = DS.attr('string');
|
||||
comments = DS.hasMany('comment', { async: true });
|
||||
relatedPosts = DS.hasMany('post');
|
||||
series = DS.belongsTo('series');
|
||||
}
|
||||
|
||||
declare module 'ember-data' {
|
||||
interface ModelRegistry {
|
||||
'relational-post': RelationalPost;
|
||||
comment: Comment;
|
||||
series: Series;
|
||||
}
|
||||
}
|
||||
|
||||
let blogPost = store.peekRecord('relational-post', 1);
|
||||
blogPost!.get('comments').then((comments) => {
|
||||
// now we can work with the comments
|
||||
let author: string = comments.get('firstObject')!.get('author');
|
||||
});
|
||||
|
||||
blogPost!.hasMany('relatedPosts');
|
||||
blogPost!.belongsTo('series');
|
||||
@@ -0,0 +1,95 @@
|
||||
import Ember from 'ember';
|
||||
import DS from 'ember-data';
|
||||
|
||||
const JsonApi = DS.JSONAPISerializer.extend({});
|
||||
|
||||
const Customized = DS.JSONAPISerializer.extend({
|
||||
serialize(snapshot: DS.Snapshot<'user'>, options: {}) {
|
||||
const lookup = snapshot.belongsTo('username');
|
||||
let json: any = this._super(...Array.from(arguments));
|
||||
|
||||
json.data.attributes.cost = {
|
||||
amount: json.data.attributes.amount,
|
||||
currency: json.data.attributes.currency
|
||||
};
|
||||
|
||||
return json;
|
||||
},
|
||||
normalizeResponse(store: DS.Store, primaryModelClass: DS.Model, payload: any, id: string|number, requestType: string) {
|
||||
payload.data.attributes.amount = payload.data.attributes.cost.amount;
|
||||
payload.data.attributes.currency = payload.data.attributes.cost.currency;
|
||||
|
||||
delete payload.data.attributes.cost;
|
||||
|
||||
return this._super(...Array.from(arguments));
|
||||
}
|
||||
});
|
||||
|
||||
const EmbeddedRecordMixin = DS.JSONSerializer.extend(DS.EmbeddedRecordsMixin, {
|
||||
attrs: {
|
||||
author: {
|
||||
serialize: false,
|
||||
deserialize: 'records'
|
||||
},
|
||||
comments: {
|
||||
deserialize: 'records',
|
||||
serialize: 'ids'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
class Message extends DS.Model.extend({
|
||||
title: DS.attr(),
|
||||
body: DS.attr(),
|
||||
|
||||
author: DS.belongsTo('user'),
|
||||
comments: DS.belongsTo('comment')
|
||||
}) {}
|
||||
|
||||
declare module 'ember-data' {
|
||||
interface ModelRegistry {
|
||||
'message-for-serializer': Message;
|
||||
}
|
||||
}
|
||||
|
||||
interface CustomSerializerOptions {
|
||||
includeId: boolean;
|
||||
}
|
||||
|
||||
const SerializerUsingSnapshots = DS.RESTSerializer.extend({
|
||||
serialize(snapshot: DS.Snapshot<'message-for-serializer'>, options: CustomSerializerOptions) {
|
||||
let json: any = {
|
||||
POST_TTL: snapshot.attr('title'),
|
||||
POST_BDY: snapshot.attr('body'),
|
||||
POST_CMS: snapshot.hasMany('comments', { ids: true })
|
||||
};
|
||||
|
||||
if (options.includeId) {
|
||||
json.POST_ID_ = snapshot.id;
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
});
|
||||
|
||||
DS.Serializer.extend({
|
||||
serialize(snapshot: DS.Snapshot<'message-for-serializer'>, options: {}) {
|
||||
let json: any = {
|
||||
id: snapshot.id
|
||||
};
|
||||
|
||||
snapshot.eachAttribute((key, attribute) => {
|
||||
json[key] = snapshot.attr(key);
|
||||
});
|
||||
|
||||
snapshot.eachRelationship((key, relationship) => {
|
||||
if (relationship.kind === 'belongsTo') {
|
||||
json[key] = snapshot.belongsTo(key, { id: true });
|
||||
} else if (relationship.kind === 'hasMany') {
|
||||
json[key] = snapshot.hasMany(key, { ids: true });
|
||||
}
|
||||
});
|
||||
|
||||
return json;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,205 @@
|
||||
import Ember from 'ember';
|
||||
import DS from 'ember-data';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
declare const store: DS.Store;
|
||||
|
||||
class PostComment extends DS.Model {}
|
||||
class Post extends DS.Model {
|
||||
title = DS.attr('string');
|
||||
comments = DS.hasMany('comment');
|
||||
}
|
||||
|
||||
declare module 'ember-data' {
|
||||
interface ModelRegistry {
|
||||
'post': Post;
|
||||
'post-comment': PostComment;
|
||||
}
|
||||
}
|
||||
|
||||
let post = store.createRecord('post', {
|
||||
title: 'Rails is Omakase',
|
||||
body: 'Lorem ipsum',
|
||||
});
|
||||
|
||||
post.save(); // => POST to '/posts'
|
||||
post.save().then(saved => {
|
||||
assertType<Post>(saved);
|
||||
});
|
||||
|
||||
store.findRecord('post', 1).then(function(post) {
|
||||
post.get('title'); // => "Rails is Omakase"
|
||||
post.set('title', 'A new post');
|
||||
post.save(); // => PATCH to '/posts/1'
|
||||
});
|
||||
|
||||
class User extends DS.Model {
|
||||
username = DS.attr('string');
|
||||
}
|
||||
|
||||
class Author extends User {}
|
||||
|
||||
declare module 'ember-data' {
|
||||
interface ModelRegistry {
|
||||
'user': User;
|
||||
'author': Author;
|
||||
}
|
||||
}
|
||||
|
||||
store.queryRecord('user', {}).then(function(user) {
|
||||
let username = user.get('username');
|
||||
console.log(`Currently logged in as ${username}`);
|
||||
});
|
||||
|
||||
store.findAll('post'); // => GET /posts
|
||||
store.findAll('author', { reload: true }).then(function(authors) {
|
||||
authors.getEach('id'); // ['first', 'second']
|
||||
});
|
||||
store.findAll('post', {
|
||||
adapterOptions: { subscribe: false },
|
||||
});
|
||||
store.findAll('post', { include: 'comments,comments.author' });
|
||||
|
||||
store.peekAll('post'); // => no network request
|
||||
|
||||
if (store.hasRecordForId('post', 1)) {
|
||||
let maybePost = store.peekRecord('post', 1);
|
||||
if (maybePost) {
|
||||
maybePost.get('id'); // 1
|
||||
}
|
||||
}
|
||||
|
||||
class Message extends DS.Model {
|
||||
hasBeenSeen = DS.attr('boolean');
|
||||
}
|
||||
|
||||
declare module 'ember-data' {
|
||||
interface ModelRegistry {
|
||||
message: Message;
|
||||
}
|
||||
}
|
||||
|
||||
const messages = store.peekAll('message');
|
||||
messages.forEach(function(message) {
|
||||
message.set('hasBeenSeen', true);
|
||||
});
|
||||
messages.save();
|
||||
|
||||
const people = store.peekAll('user');
|
||||
people.get('isUpdating'); // false
|
||||
people.update().then(function() {
|
||||
people.get('isUpdating'); // false
|
||||
});
|
||||
people.get('isUpdating'); // true
|
||||
|
||||
const MyRoute = Ember.Route.extend({
|
||||
model(params: any): any {
|
||||
return this.store.findRecord('post', params.post_id, {
|
||||
include: 'comments,comments.author',
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// Store is injectable via `inject` and resolves to `DS.Store`.
|
||||
const SomeComponent = Ember.Component.extend({
|
||||
store: Ember.inject.service('store'),
|
||||
|
||||
lookUpUsers() {
|
||||
assertType<User>(this.get('store').findRecord('user', 123));
|
||||
assertType<DS.PromiseArray<User>>(this.get('store').findAll('user'));
|
||||
}
|
||||
});
|
||||
|
||||
const MyRouteAsync = Ember.Route.extend({
|
||||
async beforeModel(): Promise<Ember.Array<DS.Model>> {
|
||||
const store = Ember.get(this, 'store');
|
||||
return await store.findAll('post-comment');
|
||||
},
|
||||
async model(): Promise<DS.Model> {
|
||||
const store = this.get('store');
|
||||
return await store.findRecord('post-comment', 1);
|
||||
},
|
||||
async afterModel(): Promise<Ember.Array<PostComment>> {
|
||||
const post = await this.get('store').findRecord('post', 1);
|
||||
return await post.get('comments');
|
||||
}
|
||||
});
|
||||
|
||||
class MyRouteAsyncES6 extends Ember.Route {
|
||||
async beforeModel(): Promise<Ember.Array<DS.Model>> {
|
||||
return await this.store.findAll('post-comment');
|
||||
}
|
||||
async model(): Promise<DS.Model> {
|
||||
return await this.store.findRecord('post-comment', 1);
|
||||
}
|
||||
async afterModel(): Promise<Ember.Array<PostComment>> {
|
||||
const post = await this.store.findRecord('post', 1);
|
||||
return await post.get('comments');
|
||||
}
|
||||
}
|
||||
|
||||
// GET to /users?filter[email]=tomster@example.com
|
||||
const tom = store
|
||||
.query('user', {
|
||||
filter: {
|
||||
email: 'tomster@example.com',
|
||||
},
|
||||
})
|
||||
.then(function(users) {
|
||||
return users.get('firstObject');
|
||||
});
|
||||
|
||||
// GET /users?isAdmin=true
|
||||
const admins = store.query('user', { isAdmin: true });
|
||||
admins.then(function() {
|
||||
console.log(admins.get('length')); // 42
|
||||
});
|
||||
admins.update().then(function() {
|
||||
admins.get('isUpdating'); // false
|
||||
console.log(admins.get('length')); // 123
|
||||
});
|
||||
|
||||
store.push({
|
||||
data: [
|
||||
{
|
||||
id: 1,
|
||||
type: 'album',
|
||||
attributes: {
|
||||
title: 'Fewer Moving Parts',
|
||||
artist: 'David Bazan',
|
||||
songCount: 10,
|
||||
},
|
||||
relationships: {},
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
type: 'album',
|
||||
attributes: {
|
||||
title: "Calgary b/w I Can't Make You Love Me/Nick Of Time",
|
||||
artist: 'Bon Iver',
|
||||
songCount: 2,
|
||||
},
|
||||
relationships: {},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
class UserAdapter extends DS.Adapter {
|
||||
thisAdapterOnlyMethod(): void {}
|
||||
}
|
||||
class UserSerializer extends DS.Serializer {
|
||||
thisSerializerOnlyMethod(): void {}
|
||||
}
|
||||
|
||||
declare module 'ember-data' {
|
||||
interface AdapterRegistry {
|
||||
user: UserAdapter;
|
||||
}
|
||||
|
||||
interface SerializerRegistry {
|
||||
user: UserSerializer;
|
||||
}
|
||||
}
|
||||
|
||||
assertType<UserAdapter>(store.adapterFor('user'));
|
||||
assertType<UserSerializer>(store.serializerFor('user'));
|
||||
@@ -0,0 +1,16 @@
|
||||
import Ember from 'ember';
|
||||
import DS from 'ember-data';
|
||||
|
||||
class Point extends Ember.Object {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
const PointTransform = DS.Transform.extend({
|
||||
serialize(value: Point): number[] {
|
||||
return [value.get('x'), value.get('y')];
|
||||
},
|
||||
deserialize(value: [ number, number ]): Point {
|
||||
return Point.create({ x: value[0], y: value[1] });
|
||||
}
|
||||
});
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import DS from 'ember-data';
|
||||
export default DS.Transform;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import DS from 'ember-data';
|
||||
|
||||
export default DS.BooleanTransform;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import DS from 'ember-data';
|
||||
|
||||
export default DS.DateTransform;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import DS from 'ember-data';
|
||||
|
||||
export default DS.NumberTransform;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import DS from 'ember-data';
|
||||
|
||||
export default DS.StringTransform;
|
||||
@@ -0,0 +1,3 @@
|
||||
import DS from 'ember-data';
|
||||
|
||||
export default DS.Transform;
|
||||
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6",
|
||||
"dom"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": false,
|
||||
"baseUrl": "../../",
|
||||
"typeRoots": [
|
||||
"../../"
|
||||
],
|
||||
"paths": {
|
||||
"ember": ["ember/v2"],
|
||||
"ember-data": ["ember-data/v2"],
|
||||
"ember-data/*": ["ember-data/v2/*"]
|
||||
},
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"adapter.d.ts",
|
||||
"serializer.d.ts",
|
||||
"model.d.ts",
|
||||
"attr.d.ts",
|
||||
"relationships.d.ts",
|
||||
"store.d.ts",
|
||||
"transform.d.ts",
|
||||
"adapters/errors.d.ts",
|
||||
"adapters/rest.d.ts",
|
||||
"adapters/json-api.d.ts",
|
||||
"serializers/json-api.d.ts",
|
||||
"serializers/json.d.ts",
|
||||
"serializers/rest.d.ts",
|
||||
"serializers/embedded-records-mixin.d.ts",
|
||||
"transforms/transform.d.ts",
|
||||
"transforms/date.d.ts",
|
||||
"transforms/boolean.d.ts",
|
||||
"transforms/string.d.ts",
|
||||
"transforms/number.d.ts",
|
||||
"test/lib/assert.ts",
|
||||
"test/model.ts",
|
||||
"test/module-api.ts",
|
||||
"test/adapter.ts",
|
||||
"test/serializer.ts",
|
||||
"test/transform.ts",
|
||||
"test/relationships.ts",
|
||||
"test/store.ts",
|
||||
"test/has-many.ts",
|
||||
"test/belongs-to.ts",
|
||||
"test/record-reference.ts",
|
||||
"test/injections.ts",
|
||||
"test/error.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "dtslint/dt.json",
|
||||
"rules": {
|
||||
"strict-export-declare-modifiers": false,
|
||||
// Heavy use of Function type in this older package.
|
||||
"ban-types": false,
|
||||
"jsdoc-format": false,
|
||||
"no-misused-new": false,
|
||||
// not sure what this means
|
||||
"no-single-declare-module": false,
|
||||
"object-literal-key-quotes": false,
|
||||
"only-arrow-functions": false,
|
||||
"no-empty-interface": false,
|
||||
"prefer-const": false,
|
||||
"no-unnecessary-generics": false,
|
||||
"no-declare-current-package": false,
|
||||
"no-self-import": false,
|
||||
"no-return-await": false // used in tests
|
||||
}
|
||||
}
|
||||
Vendored
+3
-2
@@ -1,8 +1,9 @@
|
||||
// Type definitions for ember-feature-flags 3.0
|
||||
// Type definitions for ember-feature-flags 4.0
|
||||
// Project: https://github.com/kategengler/ember-feature-flags#readme
|
||||
// Definitions by: Frank Tan <https://github.com/tansongyang>
|
||||
// Mike North <https://github.com/mike-north>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
// TypeScript Version: 2.8
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import Features from 'ember-feature-flags';
|
||||
import 'ember-feature-flags/tests/helpers/with-feature';
|
||||
|
||||
/** Static assertion that `value` has type `T` */
|
||||
// Disable tslint here b/c the generic is used to let us do a type coercion and
|
||||
// validate that coercion works for the type value "passed into" the function.
|
||||
// tslint:disable-next-line:no-unnecessary-generics
|
||||
export declare function assertType<T>(value: T): void;
|
||||
|
||||
declare module 'ember-feature-flags' {
|
||||
export default interface Features {
|
||||
someFeature: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.npmjs.com/package/ember-feature-flags#withfeature
|
||||
declare var features: Features;
|
||||
features.isEnabled('new-billing-plans'); // $ExpectType boolean
|
||||
features.enable('newHomepage'); // $ExpectType void
|
||||
features.disable('newHomepage'); // $ExpectType void
|
||||
const setup = {
|
||||
'new-billing-plans': true,
|
||||
'new-homepage': false
|
||||
};
|
||||
features.setup(setup); // $ExpectType void
|
||||
withFeature('new-homepage'); // $ExpectType void
|
||||
assertType<boolean>(features.get('someFeature'));
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// Type definitions for ember-feature-flags 3.0
|
||||
// Project: https://github.com/kategengler/ember-feature-flags#readme
|
||||
// Definitions by: Frank Tan <https://github.com/tansongyang>
|
||||
// Mike North <https://github.com/mike-north>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
// https://github.com/kategengler/ember-feature-flags/blob/v3.0.0/addon/services/features.js#L5
|
||||
export default interface Features extends Ember.Service {
|
||||
setup(features: { [key: string]: boolean }): void;
|
||||
enable(feature: string): void;
|
||||
disable(feature: string): void;
|
||||
isEnabled(feature: string): boolean;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
// https://www.npmjs.com/package/ember-feature-flags#withfeature
|
||||
// https://github.com/kategengler/ember-feature-flags/blob/v3.0.0/test-support/helpers/with-feature.js#L3
|
||||
declare function withFeature(name: string): void;
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6",
|
||||
"dom"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": false,
|
||||
"baseUrl": "../../",
|
||||
"typeRoots": [
|
||||
"../../"
|
||||
],
|
||||
"paths": {
|
||||
"ember": ["ember/v2"],
|
||||
"ember-feature-flags": ["ember-feature-flags/v3"]
|
||||
},
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"tests/helpers/with-feature.d.ts",
|
||||
"ember-feature-flags-tests.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "dtslint/dt.json",
|
||||
"rules": {
|
||||
"strict-export-declare-modifiers": false
|
||||
}
|
||||
}
|
||||
Vendored
+2
-1
@@ -2,8 +2,9 @@
|
||||
// Project: https://github.com/emberjs/ember-mocha#readme
|
||||
// Definitions by: Derek Wickern <https://github.com/dwickern>
|
||||
// Simon Ihmig <https://github.com/simonihmig>
|
||||
// Mike North <https://github.com/mike-north>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
// TypeScript Version: 2.8
|
||||
|
||||
import { TestContext, ModuleCallbacks } from "ember-test-helpers";
|
||||
import Ember from 'ember';
|
||||
|
||||
Vendored
+3
-2
@@ -1,8 +1,9 @@
|
||||
// Type definitions for ember-modal-dialog 2.4
|
||||
// Type definitions for ember-modal-dialog 3.0
|
||||
// Project: https://github.com/yapplabs/ember-modal-dialog#readme
|
||||
// Definitions by: Frank Tan <https://github.com/tansongyang>
|
||||
// Mike North <https://github.com/mike-north>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
// TypeScript Version: 2.8
|
||||
|
||||
declare module 'ember-modal-dialog/components/modal-dialog' {
|
||||
import Ember from 'ember';
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import ModalDialog from 'ember-modal-dialog/components/modal-dialog';
|
||||
|
||||
class MyDialog extends ModalDialog {
|
||||
// https://www.npmjs.com/package/ember-modal-dialog#configurable-properties
|
||||
testProperties() {
|
||||
this.hasOverlay; // $ExpectType boolean
|
||||
this.translucentOverlay; // $ExpectType boolean
|
||||
this.onClose();
|
||||
this.onClickOverlay();
|
||||
this.clickOutsideToClose; // $ExpectType boolean
|
||||
this.renderInPlace; // $ExpectType boolean
|
||||
this.overlayPosition; // $ExpectType "parent" | "sibling"
|
||||
this.containerClass; // $ExpectType string
|
||||
this.containerClassNames; // $ExpectType string[]
|
||||
this.overlayClass; // $ExpectType string
|
||||
this.overlayClassNames; // $ExpectType string[]
|
||||
this.wrapperClass; // $ExpectType string
|
||||
this.wrapperClassNames; // $ExpectType string[]
|
||||
this.animatable; // $ExpectType boolean
|
||||
}
|
||||
}
|
||||
|
||||
class MyOtherDialog extends ModalDialog.extend({
|
||||
testProperties() {
|
||||
this.hasOverlay; // $ExpectType boolean
|
||||
}
|
||||
}) {}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
// Type definitions for ember-modal-dialog 2.4
|
||||
// Project: https://github.com/yapplabs/ember-modal-dialog#readme
|
||||
// Definitions by: Frank Tan <https://github.com/tansongyang>
|
||||
// Mike North <https://github.com/mike-north>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
|
||||
declare module 'ember-modal-dialog/components/modal-dialog' {
|
||||
import Ember from 'ember';
|
||||
|
||||
// https://github.com/yapplabs/ember-modal-dialog/blob/v2.4.1/addon/components/modal-dialog.js#L28
|
||||
// https://www.npmjs.com/package/ember-modal-dialog#configurable-properties
|
||||
export default class ModalDialog extends Ember.Component {
|
||||
/**
|
||||
* Toggles presence of overlay div in DOM
|
||||
*/
|
||||
hasOverlay: boolean;
|
||||
/**
|
||||
* Indicates translucence of overlay, toggles presence of translucent CSS
|
||||
* selector
|
||||
*/
|
||||
translucentOverlay: boolean;
|
||||
/**
|
||||
* The action handler for the dialog's onClose action. This action triggers
|
||||
* when the user clicks the modal overlay.
|
||||
*/
|
||||
onClose: () => void;
|
||||
/**
|
||||
* An action to be called when the overlay is clicked. If this action is
|
||||
* specified, clicking the overlay will invoke it instead of onClose.
|
||||
*/
|
||||
onClickOverlay: () => void;
|
||||
/**
|
||||
* Indicates whether clicking outside a modal without an overlay should
|
||||
* close the modal. Useful if your modal isn't the focus of interaction, and
|
||||
* you want hover effects to still work outside the modal.
|
||||
*/
|
||||
clickOutsideToClose: boolean;
|
||||
/**
|
||||
* A boolean, when true renders the modal without wormholing or tethering,
|
||||
* useful for including a modal in a style guide
|
||||
*/
|
||||
renderInPlace: boolean;
|
||||
/**
|
||||
* either 'parent' or 'sibling', to control whether the overlay div is
|
||||
* rendered as a parent element of the container div or as a sibling to it
|
||||
* (default: 'parent')
|
||||
*/
|
||||
overlayPosition: 'parent' | 'sibling';
|
||||
/**
|
||||
* CSS class name(s) to append to container divs. Set this from template.
|
||||
*/
|
||||
containerClass: string;
|
||||
/**
|
||||
* CSS class names to append to container divs. This is a concatenated
|
||||
* property, so it does not replace the default container class
|
||||
* (default: 'ember-modal-dialog'. If you subclass this component, you may
|
||||
* define this in your subclass.)
|
||||
*/
|
||||
containerClassNames: string[];
|
||||
/**
|
||||
* CSS class name(s) to append to overlay divs. Set this from template.
|
||||
*/
|
||||
overlayClass: string;
|
||||
/**
|
||||
* CSS class names to append to overlay divs. This is a concatenated
|
||||
* property, so it does not replace the default overlay class
|
||||
* (default: 'ember-modal-overlay'. If you subclass this component, you may
|
||||
* define this in your subclass.)
|
||||
*/
|
||||
overlayClassNames: string[];
|
||||
/**
|
||||
* CSS class name(s) to append to wrapper divs. Set this from template.
|
||||
*/
|
||||
wrapperClass: string;
|
||||
/**
|
||||
* CSS class names to append to wrapper divs. This is a concatenated
|
||||
* property, so it does not replace the default container class
|
||||
* (default: 'ember-modal-wrapper'. If you subclass this component, you may
|
||||
* define this in your subclass.)
|
||||
*/
|
||||
wrapperClassNames: string[];
|
||||
/**
|
||||
* A boolean, when true makes modal animatable using liquid-fire
|
||||
* (requires liquid-wormhole to be installed, and for tethering situations
|
||||
* liquid-tether. Having these optional dependencies installed and NOT
|
||||
* explicitly specifying animatable is deprecated in 2.x and is equivalent
|
||||
* to animatable=false for backwards compatibility. As of 3.x, the implicit
|
||||
* default will be animatable=true when the optional
|
||||
* liquid-wormhole/liquid-tether dependency is present.
|
||||
*/
|
||||
animatable: boolean;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6",
|
||||
"dom"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": false,
|
||||
"baseUrl": "../../",
|
||||
"typeRoots": [
|
||||
"../../"
|
||||
],
|
||||
"paths": {
|
||||
"ember-modal-dialog": ["ember-modal-dialog/v2"],
|
||||
"ember": ["ember/v2"]
|
||||
},
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"ember-modal-dialog-tests.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "dtslint/dt.json",
|
||||
"rules": {
|
||||
"no-single-declare-module": false,
|
||||
"no-declare-current-package": false,
|
||||
"strict-export-declare-modifiers": false
|
||||
}
|
||||
}
|
||||
Vendored
+3
-2
@@ -1,8 +1,9 @@
|
||||
// Type definitions for ember-qunit 3.0
|
||||
// Type definitions for ember-qunit 3.4
|
||||
// Project: https://github.com/emberjs/ember-qunit#readme
|
||||
// Definitions by: Derek Wickern <https://github.com/dwickern>
|
||||
// Mike North <https://github.com/mike-north>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
// TypeScript Version: 2.8
|
||||
|
||||
/// <reference types="qunit" />
|
||||
|
||||
|
||||
Vendored
+1
@@ -1,6 +1,7 @@
|
||||
// Type definitions for ember-qunit 2.2
|
||||
// Project: https://github.com/emberjs/ember-qunit#readme
|
||||
// Definitions by: Derek Wickern <https://github.com/dwickern>
|
||||
// Mike North <https://github.com/mike-north>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
"paths": {
|
||||
"ember-qunit": [
|
||||
"ember-qunit/v2"
|
||||
]
|
||||
],
|
||||
"ember": ["ember/v2"],
|
||||
"ember-test-helpers": ["ember-test-helpers/v0"]
|
||||
},
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
@@ -26,4 +28,4 @@
|
||||
"index.d.ts",
|
||||
"ember-qunit-tests.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+3
-2
@@ -1,8 +1,9 @@
|
||||
// Type definitions for ember-resolver 4.5
|
||||
// Type definitions for ember-resolver 5.0
|
||||
// Project: https://github.com/ember-cli/ember-resolver#readme
|
||||
// Definitions by: Dan Freeman <https://github.com/dfreeman>
|
||||
// Mike North <https://github.com/mike-north>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
// TypeScript Version: 2.8
|
||||
|
||||
/// <reference types="ember" />
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import Application from '@ember/application';
|
||||
import EmberResolver from 'ember-resolver';
|
||||
|
||||
const MyResolver = EmberResolver.extend({
|
||||
pluralizedTypes: {
|
||||
sheep: 'sheep'
|
||||
}
|
||||
});
|
||||
|
||||
const App = Application.extend({
|
||||
Resolver: MyResolver
|
||||
});
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
// Type definitions for ember-resolver 4.5
|
||||
// Project: https://github.com/ember-cli/ember-resolver#readme
|
||||
// Definitions by: Dan Freeman <https://github.com/dfreeman>
|
||||
// Mike North <https://github.com/mike-north>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
|
||||
/// <reference types="ember" />
|
||||
|
||||
import Resolver from '@ember/application/resolver';
|
||||
|
||||
/**
|
||||
* An Ember `Resolver` implementation used by ember-cli.
|
||||
*/
|
||||
export default class EmberResolver extends Resolver {}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"baseUrl": "../../",
|
||||
"typeRoots": [
|
||||
"../../"
|
||||
],
|
||||
"paths": {
|
||||
"ember": ["ember/v2"],
|
||||
"ember-resolver": ["ember-resolver/v4"]
|
||||
},
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"ember-resolver-tests.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{ "extends": "dtslint/dt.json" }
|
||||
Vendored
+11
-2
@@ -1,8 +1,17 @@
|
||||
// Type definitions for ember-test-helpers 0.7
|
||||
// Type definitions for ember-test-helpers 1.0
|
||||
// Project: https://github.com/emberjs/ember-test-helpers#readme
|
||||
// Definitions by: Derek Wickern <https://github.com/dwickern>
|
||||
// Mike North <https://github.com/mike-north>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
// TypeScript Version: 2.8
|
||||
|
||||
// NOTE: These types apply to ember-test-helper v0.7. The major
|
||||
// version had to be bumped for SemVer due to a breaking change
|
||||
// in TypeScript 3.1
|
||||
//
|
||||
// In the future, we'll use another versioning strategy that
|
||||
// provides safety from breaking changes without bumping the major
|
||||
// version number
|
||||
|
||||
/// <reference types="jquery" />
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/// <reference types="qunit" />
|
||||
import { ModuleCallbacks, TestContext, TestModule } from "ember-test-helpers";
|
||||
import wait from 'ember-test-helpers/wait';
|
||||
import hasEmberVersion from 'ember-test-helpers/has-ember-version';
|
||||
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
function moduleFor(name: string, description: string, callbacks: ModuleCallbacks) {
|
||||
const module = new TestModule(name, description, callbacks);
|
||||
|
||||
QUnit.module(module.name, {
|
||||
beforeEach() {
|
||||
module.setup();
|
||||
},
|
||||
afterEach() {
|
||||
module.teardown();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function testWait() {
|
||||
await wait();
|
||||
}
|
||||
|
||||
if (hasEmberVersion(2, 10)) {
|
||||
// ...
|
||||
}
|
||||
|
||||
// https://github.com/emberjs/ember-test-helpers/blob/f07e86914f2a3823c4cb6787307f9ba2bf447e68/tests/unit/setup-context-test.js
|
||||
QUnit.test('it sets up this.owner', function(this: TestContext, assert: Assert) {
|
||||
const { owner } = this;
|
||||
assert.ok(owner, 'owner was setup');
|
||||
assert.equal(typeof owner.lookup, 'function', 'has expected lookup interface');
|
||||
|
||||
if (hasEmberVersion(2, 12)) {
|
||||
assert.equal(typeof owner.factoryFor, 'function', 'has expected factory interface');
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('can pauseTest to be resumed "later"', async function(this: TestContext, assert: Assert) {
|
||||
const promise = this.pauseTest();
|
||||
|
||||
this.resumeTest();
|
||||
|
||||
await promise;
|
||||
});
|
||||
|
||||
// https://github.com/emberjs/ember-test-helpers/blob/fb4c8d4cd36b54728ce180227f865b1fa0162632/tests/unit/setup-rendering-context-test.js
|
||||
QUnit.test('render exposes an `.element` property', async function(this: TestContext, assert: Assert) {
|
||||
await this.render(hbs`<p>Hello!</p>`);
|
||||
|
||||
assert.equal(this.element.textContent, 'Hello!');
|
||||
});
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
// Type definitions for ember-test-helpers 0.7
|
||||
// Project: https://github.com/emberjs/ember-test-helpers#readme
|
||||
// Definitions by: Derek Wickern <https://github.com/dwickern>
|
||||
// Mike North <https://github.com/mike-north>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
|
||||
/// <reference types="jquery" />
|
||||
|
||||
declare module 'ember-test-helpers' {
|
||||
import Ember from 'ember';
|
||||
import { TemplateFactory } from 'htmlbars-inline-precompile';
|
||||
import RSVP from "rsvp";
|
||||
|
||||
interface ModuleCallbacks {
|
||||
integration?: boolean;
|
||||
unit?: boolean;
|
||||
needs?: string[];
|
||||
|
||||
beforeSetup?(assert?: any): void;
|
||||
setup?(assert?: any): void;
|
||||
teardown?(assert?: any): void;
|
||||
afterTeardown?(assert?: any): void;
|
||||
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface TestContext {
|
||||
get(key: string): any;
|
||||
getProperties<K extends string>(...keys: K[]): Pick<any, K>;
|
||||
set<V>(key: string, value: V): V;
|
||||
setProperties<P extends { [key: string]: any }>(hash: P): P;
|
||||
on(actionName: string, handler: (this: TestContext, ...args: any[]) => any): void;
|
||||
send(actionName: string): void;
|
||||
$: JQueryStatic;
|
||||
subject(options?: {}): any;
|
||||
render(template?: string | string[] | TemplateFactory): Promise<void>;
|
||||
clearRender(): void;
|
||||
registry: Ember.Registry;
|
||||
container: Ember.Container;
|
||||
dispatcher: Ember.EventDispatcher;
|
||||
application: Ember.Application;
|
||||
register(fullName: string, factory: any): void;
|
||||
factory(fullName: string): any;
|
||||
inject: {
|
||||
controller(name: string, options?: { as: string }): any;
|
||||
service(name: string, options?: { as: string }): any;
|
||||
};
|
||||
owner: Ember.ApplicationInstance & {
|
||||
factoryFor(fullName: string, options?: {}): any;
|
||||
};
|
||||
pauseTest(): Promise<void>;
|
||||
resumeTest(): void;
|
||||
element: Element;
|
||||
}
|
||||
|
||||
class TestModule {
|
||||
constructor(name: string, callbacks?: ModuleCallbacks);
|
||||
constructor(name: string, description?: string, callbacks?: ModuleCallbacks);
|
||||
|
||||
name: string;
|
||||
subjectName: string;
|
||||
description: string;
|
||||
isIntegration: boolean;
|
||||
callbacks: ModuleCallbacks;
|
||||
context: TestContext;
|
||||
resolver: Ember.Resolver;
|
||||
|
||||
setup(assert?: any): RSVP.Promise<void>;
|
||||
teardown(assert?: any): RSVP.Promise<void>;
|
||||
getContext(): TestContext;
|
||||
setContext(context: TestContext): void;
|
||||
}
|
||||
|
||||
class TestModuleForAcceptance extends TestModule {}
|
||||
class TestModuleForIntegration extends TestModule {}
|
||||
class TestModuleForComponent extends TestModule {}
|
||||
class TestModuleForModel extends TestModule {}
|
||||
|
||||
function getContext(): TestContext | undefined;
|
||||
function setContext(context: TestContext): void;
|
||||
function unsetContext(): void;
|
||||
function setResolver(resolver: Ember.Resolver): void;
|
||||
}
|
||||
|
||||
declare module 'ember-test-helpers/wait' {
|
||||
import RSVP from "rsvp";
|
||||
|
||||
interface WaitOptions {
|
||||
waitForTimers?: boolean;
|
||||
waitForAJAX?: boolean;
|
||||
waitForWaiters?: boolean;
|
||||
}
|
||||
|
||||
export default function wait(options?: WaitOptions): RSVP.Promise<void>;
|
||||
}
|
||||
|
||||
declare module 'ember-test-helpers/has-ember-version' {
|
||||
export default function hasEmberVersion(major: number, minor: number): boolean;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6",
|
||||
"dom"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": false,
|
||||
"baseUrl": "../../",
|
||||
"typeRoots": [
|
||||
"../../"
|
||||
],
|
||||
"paths": {
|
||||
"ember": ["ember/v2"],
|
||||
"ember-test-helpers": ["ember-test-helpers/v0"]
|
||||
},
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"ember-test-helpers-tests.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "dtslint/dt.json",
|
||||
"rules": {
|
||||
"strict-export-declare-modifiers": false,
|
||||
"no-duplicate-imports": false,
|
||||
"no-declare-current-package": false
|
||||
}
|
||||
}
|
||||
Vendored
+72
-72
@@ -1,4 +1,4 @@
|
||||
// Type definitions for Ember.js 2.8
|
||||
// Type definitions for Ember.js 3.0
|
||||
// Project: http://emberjs.com/
|
||||
// Definitions by: Jed Mao <https://github.com/jedmao>
|
||||
// bttf <https://github.com/bttf>
|
||||
@@ -9,7 +9,7 @@
|
||||
// Alex LaFroscia <https://github.com/alexlafroscia>
|
||||
// Mike North <https://github.com/mike-north>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
// TypeScript Version: 2.8
|
||||
|
||||
/// <reference types="jquery" />
|
||||
/// <reference types="handlebars" />
|
||||
@@ -30,8 +30,19 @@ declare module 'ember' {
|
||||
/**
|
||||
* Deconstructs computed properties into the types which would be returned by `.get()`.
|
||||
*/
|
||||
type ComputedPropertyGetters<T> = { [K in keyof T]: Ember.ComputedProperty<T[K], any> | ModuleComputed<T[K], any> | T[K] };
|
||||
type ComputedPropertySetters<T> = { [K in keyof T]: Ember.ComputedProperty<any, T[K]> | ModuleComputed<any, T[K]> | T[K] };
|
||||
type UnwrapComputedPropertyGetter<T> =
|
||||
T extends Ember.ComputedProperty<infer U, any> ? U :
|
||||
T;
|
||||
type UnwrapComputedPropertyGetters<T> = {
|
||||
[P in keyof T]: UnwrapComputedPropertyGetter<T[P]>;
|
||||
};
|
||||
|
||||
type UnwrapComputedPropertySetter<T> =
|
||||
T extends Ember.ComputedProperty<any, infer U> ? U :
|
||||
T;
|
||||
type UnwrapComputedPropertySetters<T> = {
|
||||
[P in keyof T]: UnwrapComputedPropertySetter<T[P]>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check that any arguments to `create()` match the type's properties.
|
||||
@@ -698,6 +709,10 @@ declare module 'ember' {
|
||||
This will force the cached result to be recomputed if the dependencies are modified.
|
||||
**/
|
||||
class ComputedProperty<Get, Set = Get> {
|
||||
// Necessary in order to avoid losing type information
|
||||
// see: https://github.com/typed-ember/ember-cli-typescript/issues/246#issuecomment-414812013
|
||||
private ______getType: Get;
|
||||
private ______setType: Set;
|
||||
/**
|
||||
* Call on a computed property to set it into non-cached mode. When in this
|
||||
* mode the computed property will not automatically cache the return value.
|
||||
@@ -833,36 +848,31 @@ declare module 'ember' {
|
||||
**/
|
||||
toString(): string;
|
||||
|
||||
static create<Instance>(this: EmberClassConstructor<Instance>): Fix<Instance>;
|
||||
static create<Class extends typeof Ember.CoreObject>(this: Class): InstanceType<Class>;
|
||||
|
||||
static create<Instance, Args, T1 extends EmberInstanceArguments<Args>>(
|
||||
this: EmberClassConstructor<Instance & ComputedPropertyGetters<Args>>,
|
||||
arg1: T1 & ThisType<Fix<T1 & Instance>>
|
||||
): Fix<Instance & T1>;
|
||||
static create<Class extends typeof Ember.CoreObject,
|
||||
T1 extends EmberInstanceArguments<UnwrapComputedPropertySetters<InstanceType<Class>>>
|
||||
>(this: Class,
|
||||
arg1: T1 & ThisType<T1 & InstanceType<Class>>
|
||||
): InstanceType<Class> & T1;
|
||||
|
||||
static create<
|
||||
Instance,
|
||||
Args,
|
||||
T1 extends EmberInstanceArguments<Args>,
|
||||
T2 extends EmberInstanceArguments<Args>
|
||||
>(
|
||||
this: EmberClassConstructor<Instance & ComputedPropertyGetters<Args>>,
|
||||
arg1: T1 & ThisType<Fix<Instance & T1>>,
|
||||
arg2: T2 & ThisType<Fix<Instance & T1 & T2>>
|
||||
): Fix<Instance & T1 & T2>;
|
||||
static create<Class extends typeof Ember.CoreObject,
|
||||
T1 extends EmberInstanceArguments<UnwrapComputedPropertySetters<InstanceType<Class>>>,
|
||||
T2 extends EmberInstanceArguments<UnwrapComputedPropertySetters<InstanceType<Class>>>
|
||||
>(this: Class,
|
||||
arg1: T1 & ThisType<T1 & InstanceType<Class>>,
|
||||
arg2: T2 & ThisType<T2 & InstanceType<Class>>
|
||||
): InstanceType<Class> & T1 & T2;
|
||||
|
||||
static create<
|
||||
Instance,
|
||||
Args,
|
||||
T1 extends EmberInstanceArguments<Args>,
|
||||
T2 extends EmberInstanceArguments<Args>,
|
||||
T3 extends EmberInstanceArguments<Args>
|
||||
>(
|
||||
this: EmberClassConstructor<Instance & ComputedPropertyGetters<Args>>,
|
||||
arg1: T1 & ThisType<Fix<Instance & T1>>,
|
||||
arg2: T2 & ThisType<Fix<Instance & T1 & T2>>,
|
||||
arg3: T3 & ThisType<Fix<Instance & T1 & T2 & T3>>
|
||||
): Fix<Instance & T1 & T2 & T3>;
|
||||
static create<Class extends typeof Ember.CoreObject,
|
||||
T1 extends EmberInstanceArguments<UnwrapComputedPropertySetters<InstanceType<Class>>>,
|
||||
T2 extends EmberInstanceArguments<UnwrapComputedPropertySetters<InstanceType<Class>>>,
|
||||
T3 extends EmberInstanceArguments<UnwrapComputedPropertySetters<InstanceType<Class>>>
|
||||
>(this: Class,
|
||||
arg1: T1 & ThisType<T1 & InstanceType<Class>>,
|
||||
arg2: T2 & ThisType<T2 & InstanceType<Class>>,
|
||||
arg3: T3 & ThisType<T3 & InstanceType<Class>>
|
||||
): InstanceType<Class> & T1 & T2 & T3;
|
||||
|
||||
static extend<Statics, Instance>(
|
||||
this: Statics & EmberClassConstructor<Instance>
|
||||
@@ -1677,29 +1687,27 @@ declare module 'ember' {
|
||||
/**
|
||||
* Retrieves the value of a property from the object.
|
||||
*/
|
||||
get<T, K extends keyof T>(this: ComputedPropertyGetters<T>, key: K): T[K];
|
||||
get<K extends keyof this>(key: K): UnwrapComputedPropertyGetter<this[K]>;
|
||||
/**
|
||||
* To get the values of multiple properties at once, call `getProperties`
|
||||
* with a list of strings or an array:
|
||||
*/
|
||||
getProperties<T, K extends keyof T>(this: ComputedPropertyGetters<T>, list: K[]): Pick<T, K>;
|
||||
getProperties<T, K extends keyof T>(
|
||||
this: ComputedPropertyGetters<T>,
|
||||
getProperties<K extends keyof this>(list: K[]): Pick< UnwrapComputedPropertyGetters<this>, K>;
|
||||
getProperties<K extends keyof this>(
|
||||
...list: K[]
|
||||
): Pick<T, K>;
|
||||
): Pick< UnwrapComputedPropertyGetters<this>, K>;
|
||||
/**
|
||||
* Sets the provided key or path to the value.
|
||||
*/
|
||||
set<T, K extends keyof T>(this: ComputedPropertySetters<T>, key: K, value: T[K]): T[K];
|
||||
set<K extends keyof this>(key: K, value: UnwrapComputedPropertySetter<this[K]>): UnwrapComputedPropertySetter<this[K]>;
|
||||
/**
|
||||
* Sets a list of properties at once. These properties are set inside
|
||||
* a single `beginPropertyChanges` and `endPropertyChanges` batch, so
|
||||
* observers will be buffered.
|
||||
*/
|
||||
setProperties<T, K extends keyof T>(
|
||||
this: ComputedPropertySetters<T>,
|
||||
hash: Pick<T, K>
|
||||
): Pick<T, K>;
|
||||
setProperties<K extends keyof this>(
|
||||
hash: Pick<UnwrapComputedPropertySetters<this>, K>
|
||||
): Pick< UnwrapComputedPropertySetters<this>, K>;
|
||||
/**
|
||||
* Convenience method to call `propertyWillChange` and `propertyDidChange` in
|
||||
* succession.
|
||||
@@ -1735,11 +1743,10 @@ declare module 'ember' {
|
||||
* Retrieves the value of a property, or a default value in the case that the
|
||||
* property returns `undefined`.
|
||||
*/
|
||||
getWithDefault<T, K extends keyof T>(
|
||||
this: ComputedPropertyGetters<T>,
|
||||
getWithDefault<K extends keyof this>(
|
||||
key: K,
|
||||
defaultValue: T[K]
|
||||
): T[K];
|
||||
defaultValue: UnwrapComputedPropertyGetter<this[K]>
|
||||
): UnwrapComputedPropertyGetter<this[K]>;
|
||||
/**
|
||||
* Set the value of a property to the current value plus some amount.
|
||||
*/
|
||||
@@ -1759,7 +1766,7 @@ declare module 'ember' {
|
||||
* without accidentally invoking it if it is intended to be
|
||||
* generated lazily.
|
||||
*/
|
||||
cacheFor<T, K extends keyof T>(this: ComputedPropertyGetters<T>, key: K): T[K] | undefined;
|
||||
cacheFor<K extends keyof this>(key: K): UnwrapComputedPropertyGetter<this[K]> | undefined;
|
||||
}
|
||||
const Observable: Mixin<Observable, Ember.CoreObject>;
|
||||
/**
|
||||
@@ -3046,9 +3053,9 @@ declare module 'ember' {
|
||||
* it to be created.
|
||||
*/
|
||||
function cacheFor<T, K extends keyof T>(
|
||||
obj: ComputedPropertyGetters<T>,
|
||||
obj: T,
|
||||
key: K
|
||||
): T[K] | undefined;
|
||||
): UnwrapComputedPropertyGetter<T[K]> | undefined;
|
||||
/**
|
||||
* Add an event listener
|
||||
*/
|
||||
@@ -3094,16 +3101,11 @@ declare module 'ember' {
|
||||
* To get multiple properties at once, call `Ember.getProperties`
|
||||
* with an object followed by a list of strings or an array:
|
||||
*/
|
||||
function getProperties<T, K extends keyof T>(obj: T, list: K[]): Pick<UnwrapComputedPropertyGetters<T>, K>; // for dynamic K
|
||||
function getProperties<T, K extends keyof T>(
|
||||
obj: ComputedPropertyGetters<T>,
|
||||
list: K[]
|
||||
): Pick<T, K>;
|
||||
function getProperties<T, K extends keyof T>(obj: T, list: K[]): Pick<T, K>; // for dynamic K
|
||||
function getProperties<T, K extends keyof T>(
|
||||
obj: ComputedPropertyGetters<T>,
|
||||
obj: T,
|
||||
...list: K[]
|
||||
): Pick<T, K>;
|
||||
function getProperties<T, K extends keyof T>(obj: T, ...list: K[]): Pick<T, K>; // for dynamic K
|
||||
): Pick<UnwrapComputedPropertyGetters<T>, K>;
|
||||
/**
|
||||
* A value is blank if it is empty or a whitespace string.
|
||||
*/
|
||||
@@ -3197,30 +3199,27 @@ declare module 'ember' {
|
||||
* the function will be invoked. If the property is not defined but the
|
||||
* object implements the `unknownProperty` method then that will be invoked.
|
||||
*/
|
||||
function get<T, K extends keyof T>(obj: ComputedPropertyGetters<T>, key: K): T[K];
|
||||
function get<T, K extends keyof T>(obj: T, key: K): T[K]; // for dynamic K
|
||||
function get<T, K extends keyof T>(obj: T, key: K): UnwrapComputedPropertyGetter<T[K]>;
|
||||
/**
|
||||
* Retrieves the value of a property from an Object, or a default value in the
|
||||
* case that the property returns `undefined`.
|
||||
*/
|
||||
function getWithDefault<T, K extends keyof T>(
|
||||
obj: ComputedPropertyGetters<T>,
|
||||
obj: T,
|
||||
key: K,
|
||||
defaultValue: T[K]
|
||||
): T[K];
|
||||
function getWithDefault<T, K extends keyof T>(obj: T, key: K, defaultValue: T[K]): T[K]; // for dynamic K
|
||||
defaultValue: UnwrapComputedPropertyGetter<T[K]>
|
||||
): UnwrapComputedPropertyGetter<T[K]>;
|
||||
/**
|
||||
* Sets the value of a property on an object, respecting computed properties
|
||||
* and notifying observers and other listeners of the change. If the
|
||||
* property is not defined but the object implements the `setUnknownProperty`
|
||||
* method then that will be invoked as well.
|
||||
*/
|
||||
function set<T, K extends keyof T, V extends T[K]>(
|
||||
obj: ComputedPropertySetters<T>,
|
||||
function set<T, K extends keyof T>(
|
||||
obj: T,
|
||||
key: K,
|
||||
value: V
|
||||
): V;
|
||||
function set<T, K extends keyof T, V extends T[K]>(obj: T, key: K, value: V): V; // for dynamic K
|
||||
value: UnwrapComputedPropertySetter<T[K]>
|
||||
): UnwrapComputedPropertyGetter<T[K]>;
|
||||
/**
|
||||
* Error-tolerant form of `Ember.set`. Will not blow up if any part of the
|
||||
* chain is `undefined`, `null`, or destroyed.
|
||||
@@ -3232,10 +3231,9 @@ declare module 'ember' {
|
||||
* observers will be buffered.
|
||||
*/
|
||||
function setProperties<T, K extends keyof T>(
|
||||
obj: ComputedPropertySetters<T>,
|
||||
hash: Pick<T, K>
|
||||
): Pick<T, K>;
|
||||
function setProperties<T, K extends keyof T>(obj: T, hash: Pick<T, K>): Pick<T, K>; // for dynamic K
|
||||
obj: T,
|
||||
hash: Pick<UnwrapComputedPropertySetters<T>, K>
|
||||
): Pick<UnwrapComputedPropertyGetters<T>, K>;
|
||||
/**
|
||||
* Detects when a specific package of Ember (e.g. 'Ember.Application')
|
||||
* has fully loaded and is available for extension.
|
||||
@@ -3674,7 +3672,9 @@ declare module '@ember/object' {
|
||||
|
||||
declare module '@ember/object/computed' {
|
||||
import Ember from 'ember';
|
||||
export default class ComputedProperty<Get, Set = Get> extends Ember.ComputedProperty<Get, Set> { }
|
||||
type ComputedProperty<Get, Set = Get> = Ember.ComputedProperty<Get, Set>;
|
||||
const ComputedProperty: typeof Ember.ComputedProperty;
|
||||
export default ComputedProperty;
|
||||
export const alias: typeof Ember.computed.alias;
|
||||
export const and: typeof Ember.computed.and;
|
||||
export const bool: typeof Ember.computed.bool;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import Ember from 'ember';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
class Foo extends Ember.Object {
|
||||
hello() { return 'world'; }
|
||||
protected bar() { return 'bar'; }
|
||||
private baz() { return 'baz'; }
|
||||
}
|
||||
const f = new Foo();
|
||||
assertType<string>(f.hello());
|
||||
assertType<string>(f.bar()); // $ExpectError
|
||||
assertType<string>(f.baz()); // $ExpectError
|
||||
|
||||
class Foo2 extends Ember.Object.extend({
|
||||
bar: ''
|
||||
}) {
|
||||
hello() { return 'world'; }
|
||||
protected bar() { return 'bar'; } // $ExpectError
|
||||
private baz() { return 'baz'; }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { assertType } from './lib/assert';
|
||||
import Ember from 'ember';
|
||||
import { PersonWithNumberName, Person } from './create';
|
||||
|
||||
Person.create({ firstName: 99 }); // $ExpectError
|
||||
Person.create({}, { firstName: 99 }); // $ExpectError
|
||||
Person.create({}, {}, { firstName: 99 }); // $ExpectError
|
||||
|
||||
const p4 = new PersonWithNumberName();
|
||||
|
||||
// assertType<Ember.ComputedProperty<string, string>>(p4.fullName); // $ExpectError
|
||||
@@ -1,7 +1,54 @@
|
||||
import Ember from 'ember';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
/**
|
||||
* Zero-argument case
|
||||
*/
|
||||
const o = Ember.Object.create();
|
||||
// create returns an object
|
||||
assertType<object>(o);
|
||||
// object returned by create type-checks as an instance of Ember.Object
|
||||
assertType<boolean>(o.isDestroyed); // from instance
|
||||
assertType<boolean>(o.isDestroying); // from instance
|
||||
assertType<(key: string) => any>(o.get); // from prototype
|
||||
|
||||
/**
|
||||
* One-argument case
|
||||
*/
|
||||
const o1 = Ember.Object.create({x: 9, y: 'hello', z: false});
|
||||
assertType<number>(o1.x);
|
||||
assertType<string>(o1.y);
|
||||
o1.y; // $ExpectType string
|
||||
o1.z; // $ExpectType boolean
|
||||
|
||||
const obj = Ember.Object.create({ a: 1 }, { b: 2 }, { c: 3 });
|
||||
assertType<number>(obj.a);
|
||||
assertType<number>(obj.b);
|
||||
assertType<number>(obj.a);
|
||||
assertType<number>(obj.c);
|
||||
|
||||
export class Person extends Ember.Object.extend({
|
||||
fullName: Ember.computed('firstName', 'lastName', function() {
|
||||
return [this.firstName + this.lastName].join(' ');
|
||||
})
|
||||
}) {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
age: number;
|
||||
}
|
||||
const p = new Person();
|
||||
|
||||
assertType<string>(p.firstName);
|
||||
assertType<Ember.ComputedProperty<string>>(p.fullName);
|
||||
assertType<string>(p.get('fullName'));
|
||||
|
||||
const p2 = Person.create({ firstName: 'string' });
|
||||
const p2b = Person.create({}, { firstName: 'string' });
|
||||
const p2c = Person.create({}, {}, { firstName: 'string' });
|
||||
|
||||
export class PersonWithNumberName extends Person.extend({
|
||||
fullName: 6
|
||||
}) {}
|
||||
|
||||
const p4 = new PersonWithNumberName();
|
||||
assertType<string>(p4.firstName);
|
||||
assertType<number>(p4.fullName);
|
||||
|
||||
@@ -29,6 +29,9 @@ assertType<string>(Person2.species);
|
||||
let tom = Person2.create({
|
||||
name: 'Tom Dale'
|
||||
});
|
||||
|
||||
let badTom = Person2.create({ name: 99 }); // $ExpectError
|
||||
|
||||
let yehuda = Person2.createPerson('Yehuda Katz');
|
||||
|
||||
tom.sayHello(); // "Hello. My name is Tom Dale"
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"index.d.ts",
|
||||
"test/lib/assert.ts",
|
||||
"test/application.ts",
|
||||
"test/access-modifier.ts",
|
||||
"test/application-instance.ts",
|
||||
"test/engine-instance.ts",
|
||||
"test/ember-tests.ts",
|
||||
@@ -29,6 +30,8 @@
|
||||
"test/event.ts",
|
||||
"test/extend.ts",
|
||||
"test/create.ts",
|
||||
"test/create-negative.ts",
|
||||
"test/create.ts",
|
||||
"test/object.ts",
|
||||
"test/observable.ts",
|
||||
"test/mixin.ts",
|
||||
|
||||
+3898
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
||||
import ApplicationInstance from '@ember/application/instance';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
const appInstance = ApplicationInstance.create();
|
||||
appInstance.register('some:injection', class Foo {});
|
||||
|
||||
appInstance.register('some:injection', class Foo {}, {
|
||||
singleton: true,
|
||||
});
|
||||
|
||||
appInstance.register('some:injection', class Foo {}, {
|
||||
instantiate: false,
|
||||
});
|
||||
|
||||
appInstance.register('templates:foo/bar', hbs`<h1>Hello World</h1>`);
|
||||
|
||||
appInstance.register('some:injection', class Foo {}, {
|
||||
singleton: false,
|
||||
instantiate: true,
|
||||
});
|
||||
|
||||
appInstance.factoryFor('router:main');
|
||||
appInstance.lookup('route:basic');
|
||||
|
||||
appInstance.boot();
|
||||
|
||||
(async function() {
|
||||
await appInstance.boot();
|
||||
}());
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
import Ember from 'ember';
|
||||
import { assertType } from "./lib/assert";
|
||||
|
||||
let BaseApp = Ember.Application.extend({
|
||||
modulePrefix: 'my-app'
|
||||
});
|
||||
|
||||
BaseApp.initializer({
|
||||
name: 'my-initializer',
|
||||
initialize(app) {
|
||||
app.register('foo:bar', Ember.Object.extend({ foo: 'bar' }));
|
||||
}
|
||||
});
|
||||
|
||||
BaseApp.instanceInitializer({
|
||||
name: 'my-instance-initializer',
|
||||
initialize(app) {
|
||||
app.lookup('foo:bar').get('foo');
|
||||
}
|
||||
});
|
||||
|
||||
let App1 = BaseApp.create({
|
||||
rootElement: '#app-one',
|
||||
customEvents: {
|
||||
paste: 'paste'
|
||||
}
|
||||
});
|
||||
|
||||
let App2 = BaseApp.create({
|
||||
rootElement: '#app-two',
|
||||
customEvents: {
|
||||
mouseenter: null,
|
||||
mouseleave: null
|
||||
}
|
||||
});
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
import Ember from 'ember';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
declare global {
|
||||
interface Array<T> extends Ember.ArrayPrototypeExtensions<T> {}
|
||||
}
|
||||
|
||||
class Person extends Ember.Object {
|
||||
name: string;
|
||||
}
|
||||
|
||||
const person = Person.create({ name: 'Joe' });
|
||||
const array = [person];
|
||||
|
||||
assertType<number>(array.get('length'));
|
||||
// This test must be disabled due to a breaking change in TS 3.1
|
||||
// see: https://github.com/Microsoft/TypeScript/issues/26120
|
||||
// https://github.com/typed-ember/ember-cli-typescript/issues/246
|
||||
// https://github.com/Microsoft/TypeScript/pull/26063
|
||||
//
|
||||
// assertType<Person | undefined>(array.get('firstObject'));
|
||||
assertType<string[]>(array.mapBy('name'));
|
||||
assertType<string[]>(array.map(p => p.get('name')));
|
||||
assertType<Person[]>(array.sortBy('name'));
|
||||
assertType<Person[]>(array.uniq());
|
||||
assertType<Person[]>(array.uniqBy('name'));
|
||||
@@ -0,0 +1,26 @@
|
||||
import Ember from 'ember';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
const pets = ['dog', 'cat', 'fish'];
|
||||
const proxy = Ember.ArrayProxy.create({ content: Ember.A(pets) });
|
||||
|
||||
proxy.get('firstObject'); // 'dog'
|
||||
proxy.set('content', Ember.A(['amoeba', 'paramecium']));
|
||||
proxy.get('firstObject'); // 'amoeba'
|
||||
|
||||
const overridden = Ember.ArrayProxy.create({
|
||||
content: Ember.A(pets),
|
||||
objectAtContent(idx: number): string {
|
||||
return this.get('content').objectAt(idx)!.toUpperCase();
|
||||
}
|
||||
});
|
||||
|
||||
overridden.get('firstObject'); // 'DOG'
|
||||
|
||||
class MyNewProxy<T> extends Ember.ArrayProxy<T> {
|
||||
isNew = true;
|
||||
}
|
||||
|
||||
let x = MyNewProxy.create({ content: Ember.A([1, 2, 3]) }) as MyNewProxy<number>;
|
||||
assertType<number | undefined>(x.get('firstObject'));
|
||||
assertType<boolean>(x.isNew);
|
||||
Executable
+48
@@ -0,0 +1,48 @@
|
||||
import Ember from 'ember';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
type Person = typeof Person.prototype;
|
||||
const Person = Ember.Object.extend({
|
||||
name: '',
|
||||
isHappy: false
|
||||
});
|
||||
|
||||
const people = Ember.A([
|
||||
Person.create({ name: 'Yehuda', isHappy: true }),
|
||||
Person.create({ name: 'Majd', isHappy: false }),
|
||||
]);
|
||||
|
||||
assertType<number>(people.get('length'));
|
||||
assertType<Person>(people.get('lastObject'));
|
||||
assertType<boolean>(people.isAny('isHappy'));
|
||||
assertType<boolean>(people.isAny('isHappy', 'false'));
|
||||
assertType<Ember.Enumerable<Person>>(people.filterBy('isHappy'));
|
||||
assertType<Ember.Enumerable<Person>>(people.rejectBy('isHappy'));
|
||||
assertType<Ember.Enumerable<Person>>(people.filter((person) => person.get('name') === 'Yehuda'));
|
||||
assertType<typeof people>(people.get('[]'));
|
||||
assertType<Person>(people.get('[]').get('firstObject'));
|
||||
|
||||
assertType<Ember.Array<boolean>>(people.mapBy('isHappy'));
|
||||
assertType<any[]>(people.mapBy('name.length'));
|
||||
|
||||
const last = people.get('lastObject');
|
||||
if (last) {
|
||||
assertType<string>(last.get('name'));
|
||||
}
|
||||
|
||||
const first = people.get('lastObject');
|
||||
if (first) {
|
||||
assertType<boolean>(first.get('isHappy'));
|
||||
}
|
||||
|
||||
const letters: Ember.Enumerable<string> = Ember.A(['a', 'b', 'c']);
|
||||
const codes: number[] = letters.map((item, index, enumerable) => {
|
||||
assertType<string>(item);
|
||||
assertType<number>(index);
|
||||
return item.charCodeAt(0);
|
||||
});
|
||||
|
||||
let value = '1,2,3';
|
||||
let filters = Ember.A(value.split(','));
|
||||
filters.push('4');
|
||||
filters.sort();
|
||||
Executable
+124
@@ -0,0 +1,124 @@
|
||||
import Ember from 'ember';
|
||||
import Component from '@ember/component';
|
||||
import Object, { computed } from '@ember/object';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import { assertType } from "./lib/assert";
|
||||
|
||||
Component.extend({
|
||||
layout: hbs`
|
||||
<div>
|
||||
{{yield}}
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
||||
Component.extend({
|
||||
layout: 'my-layout',
|
||||
});
|
||||
|
||||
const MyComponent = Component.extend();
|
||||
assertType<string | string[]>(Ember.get(MyComponent, 'positionalParams'));
|
||||
|
||||
const component1 = Component.extend({
|
||||
actions: {
|
||||
hello(name: string) {
|
||||
console.log('Hello', name);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Component.extend({
|
||||
name: '',
|
||||
hello(name: string) {
|
||||
this.set('name', name);
|
||||
},
|
||||
});
|
||||
|
||||
Component.extend({
|
||||
tagName: 'em',
|
||||
});
|
||||
|
||||
Component.extend({
|
||||
classNames: ['my-class', 'my-other-class'],
|
||||
});
|
||||
|
||||
Component.extend({
|
||||
classNameBindings: ['propertyA', 'propertyB'],
|
||||
propertyA: 'from-a',
|
||||
propertyB: computed(function() {
|
||||
if (!this.get('propertyA')) {
|
||||
return 'from-b';
|
||||
}
|
||||
}),
|
||||
});
|
||||
|
||||
Component.extend({
|
||||
classNameBindings: ['hovered'],
|
||||
hovered: true,
|
||||
});
|
||||
|
||||
Component.extend({
|
||||
classNameBindings: ['messages.empty'],
|
||||
messages: Object.create({
|
||||
empty: true,
|
||||
}),
|
||||
});
|
||||
|
||||
Component.extend({
|
||||
classNameBindings: ['isEnabled:enabled:disabled'],
|
||||
isEnabled: true,
|
||||
});
|
||||
|
||||
Component.extend({
|
||||
classNameBindings: ['isEnabled::disabled'],
|
||||
isEnabled: true,
|
||||
});
|
||||
|
||||
Component.extend({
|
||||
tagName: 'a',
|
||||
attributeBindings: ['href'],
|
||||
href: 'http://google.com',
|
||||
});
|
||||
|
||||
Component.extend({
|
||||
tagName: 'a',
|
||||
attributeBindings: ['url:href'],
|
||||
url: 'http://google.com',
|
||||
});
|
||||
|
||||
Component.extend({
|
||||
tagName: 'use',
|
||||
attributeBindings: ['xlinkHref:xlink:href'],
|
||||
xlinkHref: '#triangle',
|
||||
});
|
||||
|
||||
Component.extend({
|
||||
tagName: 'input',
|
||||
attributeBindings: ['disabled'],
|
||||
disabled: false,
|
||||
});
|
||||
|
||||
Component.extend({
|
||||
tagName: 'input',
|
||||
attributeBindings: ['disabled'],
|
||||
disabled: computed(() => {
|
||||
if ('someLogic') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}),
|
||||
});
|
||||
|
||||
Component.extend({
|
||||
tagName: 'form',
|
||||
attributeBindings: ['novalidate'],
|
||||
novalidate: null,
|
||||
});
|
||||
|
||||
Component.extend({
|
||||
click(event: object) {
|
||||
// will be called when an instance's
|
||||
// rendered element is clicked
|
||||
},
|
||||
});
|
||||
Executable
+166
@@ -0,0 +1,166 @@
|
||||
import Ember from 'ember';
|
||||
import Component from '@ember/component';
|
||||
import Computed, { alias, or } from '@ember/object/computed';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
const Person = Ember.Object.extend({
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
age: 0,
|
||||
|
||||
noArgs: Ember.computed<string>(() => 'test'),
|
||||
|
||||
fullName: Ember.computed<string>('firstName', 'lastName', function() {
|
||||
return `${this.get('firstName')} ${this.get('lastName')}`;
|
||||
}),
|
||||
|
||||
fullNameReadonly: Ember.computed<string>('fullName', function() {
|
||||
return this.get('fullName');
|
||||
}).readOnly(),
|
||||
|
||||
fullNameWritable: Ember.computed<string>('firstName', 'lastName', {
|
||||
get() {
|
||||
return this.get('fullName');
|
||||
},
|
||||
set(key, value) {
|
||||
let [first, last] = value.split(' ');
|
||||
this.set('firstName', first);
|
||||
this.set('lastName', last);
|
||||
return value;
|
||||
}
|
||||
}),
|
||||
|
||||
fullNameGetOnly: Ember.computed<string>('fullName', {
|
||||
get() {
|
||||
return this.get('fullName');
|
||||
}
|
||||
}),
|
||||
|
||||
fullNameSetOnly: Ember.computed<string>('firstName', 'lastName', {
|
||||
set(key, value) {
|
||||
let [first, last] = value.split(' ');
|
||||
this.set('firstName', first);
|
||||
this.set('lastName', last);
|
||||
return value;
|
||||
}
|
||||
}),
|
||||
|
||||
combinators: Ember.computed<string>(function() {
|
||||
return this.get('firstName');
|
||||
}).property('firstName')
|
||||
.meta({ foo: 'bar' })
|
||||
.volatile()
|
||||
.readOnly(),
|
||||
|
||||
explicitlyDeclared: alias('fullName') as Computed<string>,
|
||||
});
|
||||
|
||||
const person = Person.create({
|
||||
firstName: 'Fred',
|
||||
lastName: 'Smith',
|
||||
age: 29,
|
||||
});
|
||||
|
||||
assertType<string>(person.firstName);
|
||||
assertType<number>(person.age);
|
||||
assertType<Ember.ComputedProperty<string>>(person.noArgs);
|
||||
assertType<Ember.ComputedProperty<string>>(person.fullName);
|
||||
assertType<Ember.ComputedProperty<string>>(person.fullNameReadonly);
|
||||
assertType<Ember.ComputedProperty<string>>(person.fullNameWritable);
|
||||
assertType<Ember.ComputedProperty<string>>(person.fullNameGetOnly);
|
||||
assertType<Ember.ComputedProperty<string>>(person.fullNameSetOnly);
|
||||
assertType<Ember.ComputedProperty<string>>(person.combinators);
|
||||
assertType<Ember.ComputedProperty<string>>(person.explicitlyDeclared);
|
||||
|
||||
assertType<string>(person.get('firstName'));
|
||||
assertType<number>(person.get('age'));
|
||||
assertType<string>(person.get('noArgs'));
|
||||
assertType<string>(person.get('fullName'));
|
||||
assertType<string>(person.get('fullNameReadonly'));
|
||||
assertType<string>(person.get('fullNameWritable'));
|
||||
assertType<string>(person.get('fullNameGetOnly'));
|
||||
assertType<string>(person.get('fullNameSetOnly'));
|
||||
assertType<string>(person.get('combinators'));
|
||||
assertType<string>(person.get('explicitlyDeclared'));
|
||||
|
||||
assertType<{ firstName: string, fullName: string, age: number }>(person.getProperties('firstName', 'fullName', 'age'));
|
||||
|
||||
const person2 = Person.create({
|
||||
fullName: 'Fred Smith'
|
||||
});
|
||||
|
||||
assertType<string>(person2.get('firstName'));
|
||||
assertType<string>(person2.get('fullName'));
|
||||
|
||||
const person3 = Person.extend({
|
||||
firstName: 'Fred',
|
||||
fullName: 'Fred Smith'
|
||||
}).create();
|
||||
|
||||
assertType<string>(person3.get('firstName'));
|
||||
assertType<string>(person3.get('fullName'));
|
||||
|
||||
const person4 = Person.extend({
|
||||
firstName: Ember.computed(() => 'Fred'),
|
||||
fullName: Ember.computed(() => 'Fred Smith')
|
||||
}).create();
|
||||
|
||||
assertType<string>(person4.get('firstName'));
|
||||
assertType<string>(person4.get('fullName'));
|
||||
|
||||
// computed property macros
|
||||
const objectWithComputedProperties = Ember.Object.extend({
|
||||
alias: Ember.computed.alias('foo'),
|
||||
and: Ember.computed.and('foo', 'bar', 'baz', 'qux'),
|
||||
bool: Ember.computed.bool('foo'),
|
||||
collect: Ember.computed.collect('foo', 'bar', 'baz', 'qux'),
|
||||
deprecatingAlias: Ember.computed.deprecatingAlias('foo', {
|
||||
id: 'hamster.deprecate-banana',
|
||||
until: '3.0.0'
|
||||
}),
|
||||
empty: Ember.computed.empty('foo'),
|
||||
equalNumber: Ember.computed.equal('foo', 1),
|
||||
equalString: Ember.computed.equal('foo', 'bar'),
|
||||
equalObject: Ember.computed.equal('foo', {}),
|
||||
filter: Ember.computed.filter('foo', (item) => item === 'bar'),
|
||||
filterBy1: Ember.computed.filterBy('foo', 'bar'),
|
||||
filterBy2: Ember.computed.filterBy('foo', 'bar', false),
|
||||
gt: Ember.computed.gt('foo', 3),
|
||||
gte: Ember.computed.gte('foo', 3),
|
||||
intersect: Ember.computed.intersect('foo', 'bar', 'baz', 'qux'),
|
||||
lt: Ember.computed.lt('foo', 3),
|
||||
lte: Ember.computed.lte('foo', 3),
|
||||
map: Ember.computed.map('foo', (item, index) => item.bar),
|
||||
mapBy: Ember.computed.mapBy('foo', 'bar'),
|
||||
match: Ember.computed.match('foo', /^tom.ter$/),
|
||||
max: Ember.computed.max('foo'),
|
||||
min: Ember.computed.min('foo'),
|
||||
none: Ember.computed.none('foo'),
|
||||
not: Ember.computed.not('foo'),
|
||||
notEmpty: Ember.computed.notEmpty('foo'),
|
||||
oneWay: Ember.computed.oneWay('foo'),
|
||||
or: Ember.computed.or('foo', 'bar', 'baz', 'qux'),
|
||||
readOnly: Ember.computed.readOnly('foo'),
|
||||
reads: Ember.computed.reads('foo'),
|
||||
setDiff: Ember.computed.setDiff('foo', 'bar'),
|
||||
sort1: Ember.computed.sort('foo', 'bar'),
|
||||
sort2: Ember.computed.sort('foo', (itemA, itemB) => {
|
||||
if (itemA < itemB) {
|
||||
return -1;
|
||||
} else if (itemA > itemB) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}),
|
||||
sum: Ember.computed.sum('foo'),
|
||||
union: Ember.computed.union('foo', 'bar', 'baz', 'qux'),
|
||||
uniq: Ember.computed.uniq('foo'),
|
||||
uniqBy: Ember.computed.uniqBy('foo', 'bar')
|
||||
});
|
||||
|
||||
const component2 = Component.extend({
|
||||
isAnimal: or('isDog', 'isCat')
|
||||
}).create();
|
||||
|
||||
assertType<boolean>(component2.get('isAnimal'));
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
import Controller from '@ember/controller';
|
||||
|
||||
Controller.extend ({
|
||||
queryParams: ['category'],
|
||||
category: null,
|
||||
isExpanded: false,
|
||||
|
||||
toggleBody() {
|
||||
this.toggleProperty('isExpanded');
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import { assertType } from './lib/assert';
|
||||
import Ember from 'ember';
|
||||
import { PersonWithNumberName, Person } from './create';
|
||||
|
||||
const p3 = Person.create({ firstName: 99 }); // $ExpectError
|
||||
const p2b = Person.create({}, { firstName: 99 }); // $ExpectError
|
||||
const p2c = Person.create({}, {}, { firstName: 99 }); // $ExpectError
|
||||
|
||||
const p4 = new PersonWithNumberName();
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
import Ember from 'ember';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
const o = Ember.Object.create();
|
||||
assertType<object>(o);
|
||||
|
||||
const o1 = Ember.Object.create({x: 9});
|
||||
assertType<number>(o1.x);
|
||||
|
||||
const obj = Ember.Object.create({ a: 1 }, { b: 2 }, { c: 3 });
|
||||
assertType<number>(obj.b);
|
||||
assertType<number>(obj.a);
|
||||
assertType<number>(obj.c);
|
||||
|
||||
export class Person extends Ember.Object.extend({
|
||||
fullName: Ember.computed('firstName', 'lastName', function() {
|
||||
return [this.firstName + this.lastName].join(' ');
|
||||
})
|
||||
}) {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
age: number;
|
||||
}
|
||||
const p = new Person();
|
||||
assertType<string>(p.firstName);
|
||||
assertType<Ember.ComputedProperty<string>>(p.fullName);
|
||||
assertType<string>(p.get('fullName'));
|
||||
|
||||
const p2 = Person.create({ firstName: 'string' });
|
||||
const p2b = Person.create({}, { firstName: 'string' });
|
||||
const p2c = Person.create({}, {}, { firstName: 'string' });
|
||||
|
||||
export class PersonWithNumberName extends Person.extend({
|
||||
fullName: 6
|
||||
}) {}
|
||||
|
||||
const p4 = new PersonWithNumberName();
|
||||
assertType<string>(p4.firstName);
|
||||
assertType<number>(p4.fullName);
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
import Ember from 'ember';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
const ExtendClass = Ember.Object.extend({
|
||||
foo: 'hello'
|
||||
});
|
||||
|
||||
class ES6Class extends Ember.Object {
|
||||
bar: string;
|
||||
}
|
||||
|
||||
let testObject = null;
|
||||
|
||||
if (ExtendClass.detectInstance(testObject)) {
|
||||
assertType<string>(testObject.foo);
|
||||
}
|
||||
|
||||
if (ES6Class.detectInstance(testObject)) {
|
||||
assertType<string>(testObject.bar);
|
||||
}
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
import Ember from 'ember';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
const ExtendClass = Ember.Object.extend({
|
||||
foo: 'hello'
|
||||
});
|
||||
|
||||
class ES6Class extends Ember.Object {
|
||||
bar: string;
|
||||
}
|
||||
|
||||
let TestClass = Ember.Object;
|
||||
|
||||
if (ExtendClass.detect(TestClass)) {
|
||||
assertType<string>(TestClass.create().foo);
|
||||
}
|
||||
|
||||
if (ES6Class.detect(TestClass)) {
|
||||
assertType<string>(TestClass.create().bar);
|
||||
}
|
||||
Executable
+170
@@ -0,0 +1,170 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
let App: any;
|
||||
|
||||
App = Ember.Application.create();
|
||||
App.president = Ember.Object.create({
|
||||
name: 'Barack Obama',
|
||||
});
|
||||
App.country = Ember.Object.create({
|
||||
presidentNameBinding: 'MyApp.president.name',
|
||||
});
|
||||
App.country.get('presidentName');
|
||||
App.president = Ember.Object.create({
|
||||
firstName: 'Barack',
|
||||
lastName: 'Obama',
|
||||
fullName: Ember.computed(function() {
|
||||
return `${this.get('firstName')} ${this.get('lastName')}`;
|
||||
}),
|
||||
});
|
||||
App.president.get('fullName');
|
||||
|
||||
declare class MyPerson extends Ember.Object {
|
||||
static createMan(): MyPerson;
|
||||
}
|
||||
MyPerson.createMan();
|
||||
|
||||
const Person1 = Ember.Object.extend({
|
||||
say: (thing: string) => {
|
||||
alert(thing);
|
||||
},
|
||||
});
|
||||
|
||||
declare class MyPerson2 extends Ember.Object {
|
||||
helloWorld(): void;
|
||||
}
|
||||
MyPerson2.create().helloWorld();
|
||||
|
||||
const tom = Person1.create({
|
||||
name: 'Tom Dale',
|
||||
helloWorld() {
|
||||
this.say('Hi my name is ' + this.get('name'));
|
||||
},
|
||||
});
|
||||
tom.helloWorld();
|
||||
|
||||
const PersonReopened = Person1.reopen({ isPerson: true });
|
||||
PersonReopened.create().get('isPerson');
|
||||
|
||||
App.todosController = Ember.Object.create({
|
||||
todos: [Ember.Object.create({ isDone: false })],
|
||||
remaining: Ember.computed('todos.@each.isDone', function() {
|
||||
const todos = this.get('todos');
|
||||
return todos.filterProperty('isDone', false).get('length');
|
||||
}),
|
||||
});
|
||||
|
||||
const todos = App.todosController.get('todos');
|
||||
let todo = todos.objectAt(0);
|
||||
todo.set('isDone', true);
|
||||
App.todosController.get('remaining');
|
||||
todo = Ember.Object.create({ isDone: false });
|
||||
todos.pushObject(todo);
|
||||
App.todosController.get('remaining');
|
||||
|
||||
App.wife = Ember.Object.create({
|
||||
householdIncome: 80000,
|
||||
});
|
||||
App.husband = Ember.Object.create({
|
||||
householdIncomeBinding: 'App.wife.householdIncome',
|
||||
});
|
||||
App.husband.get('householdIncome');
|
||||
App.husband.set('householdIncome', 90000);
|
||||
App.wife.get('householdIncome');
|
||||
|
||||
App.user = Ember.Object.create({
|
||||
fullName: 'Kara Gates',
|
||||
});
|
||||
App.user.set('fullName', 'Krang Gates');
|
||||
App.userView.set('userName', 'Truckasaurus Gates');
|
||||
App.user.get('fullName');
|
||||
|
||||
App = Ember.Application.create({
|
||||
rootElement: '#sidebar',
|
||||
});
|
||||
|
||||
App.userController = Ember.Object.create({
|
||||
content: Ember.Object.create({
|
||||
firstName: 'Albert',
|
||||
lastName: 'Hofmann',
|
||||
posts: 25,
|
||||
hobbies: 'Riding bicycles',
|
||||
}),
|
||||
});
|
||||
|
||||
Handlebars.registerHelper(
|
||||
'highlight',
|
||||
(property: string, options: any) =>
|
||||
new Handlebars.SafeString('<span class="highlight">' + 'some value' + '</span>')
|
||||
);
|
||||
|
||||
const coolView = App.CoolView.create();
|
||||
|
||||
const Person2 = Ember.Object.extend({
|
||||
name: '',
|
||||
sayHello() {
|
||||
console.log('Hello from ' + this.get('name'));
|
||||
},
|
||||
});
|
||||
const people = Ember.A([
|
||||
Person2.create({ name: 'Juan' }),
|
||||
Person2.create({ name: 'Charles' }),
|
||||
Person2.create({ name: 'Majd' }),
|
||||
]);
|
||||
people.invoke('sayHello');
|
||||
|
||||
const arr = Ember.A([Ember.Object.create(), Ember.Object.create()]);
|
||||
arr.setEach('name', 'unknown');
|
||||
arr.getEach('name');
|
||||
|
||||
const Person3 = Ember.Object.extend({
|
||||
name: '',
|
||||
isHappy: false,
|
||||
});
|
||||
const people2 = Ember.A([
|
||||
Person3.create({ name: 'Yehuda', isHappy: true }),
|
||||
Person3.create({ name: 'Majd', isHappy: false }),
|
||||
]);
|
||||
const isHappy = (person: typeof Person3.prototype): boolean => {
|
||||
return !!person.get('isHappy');
|
||||
};
|
||||
people2.every(isHappy);
|
||||
people2.any(isHappy);
|
||||
people2.isEvery('isHappy');
|
||||
people2.isEvery('isHappy', true);
|
||||
people2.isAny('isHappy', 'true');
|
||||
people2.isAny('isHappy');
|
||||
|
||||
// Examples taken from http://emberjs.com/api/classes/Em.RSVP.Promise.html
|
||||
const promise = new Ember.RSVP.Promise<string>((resolve: Function, reject: Function) => {
|
||||
// on success
|
||||
resolve('ok!');
|
||||
|
||||
// on failure
|
||||
reject('no-k!');
|
||||
});
|
||||
|
||||
promise.then(
|
||||
(value: any) => {
|
||||
// on fulfillment
|
||||
},
|
||||
(reason: any) => {
|
||||
// on rejection
|
||||
}
|
||||
);
|
||||
|
||||
// make sure Ember.RSVP.Promise can be reference as a type
|
||||
declare function promiseReturningFunction(urn: string): Ember.RSVP.Promise<string>;
|
||||
|
||||
const mix1 = Ember.Mixin.create({
|
||||
foo: 1,
|
||||
});
|
||||
|
||||
const mix2 = Ember.Mixin.create({
|
||||
bar: 2,
|
||||
});
|
||||
|
||||
const component1 = Ember.Component.extend(mix1, mix2, {
|
||||
lyft: Ember.inject.service(),
|
||||
cars: Ember.computed.readOnly('lyft.cars'),
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
import EngineInstance from '@ember/engine/instance';
|
||||
|
||||
const engineInstance = EngineInstance.create();
|
||||
engineInstance.register('some:injection', class Foo {});
|
||||
|
||||
engineInstance.register('some:injection', class Foo {}, {
|
||||
singleton: true,
|
||||
});
|
||||
|
||||
engineInstance.register('some:injection', class Foo {}, {
|
||||
instantiate: false,
|
||||
});
|
||||
|
||||
engineInstance.register('some:injection', class Foo {}, {
|
||||
singleton: false,
|
||||
instantiate: true,
|
||||
});
|
||||
|
||||
engineInstance.factoryFor('router:main');
|
||||
engineInstance.lookup('route:basic');
|
||||
|
||||
engineInstance.boot();
|
||||
|
||||
(async function() {
|
||||
await engineInstance.boot();
|
||||
}());
|
||||
@@ -0,0 +1,6 @@
|
||||
import { assertType } from "./lib/assert";
|
||||
|
||||
import Ember from "ember";
|
||||
import EmberError from "@ember/error";
|
||||
|
||||
assertType<typeof Ember.Error>(EmberError);
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
function testOn() {
|
||||
let Job = Ember.Object.extend({
|
||||
logCompleted: Ember.on('completed', function() {
|
||||
console.log('Job completed!');
|
||||
})
|
||||
});
|
||||
|
||||
let job = Job.create();
|
||||
|
||||
Ember.sendEvent(job, 'completed'); // Logs 'Job completed!'
|
||||
}
|
||||
|
||||
function testEvented() {
|
||||
let Person = Ember.Object.extend(Ember.Evented, {
|
||||
greet() {
|
||||
this.trigger('greet');
|
||||
}
|
||||
});
|
||||
|
||||
let person = Person.create();
|
||||
|
||||
person.on('greet', function() {
|
||||
console.log('Our person has greeted');
|
||||
});
|
||||
|
||||
person.on('greet', function() {
|
||||
console.log('Our person has greeted');
|
||||
}).one('greet', function() {
|
||||
console.log('Offer one-time special');
|
||||
}).off('event', {}, function() {});
|
||||
|
||||
person.greet();
|
||||
}
|
||||
|
||||
function testObserver() {
|
||||
Ember.Object.extend({
|
||||
valueObserver: Ember.observer('value', function() {
|
||||
// Executes whenever the "value" property changes
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function testListener() {
|
||||
Ember.Component.extend({
|
||||
init() {
|
||||
Ember.addListener(this, 'willDestroyElement', this, 'willDestroyListener');
|
||||
Ember.addListener(this, 'willDestroyElement', this, 'willDestroyListener', true);
|
||||
Ember.addListener(this, 'willDestroyElement', this, this.willDestroyListener);
|
||||
Ember.addListener(this, 'willDestroyElement', this, this.willDestroyListener, true);
|
||||
Ember.removeListener(this, 'willDestroyElement', this, 'willDestroyListener');
|
||||
Ember.removeListener(this, 'willDestroyElement', this, this.willDestroyListener);
|
||||
},
|
||||
willDestroyListener() {
|
||||
}
|
||||
});
|
||||
}
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
import Ember from 'ember';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
const Person = Ember.Object.extend({
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
|
||||
getFullName() {
|
||||
return `${this.firstName} ${this.lastName}`;
|
||||
},
|
||||
getFullName2(): string {
|
||||
return `${this.get('firstName')} ${this.get('lastName')}`;
|
||||
}
|
||||
});
|
||||
|
||||
assertType<string>(Person.prototype.firstName);
|
||||
assertType<() => string>(Person.prototype.getFullName);
|
||||
|
||||
const person = Person.create({
|
||||
firstName: 'Joe',
|
||||
lastName: 'Blow',
|
||||
extra: 42
|
||||
});
|
||||
|
||||
assertType<string>(person.getFullName());
|
||||
assertType<number>(person.extra);
|
||||
|
||||
class ES6Person extends Ember.Object {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
|
||||
get fullName() {
|
||||
return `${this.firstName} ${this.lastName}`;
|
||||
}
|
||||
get fullName2(): string {
|
||||
return `${this.get('firstName')} ${this.get('lastName')}`;
|
||||
}
|
||||
}
|
||||
|
||||
assertType<string>(ES6Person.prototype.firstName);
|
||||
assertType<string>(ES6Person.prototype.fullName);
|
||||
|
||||
const es6Person = ES6Person.create({
|
||||
firstName: 'Joe',
|
||||
lastName: 'Blow',
|
||||
extra: 42
|
||||
});
|
||||
|
||||
assertType<string>(es6Person.fullName);
|
||||
assertType<number>(es6Person.extra);
|
||||
|
||||
class PersonWithStatics extends Ember.Object {
|
||||
static isPerson = true;
|
||||
}
|
||||
const PersonWithStatics2 = PersonWithStatics.extend({});
|
||||
class PersonWithStatics3 extends PersonWithStatics {}
|
||||
class PersonWithStatics4 extends PersonWithStatics2 {}
|
||||
assertType<boolean>(PersonWithStatics.isPerson);
|
||||
assertType<boolean>(PersonWithStatics2.isPerson);
|
||||
assertType<boolean>(PersonWithStatics3.isPerson);
|
||||
assertType<boolean>(PersonWithStatics4.isPerson);
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
declare global {
|
||||
interface Function extends Ember.FunctionPrototypeExtensions {}
|
||||
}
|
||||
|
||||
Ember.Object.extend({
|
||||
foo: '',
|
||||
|
||||
arr: function() {
|
||||
return [];
|
||||
}.property(),
|
||||
|
||||
alias: function(this: any) {
|
||||
return this.get('foo');
|
||||
}.property('foo', 'bar.@each.baz'),
|
||||
|
||||
observer: function() {}.observes('foo', 'bar'),
|
||||
|
||||
on: function() {}.on('foo', 'bar'),
|
||||
});
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
const FormatCurrencyHelper = Ember.Helper.helper(function(params, hash: { currency: string }) {
|
||||
let cents = params[0];
|
||||
let currency = hash.currency;
|
||||
return `${currency}${cents * 0.01}`;
|
||||
});
|
||||
|
||||
class User extends Ember.Object {
|
||||
email: string;
|
||||
}
|
||||
|
||||
class SessionService extends Ember.Service {
|
||||
currentUser: User;
|
||||
}
|
||||
|
||||
const CurrentUserEmailHelper = Ember.Helper.extend({
|
||||
session: Ember.inject.service() as Ember.ComputedProperty<SessionService>,
|
||||
onNewUser: Ember.observer('session.currentUser', function(this: Ember.Helper) {
|
||||
this.recompute();
|
||||
}),
|
||||
compute(): string {
|
||||
return this.get('session')
|
||||
.get('currentUser')
|
||||
.get('email');
|
||||
},
|
||||
});
|
||||
|
||||
import { helper } from '@ember/component/helper';
|
||||
|
||||
function typedHelp(/*params, hash*/) {
|
||||
return 'my type of help';
|
||||
}
|
||||
|
||||
export default helper(typedHelp);
|
||||
|
||||
function arrayNumHelp(/*params, hash*/) {
|
||||
return [1, 2, 3];
|
||||
}
|
||||
|
||||
helper(arrayNumHelp);
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
class AuthService extends Ember.Service {
|
||||
isAuthenticated: boolean;
|
||||
}
|
||||
|
||||
class ApplicationController extends Ember.Controller {
|
||||
model: {};
|
||||
string: string;
|
||||
transitionToLogin() {}
|
||||
}
|
||||
|
||||
declare module '@ember/service' {
|
||||
interface Registry {
|
||||
'auth': AuthService;
|
||||
}
|
||||
}
|
||||
|
||||
declare module '@ember/controller' {
|
||||
interface Registry {
|
||||
'application': ApplicationController;
|
||||
}
|
||||
}
|
||||
|
||||
class LoginRoute extends Ember.Route {
|
||||
auth = Ember.inject.service('auth');
|
||||
application = Ember.inject.controller('application');
|
||||
|
||||
didTransition() {
|
||||
if (!this.get('auth').get('isAuthenticated')) {
|
||||
this.get('application').transitionToLogin();
|
||||
}
|
||||
}
|
||||
|
||||
anyOldMethod() {
|
||||
this.controllerFor('application').set('string', 'must be a string');
|
||||
}
|
||||
}
|
||||
|
||||
// New module injection style.
|
||||
import Controller, { inject as controller } from '@ember/controller';
|
||||
import Service, { inject as service } from '@ember/service';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
class ComponentInjection extends Ember.Component {
|
||||
applicationController = controller('application');
|
||||
auth = service('auth');
|
||||
router = service('router');
|
||||
misc = service();
|
||||
|
||||
testem() {
|
||||
assertType<Ember.Service>(this.get('misc'));
|
||||
const url = this.get('router').urlFor('some-route', 1, 2, 3, { queryParams: { seriously: 'yes' } });
|
||||
assertType<string>(url);
|
||||
if (!this.get('auth').isAuthenticated) {
|
||||
this.get('applicationController').transitionToLogin();
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
/** Static assertion that `value` has type `T` */
|
||||
// Disable tslint here b/c the generic is used to let us do a type coercion and
|
||||
// validate that coercion works for the type value "passed into" the function.
|
||||
// tslint:disable-next-line:no-unnecessary-generics
|
||||
export declare function assertType<T>(value: T): void;
|
||||
Executable
+57
@@ -0,0 +1,57 @@
|
||||
import Ember from 'ember';
|
||||
import { assertType } from "./lib/assert";
|
||||
|
||||
interface EditableMixin {
|
||||
edit(): void;
|
||||
isEditing: boolean;
|
||||
}
|
||||
|
||||
const EditableMixin: Ember.Mixin<EditableMixin, Ember.Route> = Ember.Mixin.create({
|
||||
edit() {
|
||||
this.get('controller');
|
||||
console.log('starting to edit');
|
||||
this.set('isEditing', true);
|
||||
},
|
||||
isEditing: false
|
||||
});
|
||||
|
||||
const EditableComment = Ember.Route.extend(EditableMixin, {
|
||||
postId: 0,
|
||||
|
||||
canEdit() {
|
||||
return !this.isEditing;
|
||||
},
|
||||
|
||||
tryEdit() {
|
||||
if (this.canEdit()) {
|
||||
this.edit();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const comment = EditableComment.create({
|
||||
postId: 42
|
||||
});
|
||||
|
||||
comment.edit();
|
||||
comment.canEdit();
|
||||
comment.tryEdit();
|
||||
assertType<boolean>(comment.isEditing);
|
||||
assertType<number>(comment.postId);
|
||||
|
||||
const LiteralMixins = Ember.Object.extend({ a: 1 }, { b: 2 }, { c: 3 });
|
||||
const obj = LiteralMixins.create();
|
||||
assertType<number>(obj.a);
|
||||
assertType<number>(obj.b);
|
||||
assertType<number>(obj.c);
|
||||
|
||||
/* Test composition of mixins */
|
||||
const EditableAndCancelableMixin = Ember.Mixin.create(EditableMixin, {
|
||||
cancelled: false,
|
||||
});
|
||||
|
||||
const EditableAndCancelableComment = Ember.Route.extend(EditableAndCancelableMixin);
|
||||
|
||||
const editableAndCancelable = EditableAndCancelableComment.create();
|
||||
assertType<boolean>(editableAndCancelable.isEditing);
|
||||
assertType<boolean>(editableAndCancelable.cancelled);
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
const LifetimeHooks = Ember.Object.extend({
|
||||
resource: null as {} | null,
|
||||
|
||||
init() {
|
||||
this._super();
|
||||
this.resource = {};
|
||||
},
|
||||
|
||||
willDestroy() {
|
||||
delete this.resource;
|
||||
this._super();
|
||||
}
|
||||
});
|
||||
|
||||
class MyObject30 extends Ember.Object {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
class MyObject31 extends Ember.Object {
|
||||
constructor(properties: object) {
|
||||
super(properties);
|
||||
}
|
||||
}
|
||||
Executable
+113
@@ -0,0 +1,113 @@
|
||||
import Ember from 'ember';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
class MyComponent extends Ember.Component {
|
||||
foo = 'bar';
|
||||
|
||||
init() {
|
||||
this._super.apply(this, arguments);
|
||||
this.addObserver('foo', this, 'fooDidChange');
|
||||
this.addObserver('foo', this, this.fooDidChange);
|
||||
Ember.addObserver(this, 'foo', this, 'fooDidChange');
|
||||
Ember.addObserver(this, 'foo', this, this.fooDidChange);
|
||||
this.removeObserver('foo', this, 'fooDidChange');
|
||||
this.removeObserver('foo', this, this.fooDidChange);
|
||||
Ember.removeObserver(this, 'foo', this, 'fooDidChange');
|
||||
Ember.removeObserver(this, 'foo', this, this.fooDidChange);
|
||||
const lambda = () => {
|
||||
this.fooDidChange(this, 'foo');
|
||||
};
|
||||
this.addObserver('foo', lambda);
|
||||
this.removeObserver('foo', lambda);
|
||||
Ember.addObserver(this, 'foo', lambda);
|
||||
Ember.removeObserver(this, 'foo', lambda);
|
||||
}
|
||||
|
||||
fooDidChange(sender: MyComponent, key: 'foo') {
|
||||
// your code
|
||||
}
|
||||
}
|
||||
|
||||
const myComponent = MyComponent.create();
|
||||
myComponent.addObserver('foo', null, () => {});
|
||||
myComponent.set('foo', 'baz');
|
||||
|
||||
const person = Ember.Object.create({
|
||||
name: 'Fred',
|
||||
age: 29,
|
||||
capitalized: Ember.computed<string>(function() {
|
||||
return this.get('name').toUpperCase();
|
||||
})
|
||||
});
|
||||
|
||||
const pojo = { name: 'Fred', age: 29 };
|
||||
|
||||
function testGet() {
|
||||
assertType<string>(Ember.get(person, 'name'));
|
||||
assertType<number>(Ember.get(person, 'age'));
|
||||
assertType<string>(Ember.get(person, 'capitalized'));
|
||||
assertType<string>(person.get('name'));
|
||||
assertType<number>(person.get('age'));
|
||||
assertType<string>(person.get('capitalized'));
|
||||
assertType<string>(Ember.get(pojo, 'name'));
|
||||
}
|
||||
|
||||
function testGetProperties() {
|
||||
assertType<{ name: string }>(Ember.getProperties(person, 'name'));
|
||||
assertType<{ name: string, age: number }>(Ember.getProperties(person, 'name', 'age'));
|
||||
assertType<{ name: string, age: number }>(Ember.getProperties(person, [ 'name', 'age' ]));
|
||||
assertType<{ name: string, age: number, capitalized: string }>(Ember.getProperties(person, 'name', 'age', 'capitalized'));
|
||||
assertType<{ name: string }>(person.getProperties('name'));
|
||||
assertType<{ name: string, age: number }>(person.getProperties('name', 'age'));
|
||||
assertType<{ name: string, age: number }>(person.getProperties([ 'name', 'age' ]));
|
||||
assertType<{ name: string, age: number, capitalized: string }>(person.getProperties('name', 'age', 'capitalized'));
|
||||
assertType<{ name: string, age: number }>(Ember.getProperties(pojo, 'name', 'age'));
|
||||
}
|
||||
|
||||
function testGetWithDefault() {
|
||||
assertType<string>(Ember.getWithDefault(person, 'name', 'Joe'));
|
||||
assertType<number>(Ember.getWithDefault(person, 'age', 20));
|
||||
assertType<string>(Ember.getWithDefault(person, 'capitalized', 'JOE'));
|
||||
assertType<string>(person.getWithDefault('name', 'Joe'));
|
||||
assertType<number>(person.getWithDefault('age', 20));
|
||||
assertType<string>(person.getWithDefault('capitalized', 'JOE'));
|
||||
assertType<string>(Ember.getWithDefault(pojo, 'name', 'JOE'));
|
||||
}
|
||||
|
||||
function testSet() {
|
||||
assertType<string>(Ember.set(person, 'name', 'Joe'));
|
||||
assertType<number>(Ember.set(person, 'age', 35));
|
||||
assertType<string>(Ember.set(person, 'capitalized', 'JOE'));
|
||||
assertType<string>(person.set('name', 'Joe'));
|
||||
assertType<number>(person.set('age', 35));
|
||||
assertType<string>(person.set('capitalized', 'JOE'));
|
||||
assertType<string>(Ember.set(pojo, 'name', 'Joe'));
|
||||
}
|
||||
|
||||
function testSetProperties() {
|
||||
assertType<{ name: string }>(Ember.setProperties(person, { name: 'Joe' }));
|
||||
assertType<{ name: string, age: number }>(Ember.setProperties(person, { name: 'Joe', age: 35 }));
|
||||
assertType<{ name: string, capitalized: string }>(Ember.setProperties(person, { name: 'Joe', capitalized: 'JOE' }));
|
||||
assertType<{ name: string }>(person.setProperties({ name: 'Joe' }));
|
||||
assertType<{ name: string, age: number }>(person.setProperties({ name: 'Joe', age: 35 }));
|
||||
assertType<{ name: string, capitalized: string }>(person.setProperties({ name: 'Joe', capitalized: 'JOE' }));
|
||||
assertType<{ name: string, age: number }>(Ember.setProperties(pojo, { name: 'Joe', age: 35 }));
|
||||
}
|
||||
|
||||
function testDynamic() {
|
||||
const obj: any = {};
|
||||
const dynamicKey: string = 'dummy'; // tslint:disable-line:no-inferrable-types
|
||||
|
||||
assertType<any>(Ember.get(obj, 'dummy'));
|
||||
assertType<any>(Ember.get(obj, dynamicKey));
|
||||
assertType<string>(Ember.getWithDefault(obj, 'dummy', 'default'));
|
||||
assertType<string>(Ember.getWithDefault(obj, dynamicKey, 'default'));
|
||||
assertType<{ dummy: any }>(Ember.getProperties(obj, 'dummy'));
|
||||
assertType<{ dummy: any }>(Ember.getProperties(obj, [ 'dummy' ]));
|
||||
assertType<object>(Ember.getProperties(obj, dynamicKey));
|
||||
assertType<object>(Ember.getProperties(obj, [ dynamicKey ]));
|
||||
assertType<string>(Ember.set(obj, 'dummy', 'value'));
|
||||
assertType<string>(Ember.set(obj, dynamicKey, 'value'));
|
||||
assertType<{ dummy: string }>(Ember.setProperties(obj, { dummy: 'value '}));
|
||||
assertType<object>(Ember.setProperties(obj, { [dynamicKey]: 'value' }));
|
||||
}
|
||||
Executable
+65
@@ -0,0 +1,65 @@
|
||||
import Ember from 'ember';
|
||||
import { assertType } from "./lib/assert";
|
||||
|
||||
type Person = typeof Person.prototype;
|
||||
const Person = Ember.Object.extend({
|
||||
name: '',
|
||||
sayHello() {
|
||||
alert(`Hello. My name is ${this.get('name')}`);
|
||||
}
|
||||
});
|
||||
|
||||
assertType<Person>(Person.reopen());
|
||||
|
||||
assertType<string>(Person.create().name);
|
||||
assertType<void>(Person.create().sayHello());
|
||||
|
||||
const Person2 = Person.reopenClass({
|
||||
species: 'Homo sapiens',
|
||||
|
||||
createPerson(name: string): Person {
|
||||
return Person.create({ name });
|
||||
}
|
||||
});
|
||||
|
||||
assertType<string>(Person2.create().name);
|
||||
assertType<void>(Person2.create().sayHello());
|
||||
assertType<string>(Person2.species);
|
||||
|
||||
let tom = Person2.create({
|
||||
name: 'Tom Dale'
|
||||
});
|
||||
let yehuda = Person2.createPerson('Yehuda Katz');
|
||||
|
||||
tom.sayHello(); // "Hello. My name is Tom Dale"
|
||||
yehuda.sayHello(); // "Hello. My name is Yehuda Katz"
|
||||
alert(Person2.species); // "Homo sapiens"
|
||||
|
||||
const Person3 = Person2.reopen({
|
||||
goodbyeMessage: 'goodbye',
|
||||
|
||||
sayGoodbye() {
|
||||
alert(`${this.get('goodbyeMessage')}, ${this.get('name')}`);
|
||||
}
|
||||
});
|
||||
|
||||
const person3 = Person3.create();
|
||||
person3.get('name');
|
||||
person3.get('goodbyeMessage');
|
||||
person3.sayHello();
|
||||
person3.sayGoodbye();
|
||||
|
||||
interface AutoResizeMixin { resizable: true; }
|
||||
declare const AutoResizeMixin: Ember.Mixin<AutoResizeMixin>;
|
||||
|
||||
const ResizableTextArea = Ember.TextArea.reopen(AutoResizeMixin, {
|
||||
scaling: 1.0
|
||||
});
|
||||
const text = ResizableTextArea.create();
|
||||
assertType<boolean>(text.resizable);
|
||||
assertType<number>(text.scaling);
|
||||
|
||||
const Reopened = Ember.Object.reopenClass({ a: 1 }, { b: 2 }, { c: 3 });
|
||||
assertType<number>(Reopened.a);
|
||||
assertType<number>(Reopened.b);
|
||||
assertType<number>(Reopened.c);
|
||||
Executable
+104
@@ -0,0 +1,104 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import Object from '@ember/object';
|
||||
import Array from '@ember/array';
|
||||
import Ember from 'ember'; // currently needed for Transition
|
||||
|
||||
interface Post extends Ember.Object {}
|
||||
|
||||
interface Posts extends Array<Post> {}
|
||||
|
||||
Route.extend({
|
||||
beforeModel(transition: Ember.Transition) {
|
||||
this.transitionTo('someOtherRoute');
|
||||
},
|
||||
});
|
||||
|
||||
Route.extend({
|
||||
afterModel(posts: Posts, transition: Ember.Transition) {
|
||||
if (posts.length === 1) {
|
||||
this.transitionTo('post.show', posts.firstObject);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Route.extend({
|
||||
actions: {
|
||||
showModal(evt: { modalName: string }) {
|
||||
this.render(evt.modalName, {
|
||||
outlet: 'modal',
|
||||
into: 'application',
|
||||
});
|
||||
},
|
||||
hideModal(evt: { modalName: string }) {
|
||||
this.disconnectOutlet({
|
||||
outlet: 'modal',
|
||||
parentView: 'application',
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Ember.Route.extend({
|
||||
model() {
|
||||
return this.modelFor('post');
|
||||
},
|
||||
});
|
||||
|
||||
Route.extend({
|
||||
queryParams: {
|
||||
memberQp: { refreshModel: true },
|
||||
},
|
||||
});
|
||||
|
||||
Route.extend({
|
||||
renderTemplate() {
|
||||
this.render('photos', {
|
||||
into: 'application',
|
||||
outlet: 'anOutletName',
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
Route.extend({
|
||||
renderTemplate(controller: Ember.Controller, model: {}) {
|
||||
this.render('posts', {
|
||||
view: 'someView', // the template to render, referenced by name
|
||||
into: 'application', // the template to render into, referenced by name
|
||||
outlet: 'anOutletName', // the outlet inside `options.into` to render into.
|
||||
controller: 'someControllerName', // the controller to use for this template, referenced by name
|
||||
model, // the model to set on `options.controller`.
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
Route.extend({
|
||||
resetController(controller: Ember.Controller, isExiting: boolean, transition: boolean) {
|
||||
if (isExiting) {
|
||||
// controller.set('page', 1);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Route.extend({
|
||||
setupController(controller: Ember.Controller, model: {}) {
|
||||
this._super(controller, model);
|
||||
this.controllerFor('application').set('model', model);
|
||||
},
|
||||
});
|
||||
|
||||
class RouteUsingClass extends Route.extend({
|
||||
randomProperty: 'the .extend + extends bit type-checks properly',
|
||||
}) {
|
||||
beforeModel(this: RouteUsingClass) {
|
||||
return 'beforeModel can return anything, not just promises';
|
||||
}
|
||||
intermediateTransitionWithoutModel() {
|
||||
this.intermediateTransitionTo('some-route');
|
||||
}
|
||||
intermediateTransitionWithModel() {
|
||||
this.intermediateTransitionTo('some.other.route', { });
|
||||
}
|
||||
intermediateTransitionWithMultiModel() {
|
||||
this.intermediateTransitionTo('some.other.route', 1, 2, { });
|
||||
}
|
||||
}
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
import Ember from 'ember';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
const AppRouter = Ember.Router.extend({
|
||||
});
|
||||
|
||||
AppRouter.map(function() {
|
||||
this.route('index', { path: '/' });
|
||||
this.route('about');
|
||||
this.route('favorites', { path: '/favs' });
|
||||
this.route('posts', function() {
|
||||
this.route('index', { path: '/' });
|
||||
this.route('new');
|
||||
this.route('post', { path: '/post/:post_id', resetNamespace: true });
|
||||
this.route('comments', { resetNamespace: true }, function() {
|
||||
this.route('new');
|
||||
});
|
||||
});
|
||||
this.route('photo', { path: '/photo/:id' }, function() {
|
||||
this.route('comment', { path: '/comment/:id' });
|
||||
});
|
||||
this.route('not-found', { path: '/*path' });
|
||||
this.mount('my-engine');
|
||||
this.mount('my-engine', { as: 'some-other-engine', path: '/some-other-engine'});
|
||||
});
|
||||
|
||||
const RouterServiceConsumer = Ember.Service.extend({
|
||||
router: Ember.inject.service('router'),
|
||||
currentRouteName() {
|
||||
const x: string = Ember.get(this, 'router').currentRouteName;
|
||||
},
|
||||
currentURL() {
|
||||
const x: string = Ember.get(this, 'router').currentURL;
|
||||
},
|
||||
transitionWithoutModel() {
|
||||
Ember.get(this, 'router')
|
||||
.transitionTo('some-route');
|
||||
},
|
||||
transitionWithModel() {
|
||||
const model = Ember.Object.create();
|
||||
Ember.get(this, 'router')
|
||||
.transitionTo('some.other.route', model);
|
||||
},
|
||||
transitionWithMultiModel() {
|
||||
const model = Ember.Object.create();
|
||||
Ember.get(this, 'router')
|
||||
.transitionTo('some.other.route', model, model);
|
||||
},
|
||||
transitionWithModelAndOptions() {
|
||||
const model = Ember.Object.create();
|
||||
Ember.get(this, 'router')
|
||||
.transitionTo('index', model, { queryParams: { search: 'ember' }});
|
||||
}
|
||||
});
|
||||
Executable
+204
@@ -0,0 +1,204 @@
|
||||
import Ember from 'ember';
|
||||
import RSVP from 'rsvp';
|
||||
import { run } from '@ember/runloop';
|
||||
import { assertType } from "./lib/assert";
|
||||
|
||||
assertType<string[]>(Ember.run.queues);
|
||||
|
||||
function testRun() {
|
||||
let r = run(function() {
|
||||
// code to be executed within a RunLoop
|
||||
return 123;
|
||||
});
|
||||
assertType<number>(r);
|
||||
|
||||
function destroyApp(application: Ember.Application) {
|
||||
Ember.run(application, 'destroy');
|
||||
run(application, function() {
|
||||
this.destroy();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function testBind() {
|
||||
Ember.Component.extend({
|
||||
init() {
|
||||
const bound = Ember.run.bind(this, this.setupEditor);
|
||||
bound();
|
||||
},
|
||||
|
||||
editor: null as string | null,
|
||||
|
||||
setupEditor(editor: string) {
|
||||
this.set('editor', editor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function testCancel() {
|
||||
const myContext = {};
|
||||
|
||||
let runNext = run.next(myContext, function() {
|
||||
// will not be executed
|
||||
});
|
||||
|
||||
run.cancel(runNext);
|
||||
|
||||
let runLater = run.later(myContext, function() {
|
||||
// will not be executed
|
||||
}, 500);
|
||||
|
||||
run.cancel(runLater);
|
||||
|
||||
let runScheduleOnce = run.scheduleOnce('afterRender', myContext, function() {
|
||||
// will not be executed
|
||||
});
|
||||
|
||||
run.cancel(runScheduleOnce);
|
||||
|
||||
let runOnce = run.once(myContext, function() {
|
||||
// will not be executed
|
||||
});
|
||||
|
||||
run.cancel(runOnce);
|
||||
|
||||
let throttle = run.throttle(myContext, function() {
|
||||
// will not be executed
|
||||
}, 1, false);
|
||||
|
||||
run.cancel(throttle);
|
||||
|
||||
let debounce = run.debounce(myContext, function() {
|
||||
// will not be executed
|
||||
}, 1);
|
||||
|
||||
run.cancel(debounce);
|
||||
|
||||
let debounceImmediate = run.debounce(myContext, function() {
|
||||
// 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);
|
||||
}
|
||||
|
||||
function testDebounce() {
|
||||
function runIt() {
|
||||
}
|
||||
|
||||
let myContext = { name: 'debounce' };
|
||||
|
||||
run.debounce(runIt, 150);
|
||||
run.debounce(myContext, runIt, 150);
|
||||
run.debounce(myContext, runIt, 150, true);
|
||||
|
||||
Ember.Component.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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function testBegin() {
|
||||
run.begin();
|
||||
// code to be executed within a RunLoop
|
||||
run.end();
|
||||
}
|
||||
|
||||
function testJoin() {
|
||||
run.join(function() {
|
||||
// creates a new run-loop
|
||||
});
|
||||
|
||||
run(function() {
|
||||
// creates a new run-loop
|
||||
run.join(function() {
|
||||
// joins with the existing run-loop, and queues for invocation on
|
||||
// the existing run-loops action queue.
|
||||
});
|
||||
});
|
||||
|
||||
new RSVP.Promise(function(resolve) {
|
||||
Ember.run.later(function() {
|
||||
resolve({ msg: 'Hold Your Horses' });
|
||||
}, 3000);
|
||||
});
|
||||
}
|
||||
|
||||
function testLater() {
|
||||
const myContext = {};
|
||||
run.later(myContext, function() {
|
||||
// code here will execute within a RunLoop in about 500ms with this == myContext
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function testNext() {
|
||||
const myContext = {};
|
||||
run.next(myContext, function() {
|
||||
// code to be executed in the next run loop,
|
||||
// which will be scheduled after the current one
|
||||
});
|
||||
}
|
||||
|
||||
function testOnce() {
|
||||
Ember.Component.extend({
|
||||
init() {
|
||||
Ember.run.once(this, 'processFullName');
|
||||
},
|
||||
|
||||
processFullName() {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function testSchedule() {
|
||||
Ember.Component.extend({
|
||||
init() {
|
||||
run.schedule('sync', this, function() {
|
||||
// this will be executed in the first RunLoop queue, when bindings are synced
|
||||
console.log('scheduled on sync queue');
|
||||
});
|
||||
|
||||
run.schedule('actions', this, function() {
|
||||
// this will be executed in the 'actions' queue, after bindings have synced.
|
||||
console.log('scheduled on actions queue');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Ember.run.schedule('actions', () => {
|
||||
// Do more things
|
||||
});
|
||||
}
|
||||
|
||||
function testScheduleOnce() {
|
||||
function sayHi() {
|
||||
console.log('hi');
|
||||
}
|
||||
|
||||
const myContext = {};
|
||||
run(function() {
|
||||
run.scheduleOnce('afterRender', myContext, sayHi);
|
||||
run.scheduleOnce('afterRender', myContext, sayHi);
|
||||
// sayHi will only be executed once, in the afterRender queue of the RunLoop
|
||||
});
|
||||
run.scheduleOnce('actions', myContext, function() {
|
||||
console.log('Closure');
|
||||
});
|
||||
}
|
||||
|
||||
function testThrottle() {
|
||||
function runIt() {
|
||||
}
|
||||
|
||||
let myContext = { name: 'throttle' };
|
||||
|
||||
run.throttle(runIt, 150);
|
||||
run.throttle(myContext, runIt, 150);
|
||||
}
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
let pending = 0;
|
||||
Ember.Test.registerWaiter(() => pending !== 0);
|
||||
|
||||
declare const MyDb: {
|
||||
hasPendingTransactions(): boolean;
|
||||
};
|
||||
Ember.Test.registerWaiter(MyDb, MyDb.hasPendingTransactions);
|
||||
|
||||
Ember.Test.promise(function(resolve) {
|
||||
window.setTimeout(resolve, 500);
|
||||
});
|
||||
|
||||
Ember.Test.registerHelper('boot', function(app) {
|
||||
Ember.run(app, app.advanceReadiness);
|
||||
});
|
||||
|
||||
Ember.Test.registerAsyncHelper('boot', function(app) {
|
||||
Ember.run(app, app.advanceReadiness);
|
||||
});
|
||||
|
||||
Ember.Test.registerAsyncHelper('waitForPromise', (app, promise) => {
|
||||
return new Ember.Test.Promise((resolve) => {
|
||||
Ember.Test.adapter.asyncStart();
|
||||
|
||||
promise.then(() => {
|
||||
Ember.run.schedule('afterRender', null, resolve);
|
||||
Ember.Test.adapter.asyncEnd();
|
||||
});
|
||||
});
|
||||
});
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
import Ember from 'ember';
|
||||
|
||||
Ember.Route.extend({
|
||||
beforeModel(transition: Ember.Transition) {
|
||||
if (new Date() > new Date('January 1, 1980')) {
|
||||
alert('Sorry, you need a time machine to enter this route.');
|
||||
transition.abort();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Ember.Controller.extend({
|
||||
previousTransition: <Ember.Transition | null> null,
|
||||
|
||||
actions: {
|
||||
login() {
|
||||
// Log the user in, then reattempt previous transition if it exists.
|
||||
let previousTransition = this.get('previousTransition');
|
||||
if (previousTransition) {
|
||||
this.set('previousTransition', null);
|
||||
previousTransition.retry();
|
||||
} else {
|
||||
// Default back to homepage
|
||||
this.transitionToRoute('index');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
Executable
+71
@@ -0,0 +1,71 @@
|
||||
import Ember from 'ember';
|
||||
import * as utils from '@ember/utils';
|
||||
import { assertType } from "./lib/assert";
|
||||
|
||||
function testIsNoneType() {
|
||||
const maybeUndefined: string | undefined = 'not actually undefined';
|
||||
if (utils.isNone(maybeUndefined)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const anotherString = maybeUndefined + 'another string';
|
||||
}
|
||||
|
||||
function testMerge() {
|
||||
assertType<{ first: string, last: string }>(
|
||||
Ember.merge({ first: 'Tom' }, { last: 'Dale' })
|
||||
);
|
||||
}
|
||||
|
||||
function testAssign() {
|
||||
assertType<{ first: string, middle: string, last: string }>(
|
||||
Ember.assign({ first: 'Tom' }, { middle: 'M' }, { last: 'Dale' })
|
||||
);
|
||||
}
|
||||
|
||||
function testOnError() {
|
||||
Ember.onerror = function(error) {
|
||||
Ember.$.post('/report-error', {
|
||||
stack: error.stack,
|
||||
otherInformation: 'whatever app state you want to provide'
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function testMakeArray() {
|
||||
assertType<any[]>(Ember.makeArray());
|
||||
assertType<any[]>(Ember.makeArray(null));
|
||||
assertType<any[]>(Ember.makeArray(undefined));
|
||||
assertType<string[]>(Ember.makeArray('lindsay'));
|
||||
assertType<number[]>(Ember.makeArray([1, 2, 42]));
|
||||
}
|
||||
|
||||
function testDeprecateFunc() {
|
||||
function newMethod(first: string, second: number): string {
|
||||
return '';
|
||||
}
|
||||
|
||||
let oldMethod = Ember.deprecateFunc('Please use the new method', { id: 'deprecated.id', until: '6.0' }, newMethod);
|
||||
assertType<string>(newMethod('first', 123));
|
||||
assertType<string>(oldMethod('first', 123));
|
||||
}
|
||||
|
||||
function testDefineProperty() {
|
||||
const contact = {};
|
||||
|
||||
// ES5 compatible mode
|
||||
Ember.defineProperty(contact, 'firstName', {
|
||||
writable: true,
|
||||
configurable: false,
|
||||
enumerable: true,
|
||||
value: 'Charles'
|
||||
});
|
||||
|
||||
// define a simple property
|
||||
Ember.defineProperty(contact, 'lastName', undefined, 'Jolley');
|
||||
|
||||
// define a computed property
|
||||
Ember.defineProperty(contact, 'fullName', Ember.computed('firstName', 'lastName', function() {
|
||||
return `${this.firstName} ${this.lastName}`;
|
||||
}));
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import Ember from 'ember';
|
||||
import { assertType } from './lib/assert';
|
||||
|
||||
const { ViewUtils: { isSimpleClick } } = Ember;
|
||||
assertType<boolean>(isSimpleClick(new Event('wat')));
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user