Skip to content

Commit

Permalink
build: fix deps
Browse files Browse the repository at this point in the history
  • Loading branch information
xmlking committed Feb 24, 2024
1 parent 797a0f0 commit b1b7e86
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 95 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ env:
IMAGE_NAME: ${{ github.repository }}/${{ inputs.app || 'console' }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
## app build time environment variables
VERCEL_ENV: production
PUBLIC_TERMS_PRIVACY_COMPANY: 'Your Company'
PUBLIC_TERMS_PRIVACY_EFFECTIVE_DATE: 'January 1, 2024'
PUBLIC_TERMS_PRIVACY_WEBSITE: 'yourdomain.com'
PUBLIC_TERMS_PRIVACY_CONTACT_EMAIL: '[email protected]'
PUBLIC_TERMS_PRIVACY_APP_NAME: 'Your App'
PUBLIC_TERMS_PRIVACY_APP_PRICING_AND_SUBSCRIPTIONS: '[Details about the pricing, subscription model, refund policy]'
PUBLIC_TERMS_PRIVACY_COUNTRY: 'United States'
RATE_LIMIT_SECRET: ${{ secrets.RATE_LIMIT_SECRET }}

permissions:
contents: write # needed to write releases
Expand Down
13 changes: 9 additions & 4 deletions apps/console-fb/src/hooks.client.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
import type { HandleClientError } from '@sveltejs/kit';
import { dev } from '$app/environment';
import { Logger } from '@spectacular/utils';
import { dev } from '$app/environment';

// Setup logger
if (!dev) {
Logger.enableProductionMode();
}

const log = new Logger('hooks:client');
// Initialize the Sentry SDK here
if (!dev) {
// TODO
}

export const handleClientError = (({ error, event }) => {
console.error('hooks:client:handleClientError:', error);
/**
* handle client-side errors
* TODO: Error monitoring via Sentry
*/
export const handleError: HandleClientError = ({ error }) => {
log.error('hooks:client:handleClientError:', error);
const err = error as App.Error;
return {
message: err.message ?? 'Whoops!',
context: err.context
};
}) satisfies HandleClientError;
};
16 changes: 10 additions & 6 deletions apps/console-fb/src/hooks.server.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { HandleFetch, HandleServerError } from '@sveltejs/kit';
import type { Handle, HandleFetch, HandleServerError } from '@sveltejs/kit';
import { sequence } from '@sveltejs/kit/hooks';
import { dev } from '$app/environment';
import { TokenVault } from '$lib/server/backend/TokenVault';
Expand Down Expand Up @@ -51,18 +51,22 @@ TokenVault.init([

// Invoked for each endpoint called and initially for SSR router
// export const handle = sequence(setUser, guard, houdini, logger);
export const handle = sequence(authjs, guard, houdini);
export const handle: Handle = sequence(authjs, guard, houdini);

export const handleServerError = (({ error, event }) => {
export const handleError: HandleServerError = async ({ error }) => {
console.error('hooks:server:handleServerError:', error);
const err = error as App.Error;
return {
message: err.message ?? 'Whoops!',
context: err.context
};
}) satisfies HandleServerError;
};

export const handleFetch = (async ({ event, request, fetch }) => {
/**
* This function allows you to modify (or replace) a fetch request
* that happens inside a `load` or `action` function that runs on the server (or during pre-rendering).
*/
export const handleFetch: HandleFetch = async ({ event, request, fetch }) => {
console.debug('hooks.server.ts, HandleFetch: pageUrl:', event.url.toString());

const token = TokenVault.getToken(request.url);
Expand All @@ -83,4 +87,4 @@ export const handleFetch = (async ({ event, request, fetch }) => {
}
*/
return fetch(request);
}) satisfies HandleFetch;
};
2 changes: 1 addition & 1 deletion apps/console-fb/src/lib/components/toast/Toasts.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { CloseButton } from 'flowbite-svelte';
import {
CheckSolid,
CheckCircleSolid ,
CheckCircleSolid,
ExclamationCircleOutline,
InfoCircleOutline
} from 'flowbite-svelte-icons';
Expand Down
2 changes: 1 addition & 1 deletion apps/console-fb/src/lib/utils/zod.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { z } from 'zod';
* preprocesses
* emptyStringToNull
*/
export const NullableFormString = z.preprocess((v) => v === "" ? null: v, z.string().nullish())
export const NullableFormString = z.preprocess((v) => (v === '' ? null : v), z.string().nullish());

/**
* Utility functions
Expand Down
2 changes: 1 addition & 1 deletion apps/console-fb/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { setupViewTransition } from 'sveltekit-view-transition';
import { onMount } from 'svelte';
import { pwaInfo } from 'virtual:pwa-info';
import { pwaAssetsHead } from 'virtual:pwa-assets/head';
import { pwaAssetsHead } from 'virtual:pwa-assets/head';
import { inject } from '@vercel/analytics';
import { Toasts } from '$lib/components/toast';
import { dev } from '$app/environment';
Expand Down
70 changes: 36 additions & 34 deletions apps/console-fb/tests/pwa/offline.spec.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,40 @@
import {test, expect} from '@playwright/test';
import { test, expect } from '@playwright/test';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const generateSW = true
const generateSW = true;

test('Test offline and trailing slashes', async ({ browser}) => {
// test offline + trailing slashes routes
const context = await browser.newContext()
const offlinePage = await context.newPage()
await offlinePage.goto('/')
const offlineSwURL = await offlinePage.evaluate(async () => {
const registration = await Promise.race([
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
navigator.serviceWorker.ready,
new Promise((_, reject) => setTimeout(() => reject(new Error('Service worker registration failed: time out')), 10000))
])
// @ts-expect-error registration is of type unknown
return registration.active?.scriptURL
});
const offlineSwName = generateSW ? 'sw.js' : 'prompt-sw.js'
expect(offlineSwURL).toBe(`http://localhost:4173/${offlineSwName}`);
await context.setOffline(true)
const aboutAnchor = offlinePage.getByRole('link', { name: 'About' })
expect(await aboutAnchor.getAttribute('href')).toBe('/about')
await aboutAnchor.click({ noWaitAfter: false })
const url = await offlinePage.evaluate(async () => {
await new Promise(resolve => setTimeout(resolve, 3000))
return location.href
})
expect(url).toBe('http://localhost:4173/about')
expect(offlinePage.locator('li[aria-current="page"] a').getByText('About')).toBeTruthy()
await offlinePage.reload({ waitUntil: 'load' })
expect(offlinePage.url()).toBe('http://localhost:4173/about')
expect(offlinePage.locator('li[aria-current="page"] a').getByText('About')).toBeTruthy()
// Dispose context once it's no longer needed.
await context.close();
test('Test offline and trailing slashes', async ({ browser }) => {
// test offline + trailing slashes routes
const context = await browser.newContext();
const offlinePage = await context.newPage();
await offlinePage.goto('/');
const offlineSwURL = await offlinePage.evaluate(async () => {
const registration = await Promise.race([
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
navigator.serviceWorker.ready,
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Service worker registration failed: time out')), 10000)
)
]);
// @ts-expect-error registration is of type unknown
return registration.active?.scriptURL;
});
const offlineSwName = generateSW ? 'sw.js' : 'prompt-sw.js';
expect(offlineSwURL).toBe(`http://localhost:4173/${offlineSwName}`);
await context.setOffline(true);
const aboutAnchor = offlinePage.getByRole('link', { name: 'About' });
expect(await aboutAnchor.getAttribute('href')).toBe('/about');
await aboutAnchor.click({ noWaitAfter: false });
const url = await offlinePage.evaluate(async () => {
await new Promise((resolve) => setTimeout(resolve, 3000));
return location.href;
});
expect(url).toBe('http://localhost:4173/about');
expect(offlinePage.locator('li[aria-current="page"] a').getByText('About')).toBeTruthy();
await offlinePage.reload({ waitUntil: 'load' });
expect(offlinePage.url()).toBe('http://localhost:4173/about');
expect(offlinePage.locator('li[aria-current="page"] a').getByText('About')).toBeTruthy();
// Dispose context once it's no longer needed.
await context.close();
});
94 changes: 50 additions & 44 deletions apps/console-fb/tests/pwa/sw.spec.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,57 @@
import {test, expect} from '@playwright/test';
import { test, expect } from '@playwright/test';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const generateSW = true

test('The service worker is registered and cache storage is present', async ({ page}) => {
await page.goto('/');

const swURL = await page.evaluate(async () => {
const registration = await Promise.race([
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
navigator.serviceWorker.ready,
new Promise((_, reject) => setTimeout(() => reject(new Error('Service worker registration failed: time out')), 10000))
])
// @ts-expect-error registration is of type unknown
return registration.active?.scriptURL
});
const swName = generateSW ? 'sw.js' : 'prompt-sw.js'
expect(swURL).toBe(`http://localhost:4173/${swName}`);

const cacheContents = await page.evaluate(async () => {
const cacheState: Record<string, Array<string>> = {};
for (const cacheName of await caches.keys()) {
const cache = await caches.open(cacheName);
cacheState[cacheName] = (await cache.keys()).map((req) => req.url);
}
return cacheState;
});

expect(Object.keys(cacheContents).length).toEqual(1)

const key = 'workbox-precache-v2-http://localhost:4173/'

expect(Object.keys(cacheContents)[0]).toEqual(key)

const urls = cacheContents[key].map(url => url.slice('http://localhost:4173/'.length))

/*
const generateSW = true;

test('The service worker is registered and cache storage is present', async ({ page }) => {
await page.goto('/');

const swURL = await page.evaluate(async () => {
const registration = await Promise.race([
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
navigator.serviceWorker.ready,
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Service worker registration failed: time out')), 10000)
)
]);
// @ts-expect-error registration is of type unknown
return registration.active?.scriptURL;
});
const swName = generateSW ? 'sw.js' : 'prompt-sw.js';
expect(swURL).toBe(`http://localhost:4173/${swName}`);

const cacheContents = await page.evaluate(async () => {
const cacheState: Record<string, Array<string>> = {};
for (const cacheName of await caches.keys()) {
const cache = await caches.open(cacheName);
cacheState[cacheName] = (await cache.keys()).map((req) => req.url);
}
return cacheState;
});

expect(Object.keys(cacheContents).length).toEqual(1);

const key = 'workbox-precache-v2-http://localhost:4173/';

expect(Object.keys(cacheContents)[0]).toEqual(key);

const urls = cacheContents[key].map((url) => url.slice('http://localhost:4173/'.length));

/*
'http://localhost:4173/about?__WB_REVISION__=38251751d310c9b683a1426c22c135a2',
'http://localhost:4173/?__WB_REVISION__=073370aa3804305a787b01180cd6b8aa',
'http://localhost:4173/manifest.webmanifest?__WB_REVISION__=27df2fa4f35d014b42361148a2207da3'
*/
expect(urls.some(url => url.startsWith('manifest.webmanifest?__WB_REVISION__='))).toEqual(true)
expect(urls.some(url => url.startsWith('?__WB_REVISION__='))).toEqual(true)
expect(urls.some(url => url.startsWith('about?__WB_REVISION__='))).toEqual(true)
// dontCacheBustURLsMatching: any asset in _app/immutable folder shouldn't have a revision (?__WB_REVISION__=)
expect(urls.some(url => url.startsWith('_app/immutable/') && url.endsWith('.css'))).toEqual(true)
expect(urls.some(url => url.startsWith('_app/immutable/') && url.endsWith('.js'))).toEqual(true)
expect(urls.some(url => url.includes('_app/version.json?__WB_REVISION__='))).toEqual(true)
expect(urls.some((url) => url.startsWith('manifest.webmanifest?__WB_REVISION__='))).toEqual(true);
expect(urls.some((url) => url.startsWith('?__WB_REVISION__='))).toEqual(true);
expect(urls.some((url) => url.startsWith('about?__WB_REVISION__='))).toEqual(true);
// dontCacheBustURLsMatching: any asset in _app/immutable folder shouldn't have a revision (?__WB_REVISION__=)
expect(urls.some((url) => url.startsWith('_app/immutable/') && url.endsWith('.css'))).toEqual(
true
);
expect(urls.some((url) => url.startsWith('_app/immutable/') && url.endsWith('.js'))).toEqual(
true
);
expect(urls.some((url) => url.includes('_app/version.json?__WB_REVISION__='))).toEqual(true);
});
2 changes: 1 addition & 1 deletion apps/console-fb/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default defineConfig({
navigateFallback: '/'
},
pwaAssets: {
config: true,
config: true
},
includeAssets: [
'favicon.ico',
Expand Down
2 changes: 1 addition & 1 deletion apps/console/.env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERCEL_ENV=dev
VERCEL_ENV=development

### Privacy and Terms ###
PUBLIC_TERMS_PRIVACY_COMPANY='Your Company'
Expand Down
4 changes: 2 additions & 2 deletions apps/console/src/hooks.server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { sequence } from '@sveltejs/kit/hooks';
import type { Handle, HandleServerError } from '@sveltejs/kit';
import type { Handle, HandleFetch, HandleServerError } from '@sveltejs/kit';
import { Logger } from '@spectacular/utils';
import { ZodError } from 'zod';
import { GraphQLError } from 'graphql';
Expand Down Expand Up @@ -60,7 +60,7 @@ export const handleError: HandleServerError = async ({ error, status, message /*
* This function allows you to modify (or replace) a fetch request
* that happens inside a `load` or `action` function that runs on the server (or during pre-rendering).
*/
export const handleFetch = async ({ event, request, fetch }) => {
export const handleFetch: HandleFetch = async ({ event, request, fetch }) => {
console.debug('handleFetch:', event.url.toString());
/*
if (request.url.startsWith('https://graph.microsoft.com')) {
Expand Down

0 comments on commit b1b7e86

Please sign in to comment.