Skip to content
This repository has been archived by the owner on Jan 4, 2019. It is now read-only.

Feature/content lifecycle events #26

Merged
merged 38 commits into from
Jul 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
0a142ee
refactor(ControlMapper): ActionName always required
gallayl Jun 13, 2017
6eeb562
chore(Generated TS files): Updated ContentTypes, Enums, FieldSettings…
gallayl Jun 16, 2017
74c8ce9
refactor(GetSchema,Content Field assign): Refactored getting Schema, …
gallayl Jun 16, 2017
ac2ff9a
refactor(ContentTypes): Modified Date fields to work with ISO Date st…
gallayl Jun 27, 2017
720d8a6
feat(Content): added content lifecycle tracking methods and properties
gallayl Jun 27, 2017
47606f6
fix(IRepository): fixed missing spread operator type
gallayl Jun 27, 2017
13690f2
fix(ODataApi, IODataApi): fixed missing Spread operator types, fixed …
gallayl Jun 27, 2017
d9bf82a
feat(Content): improved Save() to work without parameters, based on t…
gallayl Jun 27, 2017
d42563b
test(ContentTests): Added and improved unit tests, additional tests f…
gallayl Jun 27, 2017
5c6ba67
test(Collection tests):
gallayl Jun 27, 2017
71609fa
fix: package.json merge
gallayl Jun 28, 2017
a06e874
fix(TypeScript 2.4): TypeScript 2.4 Fixes for type constraints
gallayl Jun 28, 2017
12c2db3
feat(Content): implemented IsOperationInProgress flag to contents
gallayl Jun 28, 2017
26b4c07
fix(tsconfig): added skipLibCheck(RxJs type declaration workaround)
gallayl Jun 29, 2017
536d28e
ci(Travis): added node.js 8 to build targets
gallayl Jun 29, 2017
9ef5cde
fix(BaseHttpProvider and Tests): fixed UnsetGlobalHeaders
gallayl Jun 29, 2017
50e2d38
test(Content): GetEffectiveAllowedChildTypes Id existance test
gallayl Jun 29, 2017
46b8541
fix(Content): fixed GetChanges() and IsDirty for non-loaded fields
gallayl Jun 29, 2017
1523f67
refactor(Collection): Default parameters instead of inline checking
gallayl Jun 29, 2017
1b97cf3
refactor(Content): Id and Path checking moved to deferredFunctionBuil…
gallayl Jun 29, 2017
809c448
test(Retrier): Added test when started twice, or tried to setup after…
gallayl Jun 29, 2017
49ecaae
refactor(Generics): removed IOdataApi and IRepository (generic type c…
gallayl Jun 29, 2017
4153584
refactor(ODataApi, Content, Repository): Added missing conversions on…
gallayl Jun 29, 2017
9f96785
fix(package.json): fixed lint script
gallayl Jun 30, 2017
146205a
chore(tslint): cleanup, added rule: no-unused-variables
gallayl Jun 30, 2017
1afaeb0
chore(tslint): added no-unused-expressions and only-arrow-functions
gallayl Jun 30, 2017
a75e3e3
chore(tsconfig): added noUnusedLocals
gallayl Jun 30, 2017
0b6d0f6
refactor(Content): added FromResponseObservable and FromCollectionRes…
gallayl Jun 30, 2017
183b004
fix(ODataHelper, ODataParams): fixed null checks, added scenario para…
gallayl Jun 30, 2017
db5d3d2
refactor(Content): added GetDeferredField and GetDeferredCollection t…
gallayl Jun 30, 2017
bebe36a
fix(RxAjaxHttpProvider): workaround for the withCredential flag hasn'…
gallayl Jul 3, 2017
0c69b0c
fix(Content): fixed GetSchema() when you have only Content, but the T…
gallayl Jul 3, 2017
347dd37
fix(Content): fixed Content.Children() IsSaved property
gallayl Jul 4, 2017
3b0df1e
fix(RxAjaxHttpProvider): fixed send post body
gallayl Jul 4, 2017
fa8223c
refactor(ODataApi): ODataCollectionResponse, ODataResponse and ODataA…
gallayl Jul 4, 2017
3f38d4f
fix(Content): GetFields() return fields with non-undefined value
gallayl Jul 4, 2017
8622200
test(Content): Added test for Actions() and fail test to GetSchema()
gallayl Jul 4, 2017
0ab1b51
test(Content): added tests for Children()
gallayl Jul 4, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ cache:
notifications:
email: false
node_js:
- '8'
- '7'
- '6'
before_script:
Expand Down
28 changes: 18 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sn-client-js",
"version": "2.0.0-RC.4",
"version": "2.0.0-RC.4-development2",
"description": "A JavaScript client for Sense/Net ECM that makes it easy to use the REST API of the Content Repository.",
"main": "dist/src/SN.js",
"files": [
Expand All @@ -11,7 +11,7 @@
"coverage"
],
"scripts": {
"lint": "node tslint --project ./tsconfig.json",
"lint": "./node_modules/.bin/tslint --project tsconfig.json --type-check",
"clean": "rimraf dist",
"precommit": "npm run lint",
"commit": "git-cz",
Expand Down Expand Up @@ -57,7 +57,7 @@
},
"homepage": "https://sensenet.com",
"dependencies": {
"@reactivex/rxjs": "^5.4.0",
"@reactivex/rxjs": "^5.4.1",
"nyc": "^11.0.2",
"ts-json-properties": "1.2.0"
},
Expand All @@ -73,21 +73,29 @@
"del": "3.0.0",
"fs-then-native": "2.0.0",
"gulp": "3.9.1",
"gulp-typedoc": "2.0.2",
"gulp-run": "^1.7.1",
"gulp-rename": "^1.2.2",
"istanbul": "0.4.5",
"jsdoc-to-markdown": "3.0.0",
"gulp-run": "^1.7.1",
"gulp-typedoc": "2.0.2",
"highlight.js": "^9.12.0",
"istanbul": "^0.4.5",
"jsdoc-to-markdown": "^3.0.0",
"lru-cache": "^4.1.1",
"mocha": "3.4.2",
"mocha-typescript": "^1.0.23",
"natives": "^1.1.0",
"progress": "^2.0.0",
"rimraf": "^2.6.1",
"semantic-release": "^6.3.6",
"ts-json-properties": "1.2.0",
"tslint": "^5.2.0",
"sigmund": "^1.0.1",
"through2": "^2.0.3",
"ts-json-properties": "^1.2.0",
"tslint": "^5.4.3",
"typedoc": "^0.7.0",
"typedoc-default-themes": "^0.5.0",
"typedoc-md-theme": "^1.0.1",
"typedoc-plugin-external-module-name": "^1.0.9",
"typescript": "2.3.4"
"typescript": "2.4.1",
"universalify": "^0.1.0"
},
"czConfig": {
"path": "node_modules/cz-conventional-changelog"
Expand Down
1 change: 0 additions & 1 deletion src/Authentication/IAuthenticationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import { Observable } from '@reactivex/rxjs';
import { LoginState } from './';
import { HttpProviders } from '../SN';

/**
* Interface that describes how injectable Authentication Services should work
Expand Down
3 changes: 1 addition & 2 deletions src/Authentication/JwtService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* @description This module that contains authentication-related classes, types and interfaces
*/ /** */

import { LoginState, LoginResponse, RefreshResponse, ITokenPayload, Token, TokenStore, IAuthenticationService, TokenPersist } from './';
import { LoginState, LoginResponse, RefreshResponse, Token, TokenStore, IAuthenticationService, TokenPersist } from './';
import { Subject, BehaviorSubject, Observable } from '@reactivex/rxjs';
import { BaseHttpProvider } from '../HttpProviders/BaseHttpProvider';
import { ODataHelper } from '../SN';
Expand Down Expand Up @@ -59,7 +59,6 @@ export class JwtService implements IAuthenticationService {
* @returns {Observable<boolean>} An observable that will be completed with true on a succesfull refresh
*/
private ExecTokenRefresh() {
let refreshBase64 = this.TokenStore.RefreshToken.toString();
let refresh = this.httpProviderRef.Ajax(RefreshResponse, {
method: 'POST',
url: ODataHelper.joinPaths(this.repositoryUrl, 'sn-token/refresh'),
Expand Down
6 changes: 3 additions & 3 deletions src/Authentication/TokenStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export class TokenStore {

if (!storesAvailable && !cookieAvailable) {
this.TokenStoreType = TokenStoreType.InMemory;
} else if (tokenPersist === TokenPersist.Expiration) {
} else if (this.tokenPersist === TokenPersist.Expiration) {
storesAvailable ? this.TokenStoreType = TokenStoreType.LocalStorage : this.TokenStoreType = TokenStoreType.ExpirationCookie;
} else {
storesAvailable ? this.TokenStoreType = TokenStoreType.SessionStorage : this.TokenStoreType = TokenStoreType.SessionCookie;
Expand Down Expand Up @@ -85,7 +85,7 @@ export class TokenStore {
try {
switch (this.TokenStoreType) {
case TokenStoreType.InMemory:
return Token.FromHeadAndPayload(this.innerStore[storeKey]);
return Token.FromHeadAndPayload(this.innerStore[storeKey as any]);
case TokenStoreType.LocalStorage:
return Token.FromHeadAndPayload((this.localStorageRef as any).getItem(storeKey));
case TokenStoreType.SessionStorage:
Expand All @@ -111,7 +111,7 @@ export class TokenStore {
let dtaString = token.toString();
switch (this.TokenStoreType) {
case TokenStoreType.InMemory:
this.innerStore[storeKey] = dtaString;
this.innerStore[storeKey as any] = dtaString;
break;
case TokenStoreType.LocalStorage:
this.localStorageRef && this.localStorageRef.setItem(storeKey, dtaString);
Expand Down
50 changes: 26 additions & 24 deletions src/Collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
*/ /** */

import { Observable } from '@reactivex/rxjs';
import { IODataApi, CustomAction, IODataParams, ODataRequestOptions } from './ODataApi';
import { CustomAction, IODataParams, ODataRequestOptions } from './ODataApi';
import { ODataHelper } from './SN';
import { IContent } from './Repository';
import { Content } from './Content';
import { BaseRepository } from './Repository/BaseRepository';

export class Collection<T extends IContent> {
export class Collection<T extends Content> {
Path: string = '';

/**
Expand All @@ -21,7 +22,8 @@ export class Collection<T extends IContent> {
* @param { IODataApi<any, any> } service The service to use as API Endpoint
*/
constructor(private items: T[],
private service: IODataApi<any, T>) {
private repository: BaseRepository,
private readonly contentType: {new(...args: any[]): T} = Content.constructor as {new(...args: any[]): any}) {
}

/**
Expand Down Expand Up @@ -75,8 +77,11 @@ export class Collection<T extends IContent> {
* });
* ```
*/
public Add(content: T): Observable<T> {
const newcontent = this.service.Post<T>(this.Path, content);
public Add(content: T['options']): Observable<T> {
const newcontent = this.repository.Content.Post(this.Path, content, this.contentType)
.map(resp => {
return Content.HandleLoadedContent(content.constructor as {new(...args)}, resp, this.repository);
});
newcontent
.subscribe({
next: (response) => {
Expand Down Expand Up @@ -136,7 +141,7 @@ export class Collection<T extends IContent> {
this.items.slice(0, arg)
.concat(this.items.slice(arg + 1));

return this.service.Delete(content.Id, permanently ? permanently : false);
return this.repository.Content.Delete(content.Id, permanently ? permanently : false);
} else {
return Observable.of(undefined);
}
Expand All @@ -146,7 +151,7 @@ export class Collection<T extends IContent> {
this.items =
this.items.filter((item, i) => arg.indexOf(i) > -1);
let action = new CustomAction({ name: 'DeleteBatch', path: this.Path, isAction: true, requiredParams: ['paths'] });
return this.service.CreateCustomAction(action, { data: [{ 'paths': ids }, { 'permanently': permanently }] });
return this.repository.Content.CreateCustomAction(action, { data: [{ 'paths': ids }, { 'permanently': permanently }] });
}
}
/**
Expand Down Expand Up @@ -179,11 +184,11 @@ export class Collection<T extends IContent> {
}
o['path'] = path;
let optionList = new ODataRequestOptions(o as ODataRequestOptions);
const children = this.service.Fetch<T>(optionList);
const children = this.repository.Content.Fetch<T>(optionList);
children
.subscribe(
(items) => {
this.items = items.d.results;
this.items = items.d.results.map(c => Content.HandleLoadedContent(this.contentType, c, this.repository));
}
);
return children;
Expand Down Expand Up @@ -226,19 +231,18 @@ export class Collection<T extends IContent> {
public Move(items: number[], targetPath: string): Observable<any>;
public Move(arg: any, targetPath: string): Observable<any> {
if (typeof arg === 'number') {
let content = this.items[arg];
this.items =
this.items.slice(0, arg)
.concat(this.items.slice(arg + 1));
let action = new CustomAction({ name: 'Move', id: arg, isAction: true, requiredParams: ['targetPath'] });
return this.service.CreateCustomAction(action, { data: [{ 'targetPath': targetPath }] });
return this.repository.Content.CreateCustomAction(action, { data: [{ 'targetPath': targetPath }] });
}
else {
let ids = arg.map(i => this.items[i].Id);
this.items =
this.items.filter((item, i) => arg.indexOf(i) > -1);
let action = new CustomAction({ name: 'MoveBatch', path: this.Path, isAction: true, requiredParams: ['paths', 'targetPath'] });
return this.service.CreateCustomAction(action, { data: [{ 'paths': ids, 'targetPath': targetPath }] });
return this.repository.Content.CreateCustomAction(action, { data: [{ 'paths': ids, 'targetPath': targetPath }] });
}
}
/**
Expand Down Expand Up @@ -279,14 +283,13 @@ export class Collection<T extends IContent> {
public Copy(items: number[], targetPath: string): Observable<any>;
public Copy(arg: any, targetPath: string): Observable<any> {
if (typeof arg === 'number') {
let content = this.items[arg];
let action = new CustomAction({ name: 'Copy', id: arg, isAction: true, requiredParams: ['targetPath'] });
return this.service.CreateCustomAction(action, { data: [{ 'targetPath': targetPath }] });
return this.repository.Content.CreateCustomAction(action, { data: [{ 'targetPath': targetPath }] });
}
else {
let ids = arg.map(i => this.items[i].Id);
let action = new CustomAction({ name: 'CopyBatch', path: this.Path, isAction: true, requiredParams: ['paths', 'targetPath'] });
return this.service.CreateCustomAction(action, { data: [{ 'paths': ids, 'targetPath': targetPath }] });
return this.repository.Content.CreateCustomAction(action, { data: [{ 'paths': ids, 'targetPath': targetPath }] });
}
}
/**
Expand All @@ -311,7 +314,7 @@ export class Collection<T extends IContent> {
}
o['path'] = ODataHelper.getContentURLbyPath(this.Path);
let optionList = new ODataRequestOptions(o as ODataRequestOptions);
return this.service.Get<T>(optionList);
return this.repository.Content.Get<T>(optionList);
}
/**
* Uploads a stream or text to a content binary field (e.g. a file).
Expand All @@ -328,30 +331,29 @@ export class Collection<T extends IContent> {
* @params {FileText} In case you do not have the file as a real file in the file system but a text in the browser, you can provide the raw text in this parameter.
* @returns {Observable} Returns an RxJS observable that you can subscribe of in your code.
*/
public Upload(contentType: string, fileName: string, overwrite?: boolean, useChunk?: boolean, propertyName?: string, fileText?: string): Observable<any> {
const o = overwrite ? overwrite : true;
public Upload(contentType: string, fileName: string, overwrite: boolean = true, useChunk: boolean = false, propertyName?: string, fileText?: string): Observable<any> {
const data = {
ContentType: contentType,
FileName: fileName,
Overwrite: o,
UseChunk: useChunk ? useChunk : false
Overwrite: overwrite,
UseChunk: useChunk
};
if (typeof propertyName !== 'undefined') {
data['PropertyName'] = propertyName;
}
if (typeof fileText !== 'undefined') {
data['FileText'] = fileText;
}
let uploadCreation = this.service.Upload(this.Path, data, true);
let uploadCreation = this.repository.Content.Upload(this.Path, data, true);
uploadCreation.subscribe({
next: (response) => {
const data = {
ContentType: contentType,
FileName: fileName,
Overwrite: o,
Overwrite: overwrite,
ChunkToken: response
};
return this.service.Upload(this.Path, data, false);
return this.repository.Content.Upload(this.Path, data, false);
}
});
return uploadCreation;
Expand Down
2 changes: 1 addition & 1 deletion src/Config/snconfigfielddecorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { SnConfigFieldModelStore } from './snconfigfieldmodelstore';
* @returns {function(SnConfigModel)} A factory method which fills the SnConfigModelStore
* with for the decorated field with the provided field model data
*/
export function SnConfigField(model: SnConfigFieldModel) {
export const SnConfigField = (model: SnConfigFieldModel) => {
return (target: any, propertyName: string) => {
model.FieldName = propertyName;
model.StoreKey = `${target.constructor.name}.${propertyName}`;
Expand Down
Loading