diff --git a/apps/picsa-apps/dashboard-e2e/.eslintrc.json b/apps/picsa-apps/dashboard-e2e/.eslintrc.json new file mode 100644 index 000000000..aa38b3384 --- /dev/null +++ b/apps/picsa-apps/dashboard-e2e/.eslintrc.json @@ -0,0 +1,25 @@ +{ + "extends": ["plugin:cypress/recommended", "../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": { + "@angular-eslint/component-selector": ["off"], + "@angular-eslint/component-class-suffix": ["off"] + } + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.cy.{ts,js,tsx,jsx}", "src/**/*.{ts,js,tsx,jsx}"], + "rules": {} + } + ] +} diff --git a/apps/picsa-apps/dashboard-e2e/cypress.config.ts b/apps/picsa-apps/dashboard-e2e/cypress.config.ts new file mode 100644 index 000000000..293ed2fa6 --- /dev/null +++ b/apps/picsa-apps/dashboard-e2e/cypress.config.ts @@ -0,0 +1,6 @@ +import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset'; +import { defineConfig } from 'cypress'; + +export default defineConfig({ + e2e: nxE2EPreset(__filename, { cypressDir: 'src' }), +}); diff --git a/apps/picsa-apps/dashboard-e2e/project.json b/apps/picsa-apps/dashboard-e2e/project.json new file mode 100644 index 000000000..67185ee96 --- /dev/null +++ b/apps/picsa-apps/dashboard-e2e/project.json @@ -0,0 +1,33 @@ +{ + "name": "picsa-apps-dashboard-e2e", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "apps/picsa-apps/dashboard-e2e/src", + "targets": { + "e2e": { + "executor": "@nx/cypress:cypress", + "options": { + "cypressConfig": "apps/picsa-apps/dashboard-e2e/cypress.config.ts", + "testingType": "e2e", + "devServerTarget": "picsa-apps-dashboard:serve:development" + }, + "configurations": { + "production": { + "devServerTarget": "picsa-apps-dashboard:serve:production" + }, + "ci": { + "devServerTarget": "picsa-apps-dashboard:serve-static" + } + } + }, + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["apps/picsa-apps/dashboard-e2e/**/*.{js,ts}"] + } + } + }, + "tags": [], + "implicitDependencies": ["picsa-apps-dashboard"] +} diff --git a/apps/picsa-apps/dashboard-e2e/src/e2e/app.cy.ts b/apps/picsa-apps/dashboard-e2e/src/e2e/app.cy.ts new file mode 100644 index 000000000..a310883ad --- /dev/null +++ b/apps/picsa-apps/dashboard-e2e/src/e2e/app.cy.ts @@ -0,0 +1,13 @@ +import { getGreeting } from '../support/app.po'; + +describe('picsa-apps-dashboard-e2e', () => { + beforeEach(() => cy.visit('/')); + + it('should display welcome message', () => { + // Custom command example, see `../support/commands.ts` file + cy.login('my-email@something.com', 'myPassword'); + + // Function helper example, see `../support/app.po.ts` file + getGreeting().contains(/Welcome/); + }); +}); diff --git a/apps/picsa-apps/dashboard-e2e/src/fixtures/example.json b/apps/picsa-apps/dashboard-e2e/src/fixtures/example.json new file mode 100644 index 000000000..02e425437 --- /dev/null +++ b/apps/picsa-apps/dashboard-e2e/src/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} diff --git a/apps/picsa-apps/dashboard-e2e/src/support/app.po.ts b/apps/picsa-apps/dashboard-e2e/src/support/app.po.ts new file mode 100644 index 000000000..329342469 --- /dev/null +++ b/apps/picsa-apps/dashboard-e2e/src/support/app.po.ts @@ -0,0 +1 @@ +export const getGreeting = () => cy.get('h1'); diff --git a/apps/picsa-apps/dashboard-e2e/src/support/commands.ts b/apps/picsa-apps/dashboard-e2e/src/support/commands.ts new file mode 100644 index 000000000..c421a3c47 --- /dev/null +++ b/apps/picsa-apps/dashboard-e2e/src/support/commands.ts @@ -0,0 +1,35 @@ +/// + +// *********************************************** +// This example commands.ts shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** + +// eslint-disable-next-line @typescript-eslint/no-namespace +declare namespace Cypress { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + interface Chainable { + login(email: string, password: string): void; + } +} + +// -- This is a parent command -- +Cypress.Commands.add('login', (email, password) => { + console.log('Custom command example: Login', email, password); +}); +// +// -- This is a child command -- +// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/apps/picsa-apps/dashboard-e2e/src/support/e2e.ts b/apps/picsa-apps/dashboard-e2e/src/support/e2e.ts new file mode 100644 index 000000000..1c1a9e772 --- /dev/null +++ b/apps/picsa-apps/dashboard-e2e/src/support/e2e.ts @@ -0,0 +1,17 @@ +// *********************************************************** +// This example support/e2e.ts is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.ts using ES2015 syntax: +import './commands'; diff --git a/apps/picsa-apps/dashboard-e2e/tsconfig.json b/apps/picsa-apps/dashboard-e2e/tsconfig.json new file mode 100644 index 000000000..eba3f9f5c --- /dev/null +++ b/apps/picsa-apps/dashboard-e2e/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "allowJs": true, + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["cypress", "node"], + "sourceMap": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["**/*.ts", "**/*.js", "cypress.config.ts", "**/*.cy.ts", "**/*.cy.js", "**/*.d.ts"] +} diff --git a/apps/picsa-apps/dashboard/.eslintrc.json b/apps/picsa-apps/dashboard/.eslintrc.json new file mode 100644 index 000000000..904d31f0d --- /dev/null +++ b/apps/picsa-apps/dashboard/.eslintrc.json @@ -0,0 +1,35 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": ["plugin:@nx/angular", "plugin:@angular-eslint/template/process-inline-templates"], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "dashboard", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "dashboard", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": { + "@angular-eslint/template/prefer-control-flow": ["error"] + } + } + ] +} diff --git a/apps/picsa-apps/dashboard/README.md b/apps/picsa-apps/dashboard/README.md new file mode 100644 index 000000000..7ccbe6886 --- /dev/null +++ b/apps/picsa-apps/dashboard/README.md @@ -0,0 +1,14 @@ +## PICSA Dashboard + +## Code Style + +The project is built on top of Angular 17. Within this app modern angular practices should be adopted, +this includes use of standalone components, signals and new control flow syntax (e.g. `@if()` instead of `*ngIf`) + +https://blog.angular.io/introducing-angular-v17-4d7033312e4b + +https://angular.dev/ + +Some conventions are enforced using lint rules defined in [.eslintrc.json](./.eslintrc.json) + +https://github.com/angular-eslint/angular-eslint/tree/main/packages/eslint-plugin-template diff --git a/apps/picsa-apps/dashboard/jest.config.ts b/apps/picsa-apps/dashboard/jest.config.ts new file mode 100644 index 000000000..67a8027d4 --- /dev/null +++ b/apps/picsa-apps/dashboard/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +export default { + displayName: 'picsa-apps-dashboard', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/apps/picsa-apps/dashboard', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/picsa-apps/dashboard/project.json b/apps/picsa-apps/dashboard/project.json new file mode 100644 index 000000000..54eb634f7 --- /dev/null +++ b/apps/picsa-apps/dashboard/project.json @@ -0,0 +1,91 @@ +{ + "name": "picsa-apps-dashboard", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/picsa-apps/dashboard/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/picsa-apps/dashboard", + "index": "apps/picsa-apps/dashboard/src/index.html", + "browser": "apps/picsa-apps/dashboard/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/picsa-apps/dashboard/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": ["apps/picsa-apps/dashboard/src/favicon.ico", "apps/picsa-apps/dashboard/src/assets"], + "styles": ["apps/picsa-apps/dashboard/src/styles.scss"], + "stylePreprocessorOptions": { + "includePaths": ["libs/theme/src"] + }, + + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "picsa-apps-dashboard:build:production" + }, + "development": { + "buildTarget": "picsa-apps-dashboard:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "picsa-apps-dashboard:build" + } + }, + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["apps/picsa-apps/dashboard/**/*.ts", "apps/picsa-apps/dashboard/**/*.html"] + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "apps/picsa-apps/dashboard/jest.config.ts" + } + }, + "serve-static": { + "executor": "@nx/web:file-server", + "options": { + "buildTarget": "picsa-apps-dashboard:build", + "staticFilePath": "dist/apps/picsa-apps/dashboard/browser" + } + } + } +} diff --git a/apps/picsa-apps/dashboard/src/app/app.component.html b/apps/picsa-apps/dashboard/src/app/app.component.html new file mode 100644 index 000000000..1fcd78283 --- /dev/null +++ b/apps/picsa-apps/dashboard/src/app/app.component.html @@ -0,0 +1,38 @@ +
+ + + PICSA Dashboard + @if(supabaseService.authUser(); as user){ +
+ +
+ {{ user.email }} +
+
+ + } @else { + + } +
+ + + + + @for (link of navLinks; track link.href) { + {{ link.label }} + } + + + + + + +
diff --git a/apps/picsa-apps/dashboard/src/app/app.component.scss b/apps/picsa-apps/dashboard/src/app/app.component.scss new file mode 100644 index 000000000..457cb4bcf --- /dev/null +++ b/apps/picsa-apps/dashboard/src/app/app.component.scss @@ -0,0 +1,13 @@ +mat-sidenav { + width: 256px; +} +mat-nav-list { + --mdc-list-list-item-one-line-container-height: 48px; +} +mat-toolbar { + z-index: 2; +} +mat-sidenav-content { + display: flex; + flex-direction: column; +} diff --git a/apps/picsa-apps/dashboard/src/app/app.component.spec.ts b/apps/picsa-apps/dashboard/src/app/app.component.spec.ts new file mode 100644 index 000000000..c697dd1af --- /dev/null +++ b/apps/picsa-apps/dashboard/src/app/app.component.spec.ts @@ -0,0 +1,25 @@ +import { TestBed } from '@angular/core/testing'; +import { AppComponent } from './app.component'; +import { NxWelcomeComponent } from './nx-welcome.component'; +import { RouterTestingModule } from '@angular/router/testing'; + +describe('AppComponent', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [AppComponent, NxWelcomeComponent, RouterTestingModule], + }).compileComponents(); + }); + + it('should render title', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.nativeElement as HTMLElement; + expect(compiled.querySelector('h1')?.textContent).toContain('Welcome picsa-apps-dashboard'); + }); + + it(`should have as title 'picsa-apps-dashboard'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('picsa-apps-dashboard'); + }); +}); diff --git a/apps/picsa-apps/dashboard/src/app/app.component.ts b/apps/picsa-apps/dashboard/src/app/app.component.ts new file mode 100644 index 000000000..74d8f63ba --- /dev/null +++ b/apps/picsa-apps/dashboard/src/app/app.component.ts @@ -0,0 +1,42 @@ +import { CommonModule } from '@angular/common'; +import { AfterViewInit, Component } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { PicsaNotificationService } from '@picsa/shared/services/core/notification.service'; +import { SupabaseService } from '@picsa/shared/services/core/supabase'; + +import { DashboardMaterialModule } from './material.module'; + +interface INavLink { + label: string; + href: string; + isActive?: boolean; +} + +@Component({ + standalone: true, + imports: [RouterModule, DashboardMaterialModule, CommonModule], + selector: 'dashboard-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'], +}) +export class AppComponent implements AfterViewInit { + title = 'picsa-apps-dashboard'; + + navLinks: INavLink[] = [ + { + label: 'Home', + href: '/', + }, + // { + // label: 'Resources', + // href: '/resources', + // }, + ]; + + constructor(public supabaseService: SupabaseService, private notificationService: PicsaNotificationService) {} + + async ngAfterViewInit() { + await this.supabaseService.init(); + await this.supabaseService.signInDefaultUser(); + } +} diff --git a/apps/picsa-apps/dashboard/src/app/app.config.ts b/apps/picsa-apps/dashboard/src/app/app.config.ts new file mode 100644 index 000000000..04d4b89b5 --- /dev/null +++ b/apps/picsa-apps/dashboard/src/app/app.config.ts @@ -0,0 +1,9 @@ +import { ApplicationConfig } from '@angular/core'; +import { provideAnimations } from '@angular/platform-browser/animations'; +import { provideRouter } from '@angular/router'; + +import { appRoutes } from './app.routes'; + +export const appConfig: ApplicationConfig = { + providers: [provideRouter(appRoutes), provideAnimations()], +}; diff --git a/apps/picsa-apps/dashboard/src/app/app.routes.ts b/apps/picsa-apps/dashboard/src/app/app.routes.ts new file mode 100644 index 000000000..0e7f01bb8 --- /dev/null +++ b/apps/picsa-apps/dashboard/src/app/app.routes.ts @@ -0,0 +1,8 @@ +import { Route } from '@angular/router'; + +export const appRoutes: Route[] = [ + { + path: 'resources', + loadChildren: () => import('./pages/resources/resources.module').then((m) => m.ResourcesPageModule), + }, +]; diff --git a/apps/picsa-apps/dashboard/src/app/material.module.ts b/apps/picsa-apps/dashboard/src/app/material.module.ts new file mode 100644 index 000000000..dd707f61e --- /dev/null +++ b/apps/picsa-apps/dashboard/src/app/material.module.ts @@ -0,0 +1,14 @@ +import { NgModule } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatIconModule } from '@angular/material/icon'; +import { MatListModule } from '@angular/material/list'; +import { MatSidenavModule } from '@angular/material/sidenav'; +import { MatToolbarModule } from '@angular/material/toolbar'; + +const matModules = [MatButtonModule, MatIconModule, MatListModule, MatSidenavModule, MatToolbarModule]; + +@NgModule({ + imports: matModules, + exports: matModules, +}) +export class DashboardMaterialModule {} diff --git a/apps/picsa-apps/dashboard/src/app/pages/resources/resources.module.ts b/apps/picsa-apps/dashboard/src/app/pages/resources/resources.module.ts new file mode 100644 index 000000000..c47e15277 --- /dev/null +++ b/apps/picsa-apps/dashboard/src/app/pages/resources/resources.module.ts @@ -0,0 +1,19 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { ResourcesPageComponent } from './resources.page'; + +@NgModule({ + declarations: [], + imports: [ + CommonModule, + RouterModule.forChild([ + { + path: '', + component: ResourcesPageComponent, + }, + ]), + ], +}) +export class ResourcesPageModule {} diff --git a/apps/picsa-apps/dashboard/src/app/pages/resources/resources.page.html b/apps/picsa-apps/dashboard/src/app/pages/resources/resources.page.html new file mode 100644 index 000000000..16913ac32 --- /dev/null +++ b/apps/picsa-apps/dashboard/src/app/pages/resources/resources.page.html @@ -0,0 +1,4 @@ +
+ + +
diff --git a/apps/picsa-apps/dashboard/src/app/pages/resources/resources.page.scss b/apps/picsa-apps/dashboard/src/app/pages/resources/resources.page.scss new file mode 100644 index 000000000..e69de29bb diff --git a/apps/picsa-apps/dashboard/src/app/pages/resources/resources.page.spec.ts b/apps/picsa-apps/dashboard/src/app/pages/resources/resources.page.spec.ts new file mode 100644 index 000000000..7c5beec63 --- /dev/null +++ b/apps/picsa-apps/dashboard/src/app/pages/resources/resources.page.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ResourcesPageComponent } from './resources.page'; + +describe('ResourcesPageComponent', () => { + let component: ResourcesPageComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ResourcesPageComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(ResourcesPageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/picsa-apps/dashboard/src/app/pages/resources/resources.page.ts b/apps/picsa-apps/dashboard/src/app/pages/resources/resources.page.ts new file mode 100644 index 000000000..e77cef65d --- /dev/null +++ b/apps/picsa-apps/dashboard/src/app/pages/resources/resources.page.ts @@ -0,0 +1,30 @@ +import '@uppy/core/dist/style.min.css'; +import '@uppy/dashboard/dist/style.min.css'; + +import { CommonModule } from '@angular/common'; +import { Component, OnInit } from '@angular/core'; +import { SupabaseService } from '@picsa/shared/services/core/supabase'; +import { UppyAngularDashboardModule } from '@uppy/angular'; +import Uppy from '@uppy/core'; + +import { DashboardMaterialModule } from '../../material.module'; + +@Component({ + selector: 'dashboard-resources-page', + standalone: true, + imports: [CommonModule, DashboardMaterialModule, UppyAngularDashboardModule], + templateUrl: './resources.page.html', + styleUrls: ['./resources.page.scss'], +}) +export class ResourcesPageComponent implements OnInit { + uppy: Uppy = new Uppy({ debug: true, autoProceed: true }); + + constructor(public supabaseService: SupabaseService) {} + + async ngOnInit() { + const table = this.supabaseService.db.table('resources'); + + const { data, error } = await table.select(); + console.log({ data, error }); + } +} diff --git a/apps/picsa-apps/dashboard/src/assets/.gitkeep b/apps/picsa-apps/dashboard/src/assets/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/apps/picsa-apps/dashboard/src/favicon.ico b/apps/picsa-apps/dashboard/src/favicon.ico new file mode 100644 index 000000000..317ebcb23 Binary files /dev/null and b/apps/picsa-apps/dashboard/src/favicon.ico differ diff --git a/apps/picsa-apps/dashboard/src/index.html b/apps/picsa-apps/dashboard/src/index.html new file mode 100644 index 000000000..2dd34e155 --- /dev/null +++ b/apps/picsa-apps/dashboard/src/index.html @@ -0,0 +1,13 @@ + + + + + PICSA Dashboard + + + + + + + + diff --git a/apps/picsa-apps/dashboard/src/main.ts b/apps/picsa-apps/dashboard/src/main.ts new file mode 100644 index 000000000..14afb2d0e --- /dev/null +++ b/apps/picsa-apps/dashboard/src/main.ts @@ -0,0 +1,6 @@ +import { bootstrapApplication } from '@angular/platform-browser'; + +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err)); diff --git a/apps/picsa-apps/dashboard/src/styles.scss b/apps/picsa-apps/dashboard/src/styles.scss new file mode 100644 index 000000000..0029378bb --- /dev/null +++ b/apps/picsa-apps/dashboard/src/styles.scss @@ -0,0 +1,25 @@ +/* You can add global styles to this file, and also import other style files */ + +/** +Shared styles + +These are imported from libs\theme\src\_index.scss + +Made available from project.json +``` +"stylePreprocessorOptions": { + "includePaths": ["libs/theme/src"] + }, +``` +*/ + +@import 'themes'; +@import 'variables'; +@import 'fonts'; +@import 'layout'; +@import 'typography'; +@import 'overrides'; + +mat-sidenav-content > * { + display: contents; +} diff --git a/apps/picsa-apps/dashboard/src/test-setup.ts b/apps/picsa-apps/dashboard/src/test-setup.ts new file mode 100644 index 000000000..ab1eeeb33 --- /dev/null +++ b/apps/picsa-apps/dashboard/src/test-setup.ts @@ -0,0 +1,8 @@ +// @ts-expect-error https://thymikee.github.io/jest-preset-angular/docs/getting-started/test-environment +globalThis.ngJest = { + testEnvironmentOptions: { + errorOnUnknownElements: true, + errorOnUnknownProperties: true, + }, +}; +import 'jest-preset-angular/setup-jest'; diff --git a/apps/picsa-apps/dashboard/tsconfig.app.json b/apps/picsa-apps/dashboard/tsconfig.app.json new file mode 100644 index 000000000..58220429a --- /dev/null +++ b/apps/picsa-apps/dashboard/tsconfig.app.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [] + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/picsa-apps/dashboard/tsconfig.editor.json b/apps/picsa-apps/dashboard/tsconfig.editor.json new file mode 100644 index 000000000..8ae117d96 --- /dev/null +++ b/apps/picsa-apps/dashboard/tsconfig.editor.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": { + "types": ["jest", "node"] + } +} diff --git a/apps/picsa-apps/dashboard/tsconfig.json b/apps/picsa-apps/dashboard/tsconfig.json new file mode 100644 index 000000000..25ca437b4 --- /dev/null +++ b/apps/picsa-apps/dashboard/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/picsa-apps/dashboard/tsconfig.spec.json b/apps/picsa-apps/dashboard/tsconfig.spec.json new file mode 100644 index 000000000..e637bf83b --- /dev/null +++ b/apps/picsa-apps/dashboard/tsconfig.spec.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "target": "es2016", + "types": ["jest", "node"] + }, + "files": ["src/test-setup.ts"], + "include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/apps/picsa-server/README.md b/apps/picsa-server/README.md index 60771972a..f9839907e 100644 --- a/apps/picsa-server/README.md +++ b/apps/picsa-server/README.md @@ -1,132 +1,3 @@ # PICSA Server See docs at: https://docs.picsa.app/advanced/server/setup - -## Prerequisites - -- Docker Desktop -- [Deno](https://docs.deno.com/runtime/manual/getting_started/installation) -- [Deno VSCode Extension](https://marketplace.visualstudio.com/items?itemName=denoland.vscode-deno) - -## Quickstart - -### Start Server - -```sh -yarn nx run picsa-server:supabase start -``` - -This will start various backend services within docker containers - -API URL: http://localhost:54321 -GraphQL URL: http://localhost:54321/graphql/v1 -DB URL: postgresql://postgres:postgres@localhost:54322/postgres -Studio URL: http://localhost:54323 -Inbucket URL: http://localhost:54324 - -Update Frontend -The console will output an `anon key` which should be populated in the frontend supabase environment -`libs\environments\src\environment.ts` - -### Populate DB - -```sh -yarn nx run picsa-server:supabase db reset -``` - -### Create User - -In order to allow communication from unauthenticated users to the database a custom anonymous user -should be created from the studio dashboard with credentials: - -http://localhost:54323/project/default/auth/users - -email: `anonymous_user@picsa.app` -password: `anonymous_user@picsa.app` - -Ensure **Auto Confirm** is checked - -### Serve Functions - -If developing functions locally run via - -```sh -yarn nx run picsa-server:supabase functions serve -``` - -Functions can be called from any rest client. - -Authorization credentials should be provided using the service_role key output when server started or by calling `nx run picsa-server:supabase status` - -https://supabase.com/docs/guides/functions/local-development - -**Test Functions** - -Whilst serving functions tests can be executed by - -```sh -yarn nx run picsa-server:test-functions -``` - -In order to run tests that connect to supabase an additional `.env.local` file should be populated in the the functions directory with SUPABASE_ANON_KEY credentials - -Tests are written using the [Behavior-Driven Development](https://docs.deno.com/runtime/manual/basics/testing/behavior_driven_development) module - -Functions cli supports [additional arguments](https://fig.io/manual/deno/test) such as `--watch` - -```sh -yarn nx run picsa-server:test-functions --watch -``` - -## Advanced Usage - -## Export DB Type Generation - -```sh -yarn nx run picsa-server:gen-types -``` - -or from the console http://localhost:54323/project/default/api?page=tables-intro - -https://supabase.com/docs/guides/api/rest/generating-types - -### Link to server - -``` -yarn nx run picsa-server:supabase link --project-ref [ref] -``` - -### Pull server db - -```sh -supabase db pull -``` - -### DB Migrations - -```sh -yarn nx run picsa-server:supabase migration new create_monitoring_submissions -``` - -``` - -``` - -# Troubleshooting - -**`supabase link` fails - timeout** - -- Check dashboard and ensure ip not panned -- Pass password as var - -``` -supabase link --project-ref [ref] --password [pass] -``` - -**Relative import path "@supabase/supabase-js" not prefixed** -Any Imports have to be defined both in `import-map.json` file - -# Links - -- https://supabase.com/blog/supabase-local-dev -- https://supabase.github.io/pg_graphql/computed_fields/ diff --git a/libs/environments/tsconfig.json b/libs/environments/tsconfig.json index d3e5453d6..eae94ff9c 100644 --- a/libs/environments/tsconfig.json +++ b/libs/environments/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.base.json", + "extends": ["../../tsconfig.base.json"], "files": [], "include": [], "references": [ diff --git a/libs/shared/src/services/core/db_v2/db-sync.service.ts b/libs/shared/src/services/core/db_v2/db-sync.service.ts index 3cfc8cb49..3c3552a7e 100644 --- a/libs/shared/src/services/core/db_v2/db-sync.service.ts +++ b/libs/shared/src/services/core/db_v2/db-sync.service.ts @@ -3,7 +3,7 @@ import { Network } from '@capacitor/network'; import { _wait } from '@picsa/utils'; import { RxCollection, RxDatabase, RxDocument } from 'rxdb'; -import { SupabaseService } from '../supabase.service'; +import { SupabaseService } from '../supabase'; import { ISyncDeleteEntry, SYNC_DELETE_COLLECTION } from './schemas/sync_delete'; export interface ISyncPushEntry { diff --git a/libs/shared/src/services/core/notification.service.ts b/libs/shared/src/services/core/notification.service.ts new file mode 100644 index 000000000..b5bcf5899 --- /dev/null +++ b/libs/shared/src/services/core/notification.service.ts @@ -0,0 +1,46 @@ +import { Component, Inject, Injectable } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatIconModule } from '@angular/material/icon'; +import { MAT_SNACK_BAR_DATA, MatSnackBar, MatSnackBarConfig, MatSnackBarRef } from '@angular/material/snack-bar'; + +interface IUserNotificationData { + matIcon: string; + message: string; + buttonText?: string; +} + +@Injectable({ providedIn: 'root' }) +export class PicsaNotificationService { + constructor(private snackBar: MatSnackBar) {} + + /** Present a dismissable notification snack bar */ + showUserNotification(data: IUserNotificationData, config: MatSnackBarConfig = {}) { + const snackBarRef = this.snackBar.openFromComponent(SnackBarWithIconComponent, { data, ...config }); + return snackBarRef; + } +} + +@Component({ + selector: 'picsa-snack-bar-with-icon-component', + template: `
+ {{ data.matIcon }} + {{ data.message }} + +
`, + styles: [ + ` + .message-container { + display: flex; + align-items: center; + } + `, + ], + standalone: true, + imports: [MatIconModule, MatButtonModule], +}) +export class SnackBarWithIconComponent { + constructor( + @Inject(MAT_SNACK_BAR_DATA) public data: IUserNotificationData, + public snackRef: MatSnackBarRef + ) {} +} diff --git a/libs/shared/src/services/core/supabase.service.ts b/libs/shared/src/services/core/supabase.service.ts deleted file mode 100644 index e95e30f1f..000000000 --- a/libs/shared/src/services/core/supabase.service.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Injectable } from '@angular/core'; -import { ENVIRONMENT } from '@picsa/environments/src'; -import { StorageClient } from '@supabase/storage-js'; -import { createClient, RealtimeClient, SupabaseClient } from '@supabase/supabase-js'; - -import { PicsaAsyncService } from '../asyncService.service'; - -/** Key safe to use in browser (assuming tables have row-level security) */ - -@Injectable({ providedIn: 'root' }) -export class SupabaseService extends PicsaAsyncService { - private supabase: SupabaseClient; - public storage: StorageClient; - public realtime: RealtimeClient; - - public db: { table: SupabaseClient['from'] }; - - constructor() { - super(); - const { anonKey, apiUrl } = ENVIRONMENT.supabase; - this.supabase = createClient(apiUrl, anonKey, {}); - this.storage = this.supabase.storage; - this.realtime = this.supabase.realtime; - this.db = { table: (relation: string) => this.supabase.from(relation) }; - } - - /** User shared credential to sign in as an anonymous user for supabase */ - async signInAnonymousUser() { - const { email, password } = ENVIRONMENT.supabase.appUser; - const res = await this.supabase.auth.signInWithPassword({ email, password: password || email }); - // TODO - could consider function to generate app user base on id which could also use - // RLS for sync - console.log('[Supabase Auth]', res); - } - - public override async init(...args: any): Promise { - // Not currently required - } -} diff --git a/libs/shared/src/services/core/supabase/dialogs/sign-in.dialog.ts b/libs/shared/src/services/core/supabase/dialogs/sign-in.dialog.ts new file mode 100644 index 000000000..8e971e5b2 --- /dev/null +++ b/libs/shared/src/services/core/supabase/dialogs/sign-in.dialog.ts @@ -0,0 +1,185 @@ +import { Component, Inject } from '@angular/core'; +import { + AbstractControl, + FormControl, + FormGroup, + FormGroupDirective, + FormsModule, + NgForm, + ReactiveFormsModule, + ValidationErrors, + ValidatorFn, + Validators, +} from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { ErrorStateMatcher } from '@angular/material/core'; +import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; + +import { PicsaNotificationService } from '../../notification.service'; +import type { SupabaseService } from '../supabase.service'; + +export interface ISignInDialogData { + service: SupabaseService; +} + +/** + * Implement custom error handler to only display if control is dirty, touched, or submitted. + * https://material.angular.io/components/input/overview#changing-when-error-messages-are-shown + * */ +export class showErrorAfterInteraction implements ErrorStateMatcher { + isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean { + const isSubmitted = form && form.submitted; + return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted)); + } +} + +/** + * Custom form validator to ensure passwords match. Adapted from + * https://stackoverflow.com/a/51606362/5693245 + */ +const validatePasswordMatch: ValidatorFn = (control: AbstractControl): ValidationErrors | null => { + if (!control) return null; + const form = control.parent; + if (!form) return null; + const pass = form.get('password')?.value; + return pass === control.value ? null : { notSame: true }; +}; + +@Component({ + selector: 'picsa-supabase-sign-in-dialog', + standalone: true, + imports: [FormsModule, MatButtonModule, MatDialogModule, MatFormFieldModule, MatInputModule, ReactiveFormsModule], + template: ` +

{{ title }}

+ +
+ + Email + + @if (form.controls.email.errors) { + Please enter a valid email address + } + + + Password + + + @if(template==='register'){ + + Repeat Password + + @if (form.controls.passwordConfirm?.errors) { + Password must match + } + + } +
+
+ + @if(template==='signIn'){ + + + } @if(template==='register'){ + + + } + + `, + styles: [ + ` + mat-dialog-content { + width: 300px; + } + mat-form-field { + display: block; + } + input.mat-mdc-input-element.mdc-text-field__input { + font-size: 16px; + height: 48px; + } + `, + ], +}) +export class SupabaseSignInDialogComponent { + public title = 'Sign In'; + public template: 'signIn' | 'register' = 'signIn'; + + errorMatcher = new showErrorAfterInteraction(); + + private service: SupabaseService; + + public form = new FormGroup<{ email: FormControl; password: FormControl; passwordConfirm?: FormControl }>({ + email: new FormControl('', [Validators.required, Validators.email]), + password: new FormControl('', Validators.required), + }); + + constructor( + private dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) data: ISignInDialogData, + private notificationService: PicsaNotificationService + ) { + this.service = data.service; + } + + public enableRegisterMode() { + this.template = 'register'; + this.title = 'Register'; + this.form.addControl('passwordConfirm', new FormControl('', [Validators.required, validatePasswordMatch])); + } + + public async handleSignIn() { + this.form.disable(); + const { email, password } = this.form.value; + const { data, error } = await this.service.signInUser(email, password); + console.log({ data, error }); + if (error) { + console.error(error); + this.notificationService.showUserNotification({ message: error.message, matIcon: 'error' }); + this.form.enable(); + } else { + this.dialogRef.close(); + } + } + public async handleRegister() { + this.form.disable(); + const { email, password } = this.form.value; + const { error } = await this.service.signUpUser(email, password); + if (error) { + console.error(error); + this.notificationService.showUserNotification({ message: error.message, matIcon: 'error' }); + this.form.enable(); + } else { + this.dialogRef.close(); + } + } +} diff --git a/libs/shared/src/services/core/supabase/index.ts b/libs/shared/src/services/core/supabase/index.ts new file mode 100644 index 000000000..87efe61cb --- /dev/null +++ b/libs/shared/src/services/core/supabase/index.ts @@ -0,0 +1 @@ +export * from './supabase.service'; diff --git a/libs/shared/src/services/core/supabase/supabase.service.ts b/libs/shared/src/services/core/supabase/supabase.service.ts new file mode 100644 index 000000000..83df66561 --- /dev/null +++ b/libs/shared/src/services/core/supabase/supabase.service.ts @@ -0,0 +1,121 @@ +import { Injectable, signal } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { ENVIRONMENT } from '@picsa/environments/src'; +import { StorageClient } from '@supabase/storage-js'; +import { AuthError, createClient, RealtimeClient, SupabaseClient, User } from '@supabase/supabase-js'; +import { SupabaseAuthClient } from '@supabase/supabase-js/dist/module/lib/SupabaseAuthClient'; + +import { PicsaAsyncService } from '../../asyncService.service'; +import { PicsaNotificationService } from '../notification.service'; +import { SupabaseSignInDialogComponent } from './dialogs/sign-in.dialog'; + +/** Key safe to use in browser (assuming tables have row-level security) */ + +@Injectable({ providedIn: 'root' }) +export class SupabaseService extends PicsaAsyncService { + /** Authenticated user */ + public authUser = signal(undefined); + + /** Access to postgres db as a shortcut to table from method */ + public db: { table: SupabaseClient['from'] }; + + private supabase: SupabaseClient; + private storage: StorageClient; + private realtime: RealtimeClient; + + private auth: SupabaseAuthClient; + + constructor(private notificationService: PicsaNotificationService, private dialog: MatDialog) { + super(); + const { anonKey, apiUrl } = ENVIRONMENT.supabase; + this.supabase = createClient(apiUrl, anonKey, {}); + this.storage = this.supabase.storage; + this.realtime = this.supabase.realtime; + this.auth = this.supabase.auth; + this.db = { table: (relation: string) => this.supabase.from(relation) }; + } + public override async init(...args: any): Promise { + this.subscribeToAuthChanges(); + } + + public async signInPrompt() { + this.dialog.open(SupabaseSignInDialogComponent, { data: { service: this } }); + } + + public async signInUser(email: string, password: string) { + return this.auth.signInWithPassword({ email, password }); + } + + public async signUpUser(email: string, password: string) { + return this.auth.signUp({ email, password }); + } + + public async signOut() { + return this.auth.signOut(); + } + + /** Attempt to sign-in as persisted user, with fallback to anonymous */ + public async signInDefaultUser() { + const { error } = await this.auth.getUser(); + if (error) { + console.log('User session not found, signing in anonymous user'); + return this.signInAnonymousUser(); + } + // return user as updated by auth change subscriber + return this.authUser; + } + + /** User shared credential to sign in as an anonymous user for supabase */ + private async signInAnonymousUser() { + const { email, password } = ENVIRONMENT.supabase.appUser; + const { error } = await this.supabase.auth.signInWithPassword({ email, password: password || email }); + // TODO - could consider function to generate app user base on id which could also use RLS for sync + if (error) { + console.error(error); + this.logUserErrorMessage(error); + if (error.message === 'Invalid login credentials') { + const devMessage = `Ensure user with email: [${email}] created in supabase auth.\nSee guidance in server Readme`; + console.error('[Developer Note]\n' + devMessage); + } + } + // return user as updated by auth change subscriber + return this.authUser; + } + + private subscribeToAuthChanges() { + this.auth.onAuthStateChange((_event, session) => { + const user = session?.user; + if (user?.id !== this.authUser()?.id) { + this.authUser.set(session?.user); + } + }); + } + + /** Create variants of error messages received in supabase for notification purposes */ + private getUserErrorMessage(error: AuthError): { message: string; matIcon: string; devMessage?: string } { + const { name, message } = error; + const mapping = { + AuthRetryableFetchError: { + message: 'Server connection Failed', + matIcon: 'cloud_off', + devMessage: 'Ensure the server is running locally', + }, + 'Invalid login credentials': { + message: 'User does not exist or password incorrect', + matIcon: 'person_alert', + }, + 'invalid claim: missing sub claim': { + message: 'No user signed in, unable to load', + }, + }; + return mapping[message] || { message: `${name} - ${message}`, matIcon: 'error' }; + } + + private logUserErrorMessage(error: AuthError) { + const { message, matIcon, devMessage } = this.getUserErrorMessage(error); + this.notificationService.showUserNotification({ matIcon, message }); + if (devMessage) { + console.error('[Developer Note]\n' + devMessage); + } + } +} diff --git a/libs/theme/src/_overrides.scss b/libs/theme/src/_overrides.scss index 66d76a19a..0c077535e 100644 --- a/libs/theme/src/_overrides.scss +++ b/libs/theme/src/_overrides.scss @@ -1,5 +1,11 @@ $fontFamily: Roboto, 'Helvetica Neue', sans-serif; +// fix height styles lost since angular/material 17 updates +body { + --mdc-protected-button-container-height: 36px; + --mdc-outlined-button-container-height: 36px; +} + // Revert changes appliec md14 -> md15 button.mdc-button { font-size: 14px; @@ -11,10 +17,6 @@ button.mat-mdc-button > .mat-icon { width: 24px; height: 24px; } -// fix height styles lost since angular/material 17 updates -button.mat-mdc-raised-button { - height: var(--mdc-protected-button-container-height, 36px); -} mat-card.link { cursor: pointer; diff --git a/package.json b/package.json index cd2928ae0..62cc37020 100644 --- a/package.json +++ b/package.json @@ -6,10 +6,11 @@ "ng": "nx", "postinstall": "node ./decorate-angular-cli.js && jetifier && husky install", "start": "yarn build:webcomponents && nx serve", - "start:server": "nx run picsa-server-docker:start", + "start:server": "nx run picsa-server:supabase start", "start:budget": "nx run picsa-tools-budget-tool:serve", "start:climate": "nx run picsa-tools-climate-tool:serve", "start:crop-probability": "nx run picsa-tools-crop-probability-tool:serve", + "start:dashboard": "nx run picsa-apps-dashboard:serve", "start:monitoring": "nx run picsa-tools-monitoring-tool:serve", "start:option": "nx run picsa-tools-option-tool:serve", "start:resources": "nx run picsa-tools-resources-tool:serve", @@ -64,7 +65,13 @@ "@ngx-translate/http-loader": "~8.0.0", "@nx/angular": "17.1.2", "@stencil/angular-output-target": "^0.7.1", - "@supabase/supabase-js": "^2.38.0", + "@supabase/supabase-js": "^2.38.5", + "@uppy/angular": "^0.6.1", + "@uppy/core": "^3.7.1", + "@uppy/dashboard": "^3.7.1", + "@uppy/drag-drop": "^3.0.3", + "@uppy/progress-bar": "^3.0.4", + "@uppy/status-bar": "^3.2.5", "c3": "^0.7.20", "capacitor-blob-writer": "^1.1.14", "capacitor-video-player": "^5.0.3", @@ -89,7 +96,6 @@ "mobx": "^6.7.0", "mobx-angular": "^4.7.1", "ngx-extended-pdf-viewer": "^18.1.7", - "ngx-file-drop": "14.0.2", "ngx-lottie": "^10.0.0", "papaparse": "^5.3.2", "parse": "3.4.2", @@ -126,6 +132,8 @@ "@schematics/angular": "17.0.1", "@stencil/core": "3.2.2", "@stencil/sass": "^3.0.2", + "@swc-node/register": "~1.6.7", + "@swc/core": "~1.3.85", "@types/c3": "^0.7.8", "@types/hammerjs": "^2.0.41", "@types/intro.js": "^5.1.1", @@ -170,7 +178,7 @@ "puppeteer": "^15.5.0", "rollup-plugin-node-polyfills": "^0.2.1", "rollup-plugin-visualizer": "^5.8.3", - "supabase": "^1.100.1", + "supabase": "^1.113.2", "tailwindcss": "^3.0.2", "ts-jest": "29.1.1", "ts-node": "10.9.1", diff --git a/yarn.lock b/yarn.lock index b268df5f4..4608f8a60 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6830,12 +6830,12 @@ __metadata: languageName: node linkType: hard -"@supabase/gotrue-js@npm:^2.54.2": - version: 2.55.0 - resolution: "@supabase/gotrue-js@npm:2.55.0" +"@supabase/gotrue-js@npm:^2.56.0": + version: 2.57.0 + resolution: "@supabase/gotrue-js@npm:2.57.0" dependencies: "@supabase/node-fetch": ^2.6.14 - checksum: 0c66a8456e885cd5fde96df631822035fcafe94c7f3b51150e174e44c5821202a8f3424df6c55e9f25da712be3737d021d3e831aa619e511cc29b44eab5bdddf + checksum: 2328b53f5ed33845e6097f84c76db094572f091da465018b93a3d5f9f41161b8d25b505d5a94d462242b7d346083a1a43b877e06f956e5298efe64ddb84ead63 languageName: node linkType: hard @@ -6848,24 +6848,24 @@ __metadata: languageName: node linkType: hard -"@supabase/postgrest-js@npm:^1.8.4": - version: 1.8.4 - resolution: "@supabase/postgrest-js@npm:1.8.4" +"@supabase/postgrest-js@npm:^1.8.6": + version: 1.9.0 + resolution: "@supabase/postgrest-js@npm:1.9.0" dependencies: "@supabase/node-fetch": ^2.6.14 - checksum: e37f3046362986b739fc237b6aef9d08cf40e22fff667a3f98010f8638f91fce7019cc3300059d4405385181e7ef89ad85acbe2906d3fb0aa2d969a2a31b3d1e + checksum: bf38139685901e9b96f97ac0bef6282352ebfd41c198174fd2109f109ee431f1eb2c8b68fa32c49fecb751a27358fd5790a03cda9bd4100bd16e2034aea7e419 languageName: node linkType: hard -"@supabase/realtime-js@npm:^2.8.0": - version: 2.8.0 - resolution: "@supabase/realtime-js@npm:2.8.0" +"@supabase/realtime-js@npm:^2.8.4": + version: 2.8.4 + resolution: "@supabase/realtime-js@npm:2.8.4" dependencies: "@supabase/node-fetch": ^2.6.14 "@types/phoenix": ^1.5.4 "@types/websocket": ^1.0.3 websocket: ^1.0.34 - checksum: 85fff3aada0f3a56b803007c3cd7c8962219f9f5e2b9a6c3afaa0dfa04ad845e35e347f903afb1cda42f4369c9be21e2a1edc08362f55ce25390dc8275661184 + checksum: ddc93c0ac54042ae842e71194bfd6e77117cf8bf3d6815393abb12b15d627945b0c352a888527c48e72000a1a0259bb0ea1f33208bb619c0a5e090422d521324 languageName: node linkType: hard @@ -6878,17 +6878,173 @@ __metadata: languageName: node linkType: hard -"@supabase/supabase-js@npm:^2.38.0": - version: 2.38.0 - resolution: "@supabase/supabase-js@npm:2.38.0" +"@supabase/supabase-js@npm:^2.38.5": + version: 2.38.5 + resolution: "@supabase/supabase-js@npm:2.38.5" dependencies: "@supabase/functions-js": ^2.1.5 - "@supabase/gotrue-js": ^2.54.2 + "@supabase/gotrue-js": ^2.56.0 "@supabase/node-fetch": ^2.6.14 - "@supabase/postgrest-js": ^1.8.4 - "@supabase/realtime-js": ^2.8.0 + "@supabase/postgrest-js": ^1.8.6 + "@supabase/realtime-js": ^2.8.4 "@supabase/storage-js": ^2.5.4 - checksum: fc882c049b15904c63b7d37a652a6da71f2e34fdebce15fe1d164e83dbdd1b30470e1700e740234e989e7ceac3c027f5f31617ea7ada9da63a1afebdb6f9b259 + checksum: db6b77ee1edcc71971e530caaecc0e3d969736212b07dc3505b3397b8daa46582bc1ea7e4ffdb353096af722640d277ee32a5b357f7dc06b41361c336d6bb0e4 + languageName: node + linkType: hard + +"@swc-node/core@npm:^1.10.6": + version: 1.10.6 + resolution: "@swc-node/core@npm:1.10.6" + peerDependencies: + "@swc/core": ">= 1.3" + checksum: 9a30a227c79263cf361cbdedf695d70417c1636f95c53928cc92d1bbc69165a619d206bdeb6977c77d9319801be39c31cb7a5fc3bb2ab6140b77f6cb7f1eda5f + languageName: node + linkType: hard + +"@swc-node/register@npm:~1.6.7": + version: 1.6.8 + resolution: "@swc-node/register@npm:1.6.8" + dependencies: + "@swc-node/core": ^1.10.6 + "@swc-node/sourcemap-support": ^0.3.0 + colorette: ^2.0.19 + debug: ^4.3.4 + pirates: ^4.0.5 + tslib: ^2.5.0 + peerDependencies: + "@swc/core": ">= 1.3" + typescript: ">= 4.3" + checksum: 70bfbd1e9d969318f68e11b9db86ca4d99c52f5f8a8aa4e3c63b1d512d8b4909c034a5e1346b243c45483d13c47f57b0943f6a1cafbe6f884d14d1026e0396c7 + languageName: node + linkType: hard + +"@swc-node/sourcemap-support@npm:^0.3.0": + version: 0.3.0 + resolution: "@swc-node/sourcemap-support@npm:0.3.0" + dependencies: + source-map-support: ^0.5.21 + tslib: ^2.5.0 + checksum: a3c837ed790238ef88682eb342b75d756eba5eb3b6cfe6cf14a597bd78dfc9a9797f1e54a4977c1297e5324fba2e33bd76ab8aa9c396ad463693de2001180c9e + languageName: node + linkType: hard + +"@swc/core-darwin-arm64@npm:1.3.99": + version: 1.3.99 + resolution: "@swc/core-darwin-arm64@npm:1.3.99" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@swc/core-darwin-x64@npm:1.3.99": + version: 1.3.99 + resolution: "@swc/core-darwin-x64@npm:1.3.99" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@swc/core-linux-arm64-gnu@npm:1.3.99": + version: 1.3.99 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.99" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@swc/core-linux-arm64-musl@npm:1.3.99": + version: 1.3.99 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.99" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@swc/core-linux-x64-gnu@npm:1.3.99": + version: 1.3.99 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.99" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@swc/core-linux-x64-musl@npm:1.3.99": + version: 1.3.99 + resolution: "@swc/core-linux-x64-musl@npm:1.3.99" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@swc/core-win32-arm64-msvc@npm:1.3.99": + version: 1.3.99 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.99" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@swc/core-win32-ia32-msvc@npm:1.3.99": + version: 1.3.99 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.99" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@swc/core-win32-x64-msvc@npm:1.3.99": + version: 1.3.99 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.99" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@swc/core@npm:~1.3.85": + version: 1.3.99 + resolution: "@swc/core@npm:1.3.99" + dependencies: + "@swc/core-darwin-arm64": 1.3.99 + "@swc/core-darwin-x64": 1.3.99 + "@swc/core-linux-arm64-gnu": 1.3.99 + "@swc/core-linux-arm64-musl": 1.3.99 + "@swc/core-linux-x64-gnu": 1.3.99 + "@swc/core-linux-x64-musl": 1.3.99 + "@swc/core-win32-arm64-msvc": 1.3.99 + "@swc/core-win32-ia32-msvc": 1.3.99 + "@swc/core-win32-x64-msvc": 1.3.99 + "@swc/counter": ^0.1.1 + "@swc/types": ^0.1.5 + peerDependencies: + "@swc/helpers": ^0.5.0 + dependenciesMeta: + "@swc/core-darwin-arm64": + optional: true + "@swc/core-darwin-x64": + optional: true + "@swc/core-linux-arm64-gnu": + optional: true + "@swc/core-linux-arm64-musl": + optional: true + "@swc/core-linux-x64-gnu": + optional: true + "@swc/core-linux-x64-musl": + optional: true + "@swc/core-win32-arm64-msvc": + optional: true + "@swc/core-win32-ia32-msvc": + optional: true + "@swc/core-win32-x64-msvc": + optional: true + peerDependenciesMeta: + "@swc/helpers": + optional: true + checksum: a4d51e650913045fe3100195b053dafb55dc06fcadd4a9381712c64f09a75d548596bb1a96e8ed84ba0199f701e821a381a25db82c1016cdd731e0077a83192e + languageName: node + linkType: hard + +"@swc/counter@npm:^0.1.1": + version: 0.1.2 + resolution: "@swc/counter@npm:0.1.2" + checksum: 8427c594f1f0cf44b83885e9c8fe1e370c9db44ae96e07a37c117a6260ee97797d0709483efbcc244e77bac578690215f45b23254c4cd8a70fb25ddbb50bf33e + languageName: node + linkType: hard + +"@swc/types@npm:^0.1.5": + version: 0.1.5 + resolution: "@swc/types@npm:0.1.5" + checksum: 6aee11f62d3d805a64848e0bd5f0e0e615f958e327a9e1260056c368d7d28764d89e38bd8005a536c9bf18afbcd303edd84099d60df34a2975d62540f61df13b languageName: node linkType: hard @@ -6899,6 +7055,20 @@ __metadata: languageName: node linkType: hard +"@transloadit/prettier-bytes@npm:0.0.7": + version: 0.0.7 + resolution: "@transloadit/prettier-bytes@npm:0.0.7" + checksum: af075e1b2b045cac55d5ab854b5c94273ef7f4bd825f05fe578559465f206d2a1535343b50170252a9efb31ffdc2d6420e64eb32d2faeabeeb8b7d81d5d46ef0 + languageName: node + linkType: hard + +"@transloadit/prettier-bytes@npm:0.0.9": + version: 0.0.9 + resolution: "@transloadit/prettier-bytes@npm:0.0.9" + checksum: efa5a723c41e7bce7ad17d1affe6a43209df857e17dc2b12a7c7bd6d3c921df8298086dbfb62ed740ca3e617d8c7f47485bb311adb637b20f2f75a28b08bac4f + languageName: node + linkType: hard + "@trysound/sax@npm:0.2.0": version: 0.2.0 resolution: "@trysound/sax@npm:0.2.0" @@ -8025,6 +8195,156 @@ __metadata: languageName: node linkType: hard +"@uppy/angular@npm:^0.6.1": + version: 0.6.1 + resolution: "@uppy/angular@npm:0.6.1" + dependencies: + tslib: ^2.0.0 + peerDependencies: + "@angular/common": ^16.2.0 + "@angular/core": ^16.2.0 + "@uppy/core": ^3.6.0 + "@uppy/dashboard": ^3.6.0 + "@uppy/drag-drop": ^3.0.3 + "@uppy/progress-bar": ^3.0.4 + "@uppy/status-bar": ^3.2.5 + "@uppy/utils": ^5.5.2 + checksum: e99ca6cae9dc41013044e19f0da65a6c65d5616af0ac84b81887f7a516ea6acd1a4894dfdc0f5930dc1fec389807956a92209c1ffd6b158feefc727084935271 + languageName: node + linkType: hard + +"@uppy/core@npm:^3.7.1": + version: 3.7.1 + resolution: "@uppy/core@npm:3.7.1" + dependencies: + "@transloadit/prettier-bytes": 0.0.9 + "@uppy/store-default": ^3.0.5 + "@uppy/utils": ^5.6.0 + lodash: ^4.17.21 + mime-match: ^1.0.2 + namespace-emitter: ^2.0.1 + nanoid: ^4.0.0 + preact: ^10.5.13 + checksum: 6561cfa0218cf665371ec9caef3486ff216ca2daaafdc7b99567d4e8c1ec360707d275e2ac46769ce1244529cf5f871fe05c35b35f1604af6ec4bb8dfbea1f26 + languageName: node + linkType: hard + +"@uppy/dashboard@npm:^3.7.1": + version: 3.7.1 + resolution: "@uppy/dashboard@npm:3.7.1" + dependencies: + "@transloadit/prettier-bytes": 0.0.7 + "@uppy/informer": ^3.0.4 + "@uppy/provider-views": ^3.7.0 + "@uppy/status-bar": ^3.2.5 + "@uppy/thumbnail-generator": ^3.0.6 + "@uppy/utils": ^5.6.0 + classnames: ^2.2.6 + is-shallow-equal: ^1.0.1 + lodash: ^4.17.21 + memoize-one: ^6.0.0 + nanoid: ^4.0.0 + preact: ^10.5.13 + peerDependencies: + "@uppy/core": ^3.7.1 + checksum: 0e86f6e0cf15034479d22767349f5d3bc92961f73d0f1d68891f68d1e3325b1b27adab838605440c72e9bed87b73cb8a2d9a6781d8eb5177b468987011324e61 + languageName: node + linkType: hard + +"@uppy/drag-drop@npm:^3.0.3": + version: 3.0.3 + resolution: "@uppy/drag-drop@npm:3.0.3" + dependencies: + "@uppy/utils": ^5.4.3 + preact: ^10.5.13 + peerDependencies: + "@uppy/core": ^3.4.0 + checksum: e3eacbc6df61e33c22c934a2fcc51865e4cd8e8d6712690c79d24311ee6afab08a4cc40e383cfb404c0e76a93d1810c309a652592faff0c4b9ed4cb673e41e99 + languageName: node + linkType: hard + +"@uppy/informer@npm:^3.0.4": + version: 3.0.4 + resolution: "@uppy/informer@npm:3.0.4" + dependencies: + "@uppy/utils": ^5.5.2 + preact: ^10.5.13 + peerDependencies: + "@uppy/core": ^3.6.0 + checksum: e4bffe78fe08601a36e59ef98439e84aa10833b8f286af2e3d85cd60cce6161e691312c8e1ac2f3c5552252e76bc62800e969bbc2f17bb40a728ff473f2495fd + languageName: node + linkType: hard + +"@uppy/progress-bar@npm:^3.0.4": + version: 3.0.4 + resolution: "@uppy/progress-bar@npm:3.0.4" + dependencies: + "@uppy/utils": ^5.5.2 + preact: ^10.5.13 + peerDependencies: + "@uppy/core": ^3.6.0 + checksum: 18cd69471946c11a1575ba760dc7c92cb17c4a72599b2377833ec0d76876e54dc2fdbf38d1fd35404f4b2031e4024c30fe0ad8ff7b91ce4028e9f8cf3334357d + languageName: node + linkType: hard + +"@uppy/provider-views@npm:^3.7.0": + version: 3.7.0 + resolution: "@uppy/provider-views@npm:3.7.0" + dependencies: + "@uppy/utils": ^5.6.0 + classnames: ^2.2.6 + nanoid: ^4.0.0 + p-queue: ^7.3.4 + preact: ^10.5.13 + peerDependencies: + "@uppy/core": ^3.7.0 + checksum: 8f1d499a4f5ca4dd658115ba34358cecba99bc1d67cd7fee01761eef5a74a347739f79c44a35638fe1074175a70640af8a5cfd327e02bcf6f7a446d91a102f52 + languageName: node + linkType: hard + +"@uppy/status-bar@npm:^3.2.5": + version: 3.2.5 + resolution: "@uppy/status-bar@npm:3.2.5" + dependencies: + "@transloadit/prettier-bytes": 0.0.9 + "@uppy/utils": ^5.5.2 + classnames: ^2.2.6 + preact: ^10.5.13 + peerDependencies: + "@uppy/core": ^3.6.0 + checksum: 55a494b03885517bc0be8f27c455b122cdda4f823136e3fae7f692494684bf2a931024728f0b57530ece788a22e6b1ebeaedf4e9b58acaa6de439b97c39f76c0 + languageName: node + linkType: hard + +"@uppy/store-default@npm:^3.0.5": + version: 3.1.0 + resolution: "@uppy/store-default@npm:3.1.0" + checksum: e1042ab02af11d63bd176e0c5eba48bdf686be2de25333fd045e75b5edf34d7714d78c603d3513a25d63eb587fc67894acc6ccf886480e935457156c2f2cf298 + languageName: node + linkType: hard + +"@uppy/thumbnail-generator@npm:^3.0.6": + version: 3.0.6 + resolution: "@uppy/thumbnail-generator@npm:3.0.6" + dependencies: + "@uppy/utils": ^5.5.2 + exifr: ^7.0.0 + peerDependencies: + "@uppy/core": ^3.6.0 + checksum: d78ebc96f99f54d0ec3621f5e2ff8e71a624fbb184633cfd2a350bd9b9bc76eca630d3b5fa28c30424e06f9027d8d85789a88e99ff03244523808d82109cb299 + languageName: node + linkType: hard + +"@uppy/utils@npm:^5.4.3, @uppy/utils@npm:^5.5.2, @uppy/utils@npm:^5.6.0": + version: 5.6.0 + resolution: "@uppy/utils@npm:5.6.0" + dependencies: + lodash: ^4.17.21 + preact: ^10.5.13 + checksum: 51456f691b50efed4aacd6600aad8a2111e57ec2dc8f0f02982a13c863243eeda016edce8b0fabbfbe277b2286e9b56786d74995c76a97a6194a5461ffee77e0 + languageName: node + linkType: hard + "@vendure/ngx-translate-extract@npm:^8": version: 8.2.2 resolution: "@vendure/ngx-translate-extract@npm:8.2.2" @@ -9696,6 +10016,13 @@ __metadata: languageName: node linkType: hard +"classnames@npm:^2.2.6": + version: 2.3.2 + resolution: "classnames@npm:2.3.2" + checksum: 2c62199789618d95545c872787137262e741f9db13328e216b093eea91c85ef2bfb152c1f9e63027204e2559a006a92eb74147d46c800a9f96297ae1d9f96f4e + languageName: node + linkType: hard + "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" @@ -9928,7 +10255,7 @@ __metadata: languageName: node linkType: hard -"colorette@npm:^2.0.10, colorette@npm:^2.0.16, colorette@npm:^2.0.20": +"colorette@npm:^2.0.10, colorette@npm:^2.0.16, colorette@npm:^2.0.19, colorette@npm:^2.0.20": version: 2.0.20 resolution: "colorette@npm:2.0.20" checksum: 0c016fea2b91b733eb9f4bcdb580018f52c0bc0979443dad930e5037a968237ac53d9beb98e218d2e9235834f8eebce7f8e080422d6194e957454255bde71d3d @@ -12562,6 +12889,13 @@ __metadata: languageName: node linkType: hard +"exifr@npm:^7.0.0": + version: 7.1.3 + resolution: "exifr@npm:7.1.3" + checksum: c75a21e700378a29d226dd2c102d43679a68539ff1774b05ca19acce366ad47d056985e4f497afe7da6d0d8966d7dc73efb51acc11ff84fa57c9467e630c67ff + languageName: node + linkType: hard + "exit@npm:^0.1.2": version: 0.1.2 resolution: "exit@npm:0.1.2" @@ -14543,6 +14877,13 @@ __metadata: languageName: node linkType: hard +"is-shallow-equal@npm:^1.0.1": + version: 1.0.1 + resolution: "is-shallow-equal@npm:1.0.1" + checksum: 6bd0981c14c4c9219449c9bea4c73035defc4544394b96392573515046c1165c770a19a87c88457c40f0983f94f6750d14b0d207b27be00727e273dc4e0f5a35 + languageName: node + linkType: hard + "is-stream@npm:^2.0.0": version: 2.0.1 resolution: "is-stream@npm:2.0.1" @@ -16275,6 +16616,13 @@ __metadata: languageName: node linkType: hard +"memoize-one@npm:^6.0.0": + version: 6.0.0 + resolution: "memoize-one@npm:6.0.0" + checksum: f185ea69f7cceae5d1cb596266dcffccf545e8e7b4106ec6aa93b71ab9d16460dd118ac8b12982c55f6d6322fcc1485de139df07eacffaae94888b9b3ad7675f + languageName: node + linkType: hard + "memory-pager@npm:^1.0.2": version: 1.5.0 resolution: "memory-pager@npm:1.5.0" @@ -16338,6 +16686,15 @@ __metadata: languageName: node linkType: hard +"mime-match@npm:^1.0.2": + version: 1.0.2 + resolution: "mime-match@npm:1.0.2" + dependencies: + wildcard: ^1.1.0 + checksum: 3e4afd6be98e20bfb421146a14147560941f471886e6d3534372b37d29bb7e35a7462e1f9cee98312f92e44969ae9deca2da7ad91ab5a738af55a7d5f03a6814 + languageName: node + linkType: hard + "mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:~2.1.17, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" @@ -16766,6 +17123,13 @@ __metadata: languageName: node linkType: hard +"namespace-emitter@npm:^2.0.1": + version: 2.0.1 + resolution: "namespace-emitter@npm:2.0.1" + checksum: 49ae49674d5b83e18ad91c549ed264df1fcba02d039617e0932dab618f79e3749de6d878d54962b5cbf2611c0eafc91203a376980399c33c30edf542f19cb034 + languageName: node + linkType: hard + "nanoid@npm:^3.3.6": version: 3.3.6 resolution: "nanoid@npm:3.3.6" @@ -16775,6 +17139,15 @@ __metadata: languageName: node linkType: hard +"nanoid@npm:^4.0.0": + version: 4.0.2 + resolution: "nanoid@npm:4.0.2" + bin: + nanoid: bin/nanoid.js + checksum: 747c399cea4664dd0be1d0ec498ffd1ef8f1f5221676fc8b577e3f46f66d9afcddb9595d63d19a2e78d0bc6cc33984f65e66bf1682c850b9e26288883d96b53f + languageName: node + linkType: hard + "napi-build-utils@npm:^1.0.1": version: 1.0.2 resolution: "napi-build-utils@npm:1.0.2" @@ -16912,18 +17285,6 @@ __metadata: languageName: node linkType: hard -"ngx-file-drop@npm:14.0.2": - version: 14.0.2 - resolution: "ngx-file-drop@npm:14.0.2" - dependencies: - tslib: ^2.3.0 - peerDependencies: - "@angular/common": ">=14.0.0" - "@angular/core": ">=14.0.0" - checksum: 4195811d537caf0026d77c99c7b1be3819b2f170031d3fe5b191e376c74e595ba9e1ba80bcfa8cc922aaee1c77f9e8c770dcc416468077ea11c475897b556427 - languageName: node - linkType: hard - "ngx-lottie@npm:^10.0.0": version: 10.0.0 resolution: "ngx-lottie@npm:10.0.0" @@ -17752,6 +18113,16 @@ __metadata: languageName: node linkType: hard +"p-queue@npm:^7.3.4": + version: 7.4.1 + resolution: "p-queue@npm:7.4.1" + dependencies: + eventemitter3: ^5.0.1 + p-timeout: ^5.0.2 + checksum: 1c6888aa994d399262a9fbdd49c7066f8359732397f7a42ecf03f22875a1d65899797b46413f97e44acc18dddafbcc101eb135c284714c931dbbc83c3967f450 + languageName: node + linkType: hard + "p-retry@npm:^4.5.0": version: 4.6.2 resolution: "p-retry@npm:4.6.2" @@ -17771,6 +18142,13 @@ __metadata: languageName: node linkType: hard +"p-timeout@npm:^5.0.2": + version: 5.1.0 + resolution: "p-timeout@npm:5.1.0" + checksum: f5cd4e17301ff1ff1d8dbf2817df0ad88c6bba99349fc24d8d181827176ad4f8aca649190b8a5b1a428dfd6ddc091af4606835d3e0cb0656e04045da5c9e270c + languageName: node + linkType: hard + "p-try@npm:^2.0.0": version: 2.2.0 resolution: "p-try@npm:2.2.0" @@ -18095,7 +18473,9 @@ __metadata: "@stencil/angular-output-target": ^0.7.1 "@stencil/core": 3.2.2 "@stencil/sass": ^3.0.2 - "@supabase/supabase-js": ^2.38.0 + "@supabase/supabase-js": ^2.38.5 + "@swc-node/register": ~1.6.7 + "@swc/core": ~1.3.85 "@types/c3": ^0.7.8 "@types/hammerjs": ^2.0.41 "@types/intro.js": ^5.1.1 @@ -18108,6 +18488,12 @@ __metadata: "@types/sharp": ^0.30.5 "@typescript-eslint/eslint-plugin": 6.11.0 "@typescript-eslint/parser": 6.11.0 + "@uppy/angular": ^0.6.1 + "@uppy/core": ^3.7.1 + "@uppy/dashboard": ^3.7.1 + "@uppy/drag-drop": ^3.0.3 + "@uppy/progress-bar": ^3.0.4 + "@uppy/status-bar": ^3.2.5 "@vendure/ngx-translate-extract": ^8 autoprefixer: ^10.4.0 c3: ^0.7.20 @@ -18155,7 +18541,6 @@ __metadata: mobx-angular: ^4.7.1 ng-packagr: 17.0.1 ngx-extended-pdf-viewer: ^18.1.7 - ngx-file-drop: 14.0.2 ngx-lottie: ^10.0.0 nx: 17.1.2 papaparse: ^5.3.2 @@ -18173,7 +18558,7 @@ __metadata: save-svg-as-png: ^1.4.17 sharp: ^0.31.3 stacktrace-js: ^2.0.2 - supabase: ^1.100.1 + supabase: ^1.113.2 tailwindcss: ^3.0.2 ts-jest: 29.1.1 ts-node: 10.9.1 @@ -18206,7 +18591,7 @@ __metadata: languageName: node linkType: hard -"pirates@npm:^4.0.1, pirates@npm:^4.0.4": +"pirates@npm:^4.0.1, pirates@npm:^4.0.4, pirates@npm:^4.0.5": version: 4.0.6 resolution: "pirates@npm:4.0.6" checksum: 46a65fefaf19c6f57460388a5af9ab81e3d7fd0e7bc44ca59d753cb5c4d0df97c6c6e583674869762101836d68675f027d60f841c105d72734df9dfca97cbcc6 @@ -18790,6 +19175,13 @@ __metadata: languageName: node linkType: hard +"preact@npm:^10.5.13": + version: 10.19.2 + resolution: "preact@npm:10.19.2" + checksum: fec27fa3f14ac2d7a5061818d0cf2973ffaece83126047a47e5a075aa8e40ca56b5fcebc36106ee9cf59be0aeb51f3d996760e158d2a2660b42cbfb2e71f37bf + languageName: node + linkType: hard + "prebuild-install@npm:^7.1.1": version: 7.1.1 resolution: "prebuild-install@npm:7.1.1" @@ -20431,7 +20823,7 @@ __metadata: languageName: node linkType: hard -"source-map-support@npm:0.5.21, source-map-support@npm:^0.5.5, source-map-support@npm:~0.5.20": +"source-map-support@npm:0.5.21, source-map-support@npm:^0.5.21, source-map-support@npm:^0.5.5, source-map-support@npm:~0.5.20": version: 0.5.21 resolution: "source-map-support@npm:0.5.21" dependencies: @@ -20873,9 +21265,9 @@ __metadata: languageName: node linkType: hard -"supabase@npm:^1.100.1": - version: 1.104.1 - resolution: "supabase@npm:1.104.1" +"supabase@npm:^1.113.2": + version: 1.115.2 + resolution: "supabase@npm:1.115.2" dependencies: bin-links: ^4.0.1 https-proxy-agent: ^7.0.2 @@ -20883,7 +21275,7 @@ __metadata: tar: 6.2.0 bin: supabase: bin/supabase - checksum: a4df57764a36d934562cf52b15e7cbe60e37996d81491e35c2a4d536bccbf96c97b95fac5b3682bfc6f0a4760234f89fb5fec2a5b69f4ee0222f8c18a6072af3 + checksum: 4257a406e5088d67435aea33d8b3e39d7c41b6f3ce4d6f6ef77dd11d6dbd067e19fd9169542d9913753cf6c76b52b9f082259ac375b2415dddb12417ce531f83 languageName: node linkType: hard @@ -22351,6 +22743,13 @@ __metadata: languageName: node linkType: hard +"wildcard@npm:^1.1.0": + version: 1.1.2 + resolution: "wildcard@npm:1.1.2" + checksum: f93bf48a23b7b776f7960fa7f252af55da265b4ce8127852e420f04a907b78073bc0412f74fc662f561667f3277473974f6553a260ece67f53b1975d128320ab + languageName: node + linkType: hard + "wildcard@npm:^2.0.0": version: 2.0.1 resolution: "wildcard@npm:2.0.1"