Commit fe68c721 authored by Guillaume Perréal's avatar Guillaume Perréal
Browse files

ts: réorganise les sources.

parent cd564342
{% extends '@NgModelGenerator/_layout.ts.twig' %} {% extends '@NgModelGenerator/_layout.ts.twig' %}
{% block content %} {% block content %}
export * from 'irstea-ng-model'; export * from 'irstea-ng-model/types';
export * from './resources'; export * from './resources';
export * from './repositories'; export * from './repositories';
export * from './metadata'; export * from './metadata';
......
...@@ -6,16 +6,15 @@ ...@@ -6,16 +6,15 @@
{% autoescape false %} {% autoescape false %}
import { Injectable, Provider } from '@angular/core'; import { Injectable, Provider } from '@angular/core';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { UUID } from 'irstea-ng-model/types';
import { IRIMetadata, ResourceMetadata } from 'irstea-ng-model/metadata';
import { import {
AbstractAPIService, AbstractAPIService,
AbstractResourceCache, AbstractResourceCache,
APIMeta, APIMeta,
APIRepositoryRegistry, APIRepositoryRegistry,
IRIMetadata, LazyMetadataRegistry,
LazyMetadataRegistry, } from 'irstea-ng-model/api';
ResourceMetadata,
UUID,
} from 'irstea-ng-model';
import { import {
{% for repo in repositories %} {% for repo in repositories %}
......
...@@ -7,17 +7,14 @@ ...@@ -7,17 +7,14 @@
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { HttpResponseBase } from '@angular/common/http'; import { HttpResponseBase } from '@angular/common/http';
import { AbstractRepository, Collection, IRI, RequestOptions, UUID } from 'irstea-ng-model'; import { Collection, IRI, RequestOptions, UUID } from 'irstea-ng-model/types';
import { AbstractRepository } from 'irstea-ng-model/api';
import { hasProperty } from 'irstea-ng-model/helpers';
import { {% for name in repoImports %} import { {% for name in repoImports %}
{{ name }}{% if not loop.last %}, {% endif %} {{ name }}{% if not loop.last %}, {% endif %}
{%- endfor %} {%- endfor %}
} from './resources'; } from './resources';
// Simple type guard helper for object with keys
function hasProperty<T extends string|number|symbol>(what: unknown, key: T): what is { [key in T]: any; } {
return typeof what === 'object' && what !== null && key in what;
}
/********************************************************************************* /*********************************************************************************
* Repositories * Repositories
*********************************************************************************/ *********************************************************************************/
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
{% block content %} {% block content %}
{% autoescape false %} {% autoescape false %}
import { DateTime, IRI, UUID } from 'irstea-ng-model'; import { DateTime, IRI, UUID } from 'irstea-ng-model/types';
/********************************************************************************* /*********************************************************************************
* Ressources * Ressources
......
import { forkJoin, Observable } from 'rxjs'; import { forkJoin, Observable } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http'; import { HttpClient, HttpResponseBase } from '@angular/common/http';
import { IRI, Resource } from './resource'; import { IRI, Resource, Collection, RequestOptions } from './types';
import { IRIParameters, ResourceMetadata } from './metadata'; import { IRIParameters, ResourceMetadata } from './metadata';
import { AbstractRepository } from './repositories';
import { AbstractResourceCache } from './cache';
/** /**
* Options supplémentaires pour les requêtes. * AbstractResourceCache est une classe abstraite qui définit l'interface d'un cache de ressources.
*
* Elle doit être implémentée puis être fournie en provider d'un module core. Par exemple:
*
* final class ResourceCache<T extends Resource> extends AbstractResourceCache<T> {
* // Implémentation
* }
*
* providers: [
* [ provider: AbstractResourceCache, useClass: ResourceCache ],
* ]
*/ */
export interface RequestOptions {
body?: any; export abstract class AbstractResourceCache {
headers?: /**
| HttpHeaders * Récupère une ressource par son IRI. N'exécute la requête requestFactory que si on ne dispose
| { * pas d'une version en cache.
[header: string]: string | string[]; */
}; public abstract get<R extends Resource>(
params?: { [param: string]: string | string[] }; iri: IRI<R>,
requestFactory: () => Observable<R>,
): Observable<R>;
/**
* Met à jour une ressource existante, rafraîchit le cache local avec la réponse.
*/
public abstract put<R extends Resource>(
iri: IRI<R>,
request: Observable<R>,
): Observable<R>;
/**
* Crée une nouvelle ressource et met la ressource créée dans le cache.
*/
public abstract post<R extends Resource>(
request: Observable<R>,
): Observable<R>;
/**
* Supprime une ressource en distant et dans le cache.
*/
public abstract delete<R extends Resource>(
iri: IRI<R>,
request: Observable<HttpResponseBase>,
): Observable<HttpResponseBase>;
/**
* Effectue une recherche et met en cache toutes les ressources récupérées.
*/
public abstract getAll<R extends Resource>(
request: Observable<Collection<R>>,
): Observable<Collection<R>>;
/**
* Invalide une ressource en cache.
*/
public abstract invalidate<R extends Resource>(iri: IRI<R>): void;
}
/**
* Classe de base d'un repository.
*/
export abstract class AbstractRepository<
R extends Resource,
T extends string,
P extends IRIParameters
> {
public constructor(
public readonly metadata: ResourceMetadata<R, T, P>,
protected readonly client: HttpClient,
protected readonly cache: AbstractResourceCache,
) {}
/**
* Génère une IRI à partir de ses paramètres.
*/
public generateIRI(parameters: P): IRI<R> {
return this.metadata.generateIRI(parameters);
}
/**
* Extrait les paramètres d'une IRI.
*/
public getIRIParameters(iri: IRI<R>): P {
return this.metadata.getIRIParameters(iri);
}
} }
/** /**
......
...@@ -6,7 +6,6 @@ import { forkJoinArray } from 'rxjs-etc'; ...@@ -6,7 +6,6 @@ import { forkJoinArray } from 'rxjs-etc';
import { ValueHolder } from './value-holder'; import { ValueHolder } from './value-holder';
import { import {
AbstractResourceCache,
Collection, Collection,
COLLECTION_MEMBERS, COLLECTION_MEMBERS,
getCollectionMembers, getCollectionMembers,
...@@ -14,6 +13,7 @@ import { ...@@ -14,6 +13,7 @@ import {
IRI_PROPERTY, IRI_PROPERTY,
Resource, Resource,
} from '../types'; } from '../types';
import { AbstractResourceCache } from '../api';
/** /**
* Implémentation d'un cache de resource. * Implémentation d'un cache de resource.
......
export * from './cache.service'; export * from './cache.service';
export * from './errors';
import { forkJoin } from 'rxjs'; import { forkJoin } from 'rxjs';
import { IRI, IRI_PROPERTY, Resource } from '../types'; import { IRI, IRI_PROPERTY, Resource } from '../types';
import { ValueHolder } from './value-holder'; import { ValueHolder } from './value-holder';
import { IRIMismatchError, MissingIRIError } from './errors'; import { IRIMismatchError, MissingIRIError } from '../types/errors';
import { forkJoinArray } from 'rxjs-etc'; import { forkJoinArray } from 'rxjs-etc';
import { marbles } from 'rxjs-marbles'; import { marbles } from 'rxjs-marbles';
import { cases } from 'rxjs-marbles/jest'; import { cases } from 'rxjs-marbles/jest';
......
import { Observable, of, race, Subject, throwError } from 'rxjs'; import { Observable, of, race, Subject, throwError } from 'rxjs';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { switchMap, take } from 'rxjs/operators'; import { switchMap, take } from 'rxjs/operators';
import { IRI, IRI_PROPERTY, Resource } from '../types';
import { IRIMismatchError, MissingIRIError } from './errors'; import {
IRI,
IRI_PROPERTY,
Resource,
IRIMismatchError,
MissingIRIError,
} from '../types';
/** /**
* ValueHolder gère les requêtes d'une seule ressource. * ValueHolder gère les requêtes d'une seule ressource.
......
// Helper type-guard
// Checks that an object has a defined value for the given property.
export function hasProperty<
T extends { [name: string]: any },
K extends keyof T
>(obj: T, property: K): obj is T & { [X in K]-?: T[X] } {
return (
typeof obj === 'object' && obj !== null && obj[property] !== undefined
);
}
export * from './types'; export * from './types';
export * from './cache';
/** /**
* Type des paramètrès * Type des paramètrès
*/ */
import { IRI, Resource, TYPE_PROPERTY } from './resource'; import { IRI, Resource, TYPE_PROPERTY } from './types';
type IRIParameter = string | number; type IRIParameter = string | number;
export type IRIParameters = IRIParameter[] | IRIParameter; export type IRIParameters = IRIParameter[] | IRIParameter;
......
import { IRI, Resource } from './resource';
import { Observable } from 'rxjs';
import { HttpResponseBase } from '@angular/common/http';
import { Collection } from './collection';
/**
* AbstractResourceCache est une classe abstraite qui définit l'interface d'un cache de ressources.
*
* Elle doit être implémentée puis être fournie en provider d'un module core. Par exemple:
*
* final class ResourceCache<T extends Resource> extends AbstractResourceCache<T> {
* // Implémentation
* }
*
* providers: [
* [ provider: AbstractResourceCache, useClass: ResourceCache ],
* ]
*/
export abstract class AbstractResourceCache {
/**
* Récupère une ressource par son IRI. N'exécute la requête requestFactory que si on ne dispose
* pas d'une version en cache.
*/
public abstract get<R extends Resource>(
iri: IRI<R>,
requestFactory: () => Observable<R>,
): Observable<R>;
/**
* Met à jour une ressource existante, rafraîchit le cache local avec la réponse.
*/
public abstract put<R extends Resource>(
iri: IRI<R>,
request: Observable<R>,
): Observable<R>;
/**
* Crée une nouvelle ressource et met la ressource créée dans le cache.
*/
public abstract post<R extends Resource>(
request: Observable<R>,
): Observable<R>;
/**
* Supprime une ressource en distant et dans le cache.
*/
public abstract delete<R extends Resource>(
iri: IRI<R>,
request: Observable<HttpResponseBase>,
): Observable<HttpResponseBase>;
/**
* Effectue une recherche et met en cache toutes les ressources récupérées.
*/
public abstract getAll<R extends Resource>(
request: Observable<Collection<R>>,
): Observable<Collection<R>>;
/**
* Invalide une ressource en cache.
*/
public abstract invalidate<R extends Resource>(iri: IRI<R>): void;
}
import { IRI_PROPERTY } from '../types'; import { IRI_PROPERTY } from './index';
export class APICacheError extends Error {} export class APICacheError extends Error {}
......
export * from './api';
export * from './cache';
export * from './collection'; export * from './collection';
export * from './metadata'; export * from './errors';
export * from './misc'; export * from './misc';
export * from './repositories'; export * from './request';
export * from './resource'; export * from './resource';
import { HttpClient } from '@angular/common/http';
import { IRI, Resource } from './resource';
import { IRIParameters, ResourceMetadata } from './metadata';
import { AbstractResourceCache } from './cache';
/**
* Classe de base d'un repository.
*/
export abstract class AbstractRepository<
R extends Resource,
T extends string,
P extends IRIParameters
> {
public constructor(
public readonly metadata: ResourceMetadata<R, T, P>,
protected readonly client: HttpClient,
protected readonly cache: AbstractResourceCache,
) {}
/**
* Génère une IRI à partir de ses paramètres.
*/
public generateIRI(parameters: P): IRI<R> {
return this.metadata.generateIRI(parameters);
}
/**
* Extrait les paramètres d'une IRI.
*/
public getIRIParameters(iri: IRI<R>): P {
return this.metadata.getIRIParameters(iri);
}
}
import { HttpHeaders } from '@angular/common/http';
/**
* Options supplémentaires pour les requêtes.
*/
export interface RequestOptions {
body?: any;
headers?:
| HttpHeaders
| {
[header: string]: string | string[];
};
params?: { [param: string]: string | string[] };
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment