npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ngx-los

v9.2.1

Published

[![npm version](https://badge.fury.io/js/ngx-los.svg)](https://badge.fury.io/js/ngx-los)

Downloads

99

Readme

ngx-los

npm version

Contenido

  1. Iniciando proyecto en Angular
  2. Requisitos
  3. Instalación
  4. SCSS
  5. HTML
  6. Configuración de enviroments
  7. Configuración de Angular CLI
  8. Configuración de package.json
  9. Configuración de Suscripciones de Graphql
  10. Configuración de Sentry
  11. Redux
  12. Errores de Graphql
  13. AppModule
  14. AppComponent HTML
  15. AppComponent TS

Iniciar proyecto en Angular

Para iniciar un proyecto que contenga la seguridad de LOS es necesario contar con la versión 9 de Angular, para validar que versión tienes instalada es necesario teclear en consola lo siguiente:

ng version

Se tendrá que mostrar en pantalla la versión de Angular CLI y tendrá que ser la 9 mas estable.


     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 9.1.3
Node: 12.16.1
OS: win32 x64

Angular: 9.1.3
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.901.3
@angular-devkit/build-angular      0.901.3
@angular-devkit/build-ng-packagr   0.901.3
@angular-devkit/build-optimizer    0.901.3
@angular-devkit/build-webpack      0.901.3
@angular-devkit/core               9.1.3
@angular-devkit/schematics         9.1.3
@angular/cdk                       9.2.1
@angular/flex-layout               9.0.0-beta.29
@angular/material                  9.2.1
@ngtools/webpack                   9.1.3
@schematics/angular                9.1.3
@schematics/update                 0.901.3
ng-packagr                         9.1.1
rxjs                               6.5.5
typescript                         3.8.3
webpack                            4.42.0

Confirmando que tenemos la versión 9 mas estable, procedemos a crear el proyecto con el siguiente comando.

ng new [Nombre-aplicación] --style=scss

Nota: El nombre de las aplicaciones debe ser escrito en minúsculas y separadas por un signo de menos (-) en caso de ser dos palabras. Agregamos el argumento --style=scss para indicarle que queremos usar scss en nuestro proyecto

Creará la plantilla base de Angular necesaria para trabajar e instalará todos las dependencias de npm.

CREATE nombre-aplicacion/angular.json (3742 bytes)
CREATE nombre-aplicacion/package.json (1293 bytes)
CREATE nombre-aplicacion/README.md (1033 bytes)
CREATE nombre-aplicacion/tsconfig.json (489 bytes)
CREATE nombre-aplicacion/tslint.json (3125 bytes)
CREATE nombre-aplicacion/.editorconfig (274 bytes)
CREATE nombre-aplicacion/.gitignore (631 bytes)
CREATE nombre-aplicacion/browserslist (429 bytes)
CREATE nombre-aplicacion/karma.conf.js (1029 bytes)
CREATE nombre-aplicacion/tsconfig.app.json (210 bytes)
CREATE nombre-aplicacion/tsconfig.spec.json (270 bytes)
CREATE nombre-aplicacion/src/favicon.ico (948 bytes)
CREATE nombre-aplicacion/src/index.html (302 bytes)
CREATE nombre-aplicacion/src/main.ts (372 bytes)
CREATE nombre-aplicacion/src/polyfills.ts (2835 bytes)
CREATE nombre-aplicacion/src/styles.scss (80 bytes)
CREATE nombre-aplicacion/src/test.ts (753 bytes)
CREATE nombre-aplicacion/src/assets/.gitkeep (0 bytes)
CREATE nombre-aplicacion/src/environments/environment.prod.ts (51 bytes)
CREATE nombre-aplicacion/src/environments/environment.ts (662 bytes)
CREATE nombre-aplicacion/src/app/app.module.ts (314 bytes)
CREATE nombre-aplicacion/src/app/app.component.html (25725 bytes)
CREATE nombre-aplicacion/src/app/app.component.spec.ts (975 bytes)
CREATE nombre-aplicacion/src/app/app.component.ts (222 bytes)
CREATE nombre-aplicacion/src/app/app.component.scss (0 bytes)
CREATE nombre-aplicacion/e2e/protractor.conf.js (808 bytes)
CREATE nombre-aplicacion/e2e/tsconfig.json (214 bytes)
CREATE nombre-aplicacion/e2e/src/app.e2e-spec.ts (650 bytes)
CREATE nombre-aplicacion/e2e/src/app.po.ts (301 bytes)
- Installing packages...
√ Packages installed successfully.
    Successfully initialized git.

Una vez finalice con la leyenda de Successfully initialized git. tendremos listo nuestra plantilla base de Angular 9 lista para hacer la instalación de nuestra plantilla de seguridad.

Requisitos

Una vez creado el proyecto es necesario realizar la instalación de Angular Material mediante el siguiente comando.

ng add @angular/material

El proceso de instalación nos pedirá seleccionar un tema por defecto, seleccionamos Indigo/Pink. También nos preguntará si queremos establecer globalmente la tipografía de Angular Material, ademas de las animaciones del navegador, aceptamos ambas.

Skipping installation: Package already installed
? Choose a prebuilt theme name, or "custom" for a custom theme: Indigo/Pink[ Preview: https://material.angular.io?theme=indigo-pink ]
? Set up global Angular Material typography styles? Yes
? Set up browser animations for Angular Material? Yes

```bash
Installing packages for tooling via npm.
Installed packages for tooling via npm.
UPDATE package.json (1357 bytes)
- Installing packages...
√ Packages installed successfully.
UPDATE src/app/app.module.ts (423 bytes)
UPDATE angular.json (3908 bytes)
UPDATE src/index.html (496 bytes)
UPDATE src/styles.scss (181 bytes)

(Opcional) Para verficar que se realizo la instalacion correctamente podemos mostrar un componente de Angular material en pantalla realizando la importacion del modulo corresponiente del componente que queremos usar, en este caso un mat-slider

import { MatSliderModule } from '@angular/material/slider';
…
@NgModule ({....
  imports: [...,
  MatSliderModule,
…]
})

Agregamos el tag <mat-slider> a nuestro app.component.html como sigue:

<mat-slider min="1" max="100" step="1" value="1"></mat-slider>

Ejecutamos nuestra aplicacion con el comando ng serve ingresa en el explorador a la direccio http://localhost:4200 Deberias ver el componente mat-slider en pantalla.

Instalación

Para la instalación comenzaremos con la siguiente instrucción dentro del proyecto vacío.

npm i ngx-los

SCSS

Es necesario configurar el SCSS para heredar todos los temas diseñados para la plantilla, buscamos el archivo de estilos de capas localizado en src/styles.scss y agregamos la siguiente línea.

@import "~ngx-los/theme.scss";

HTML

En la seccion <head> agregamos la siguiente linea de codigo html

<link
  href="https://fonts.googleapis.com/icon?family=Material+Icons|Assistant|ZCOOL+XiaoWei"
  rel="stylesheet"
/>

El cuerpo <body> lo dejaremos de la siguiente manera.

<body>
  <app-root>
    <div class="app-loading">
      <div class="logo"></div>
      <svg class="spinner" viewBox="25 25 50 50">
        <circle
          class="path"
          cx="50"
          cy="50"
          r="20"
          fill="none"
          stroke-width="2"
          stroke-miterlimit="10"
        />
      </svg>
    </div>
  </app-root>
</body>

Esto para dejar un "loading" cuando la pagina aun se este cargando.

Configuración de enviroments

Nota: Nota: Los archivos de ambiente deben hacer referencia al archivo package.json para realizar la importación del mismo es necesario agregar la siguiente configuracion en el archivo tsconfig.json.

{
	"compilerOptions": {
        ...
		"resolveJsonModule": true,
	}
}

Para hacer la configuración de ambientes es necesario tener la siguiente estructura en los archivos localizados en src/enviroments/enviroment.ts y src/enviroments/enviroment.prod.ts con su respectiva información de ambiente.

El archivo tiene que contener lo siguiente

import * as packagejson from "../../package.json";
export const environment = {
  production: false,
  app: {
    id: "",
    version: packagejson.version,
    commit: "{COMMIT}",
    branch: "{BRANCH}",
    clientId: "",
    clientSecret: "",
    urls: [
      {
        key: "oauth",
        value: "http://host/url_endpoint_token",
      },
      {
        key: "login",
        value: "host/url_login",
      },
    ],
    sentry: {
      dsn: "http://url_sentry",
      showReportDialog: false,
    },
  },
  template: {
    storageName: "storage-name",
    graphql: {
      uri: "host/url_endpoint_graphql",
      subscriptions: {
        enabled: true,
        uri: "ws://url_endpoint_graphql_subscriptions",
      },
    },
  },
  header: {
    title: "Titulo de Apliacion",
    theme: "nombre-tema",
    darkTheme: false,
    colorThemeVisible: true,
    fullScreenVisible: true,
    wishHappyBirthday: true,
  },
  sidemenu: {
    menuOpen: true,
    menuOpenApps: false,
    selectRoomsVisible: true,
  },
};

| Llave | Descripción | | ---------------------------------------- | ----------------------------------------------------------------------------------------------------- | | production | Saber si el ambiente es producción | | urls | Contiene todas las URLs necesarias para el proyecto | | urls.auth | Validar credenciales de acceso | | urls.auth.host | URL para validar credenciales de acceso | | urls.auth.path.token | End point para solicitar el token de acceso | | urls.auth.path.userChangePassword | End point para que el usuario pueda cambiar su contraseña | | app.id | Id de la aplicación | | app.version | Version de la aplicacion obtenida del archivo package.json | | app.commit | Id de commit del Git (este campo lo remplaza automaticamente gitlab) | | app.branch | Branch de Git (este campo lo remplaza automaticamente gitlab) | | app.clientId | Identificador client de la aplicacion | | app.clientSecret | Secreto de aplicación cliente | | app.urls | Arreglo con las urls que usara la aplicacion | | app.urls[indice].key | llave para accesar al elemento en el arreglo | | app.urls[indice].value | valor de la url | | app.sentry.dsn | (Data Source Name) es la URL que representa la configuracion requerida por sentry | | app.showReportDialog | Indica si se debe mostrar el dialog de feedback de usuario cuando se presenta un error | | template.storageName | Nombre de la llave que se usara para guardar el token de la aplicacion en el storage | | template.graphql.subscriptions.enabled | Indica si el socket de suscripciones estara habilitado | | template.graphql.subscriptions.uri | url del socket de suscripciónes de graphql | | template.graphql.uri | url del endpoint de graphql que usará el template | | header.title | Titulo de la aplicación | | header.theme | Tema que usara por default nuestra aplicacion | | header.darkTheme | Indica si la aplicacion usara el tema osucuro | | header.colorThemeVisible | Indica si se mostrara visible la opcion para cambiar tema | | header.fullScreenVisible | Indica si se mostrara visible la opcion para cambiar a pantalla completa | | header.wishHappyBirthday | Indica si se mostrara una felicitacion cuando el empleado cumpla año | | sidemenu.menuOpen | Indica si al ingresar al sistema el menu se mostrara abierto | | sidemenu.menuOpenApps | Indica si al ingresar al sistema los menus de aplicaciones se mostraran abierto | | sidemenu.selectRoomsVisible | Indica si al ingresar al sistema la aplicación mostrara el combo de salas a las que se tiene acceso |

Es necesario también realizar una copia del archivo src/enviroments/enviroment.prod.ts y renombrarlos de la siguiente manera src/enviroments/enviroment.dev.ts y src/enviroments/enviroment.qa.ts.

Configuración de Angular CLI

Abrimos el archivo angular.json ubicado en la raiz del proyecto, a continuación ubicamos la siguiente propiedad projects/[nombre-proyecto]/architect/build/configurations y agregamos la siguiente configuracion

"dev": {
  "fileReplacements": [
    {
      "replace": "src/environments/environment.ts",
      "with": "src/environments/environment.dev.ts"
    }
  ]
},
"qa": {
  "fileReplacements": [
    {
      "replace": "src/environments/environment.ts",
      "with": "src/environments/environment.qa.ts"
    }
  ]
}

Configuración de package.json

Abrimos el archivo package.json ubicado en la raiz del proyecto, en la propiedad scripts agregamos la siguientes tareas:

    "build:qa": "ng build --prod --configuration=qa",
    "build:dev": "ng build --prod --configuration=dev",

Una vez realizado el paso anterior podremos compilar nuestra aplicación apuntando a cualquiera de los ambientes previamente definidos, por ejemplo la siguiente instruccion de terminal compiará la aplicacion para el ambiente dev :

npm run build:dev

Suscripciónes de Graphql

En nuestro archivos environment ubicamos la propiedad template/graphql y agregamos la siguiente sub propiedad:

subscriptions: {
  enabled: true,
  uri: 'ws://url_subscriptions'
}

Sentry

En nuestro archivos environment ubicamos la propiedad template/graphql/app y agregamos la siguiente sub propiedad:

sentry: {
  dsn: 'http://url_dsn',
  showReportDialog: false,
}

Redux

Para hacer la configuración de Redux es necesario crear un archivo en la siguiente estructura src/app/app.redux.ts con el siguiente contenido

import * as Template from "ngx-los";
import * as Auth from "ngx-los-auth";

export const reducers = {
  auth: Auth.authReducers,
  app: Template.appReducers,
  room: Auth.roomReducers,
  header: Template.headerReducers,
  sidemenu: Template.sideMenuReducers,
  footer: Template.footerReducers,
};

Manejo de errores de graphql

Es necesario crear el siguiente archivo: src/app/app.error.ts


import { HttpErrorResponse } from '@angular/common/http';
import { MatSnackBar } from '@angular/material/snack-bar';
import { onError } from 'apollo-link-error';
import { GraphQLError } from 'graphql';
import { environment } from '../environments/environment';

const getToken = (storageName) => {
    const authStorage = localStorage.getItem(storageName);
    if (authStorage) {
        return JSON.parse(authStorage).access_token;
    }
    return '';
};

const hasErrorMessage = (grapqhlErrors: GraphQLError[], name: string): boolean => {
    let hasError = false;

    for (const error of grapqhlErrors) {
        const messageError = typeof error.message === 'object' ? (error.message as any).error : error.message;
        if (messageError === name) {
            hasError = true;
        }
    }

    return hasError;
};

const hasStatusCode = (grapqhlErrors: GraphQLError[], statusCode: number): boolean => {
    let hasError = false;

    for (const error of grapqhlErrors) {
        const code: number = typeof error.message === 'object' ? (error.message as any).statusCode as number : Number(error.message);
        if (code === statusCode) {
            hasError = true;
        }
    }

    return hasError;
};

const validateAuth = (graphqlErrors) => {
    let message = '';

    if (hasStatusCode(graphqlErrors, 401)) {
        const token = getToken('los-auth');
        if (token) {
            message = 'No tienes los permisos necesarios para hacer esta acción';
        } else {
            const hash = '/login';
            if (window.location.hash.indexOf(hash) > -1) {
            } else {
                const redirectUrl = window.location.href;
                setTimeout(() => {
                    window.location.href = `${getUrl(environment.app.urls, 'login')}?URL_Ref=${redirectUrl}`;
                }, 3000);
            }
            message = 'No has iniciado sesión, serás redireccionado en 3 segundos';
        }
    }

    return message;
};

export function errorLink(snack: MatSnackBar) {
    return onError((error) => {
        let message = '';

        if (error.graphQLErrors) {
            message = validateAuth(error.graphQLErrors);
        }

        if (error.networkError) {
            const networkError: HttpErrorResponse = error.networkError as HttpErrorResponse;
            if (networkError.status === 0) {
                message = 'Revisa la conexión con el servidor de GraphQL';
            }
            if (networkError.status === 404) {
                message = 'Servidor de GraphQL no encontrado';
            }
        }

        if (message) {
            snack.open(message, '', { duration: 3000, panelClass: 'snackbar-error' });
        }
    });
}

const getUrl = (urls: any[], key: string) => {
    const item = urls.find(x => x.key === key);
    if (item) {
        return item.value;
    } else {
        return '';
    }
};

// ###### Escribe aquí tus funciones

// Code...

// ######

AppModule

import { MatPasswordStrengthModule } from "@angular-material-extensions/password-strength";
import { HttpClientModule } from "@angular/common/http";
import { NgModule } from "@angular/core";
import { MatButtonModule } from "@angular/material/button";
import { BrowserModule } from "@angular/platform-browser";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { StoreModule } from "@ngrx/store";
import { StoreDevtoolsModule } from "@ngrx/store-devtools";
import { ApolloBoostModule } from "apollo-angular-boost";
import { LosTemplateModule } from "ngx-los";
import { LosAuthModule } from "ngx-los-auth";
import { environment } from "../environments/environment";
import { errorLink } from "../app/app.error";
import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
import { reducers } from "./app.redux";

const options = {
  storageName: environment.template.storageName,
  graphql: {
    uri: environment.template.graphql.uri,
    subscriptions: environment.template.graphql.subscriptions,
    errorLink,
  },
  sentry: environment.app.sentry,
};

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    ApolloBoostModule,
    HttpClientModule,
    LosTemplateModule.forRoot(options),
    LosAuthModule.forRoot(options),
    StoreModule.forRoot(
      { ...reducers },
      {
        runtimeChecks: {
          strictStateImmutability: false,
          strictActionImmutability: false,
        },
      }
    ),
    StoreDevtoolsModule.instrument({
      maxAge: 25,
      logOnly: environment.production,
    }),
    MatButtonModule,
    MatPasswordStrengthModule,
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

AppComponent HTML

Localizamos el archivo src/app/app.component.html borramos su contenido y dejamos la siguiente configuración.

<los-header></los-header>
<los-side-menu></los-side-menu>
<los-footer></los-footer>

AppComponent TS

Localizamos el archivo src/app/app.component.ts dejamos la siguiente configuración.

import { Component, OnInit } from '@angular/core';
import { LosAppService, LosHeaderService, LosSideMenuService } from 'ngx-los';
import { environment } from '../environments/environment';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  constructor(
    private losAppService: LosAppService,
    private losHeaderService: LosHeaderService,
    private losSideMenuService: LosSideMenuService,
  ) { }

  async ngOnInit() {
    this.losAppService.set(environment.app);
    this.losHeaderService.set(environment.header);
    this.losSideMenuService.set(environment.sidemenu);
  }
}