diff --git a/src/module.ts b/src/module.ts index 015e2c5..0db2516 100644 --- a/src/module.ts +++ b/src/module.ts @@ -1,4 +1,4 @@ -import { defineNuxtModule, createResolver, addServerImportsDir } from '@nuxt/kit' +import { defineNuxtModule, createResolver, addImports, addServerImportsDir } from '@nuxt/kit' // Module options TypeScript interface definition export interface ModuleOptions { @@ -15,6 +15,12 @@ export default defineNuxtModule({ const resolver = createResolver(import.meta.url) nuxt.options.alias['#api-utils'] = resolver.resolve('./runtime/types/index.d.ts') + const composables = [ + { name: 'useApiFetch', from: resolver.resolve('./runtime/app/composables/apiFetch') }, + ] + + addImports(composables) + addServerImportsDir(resolver.resolve('./runtime/server/utils')) }, }) diff --git a/src/runtime/app/composables/apiFetch.ts b/src/runtime/app/composables/apiFetch.ts new file mode 100644 index 0000000..261c8f3 --- /dev/null +++ b/src/runtime/app/composables/apiFetch.ts @@ -0,0 +1 @@ +export const useApiFetch = $fetch.create({}) diff --git a/src/runtime/server/utils/authorize.ts b/src/runtime/server/utils/authorize.ts index 1772766..2be0649 100644 --- a/src/runtime/server/utils/authorize.ts +++ b/src/runtime/server/utils/authorize.ts @@ -1,3 +1,5 @@ +import { createError } from 'h3' + type PolicyFunction = (args: T) => boolean | Promise export async function authorize( diff --git a/src/runtime/server/utils/hash.ts b/src/runtime/server/utils/hash.ts new file mode 100644 index 0000000..2666706 --- /dev/null +++ b/src/runtime/server/utils/hash.ts @@ -0,0 +1,56 @@ +import { randomBytes } from 'node:crypto' + +/** + * Generate a unique hash from a string + * @param payload - The string to hash + */ +export async function hashFromPayload(payload: string): Promise { + const encoder = new TextEncoder() + const data = encoder.encode(payload) + const hashBuffer = await crypto.subtle.digest('SHA-256', data) + const hashArray = Array.from(new Uint8Array(hashBuffer)) + return hashArray.map(b => b.toString(16).padStart(2, '0')).join('') +} + +/** + * Generate a unique hash from a file + * @param file + */ +export async function hashFromFile(file: File) { + return await crypto.subtle + .digest('SHA-256', await file.arrayBuffer()) + .then(buf => Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2, '0')).join('')) +} + +/** + * Generates a hash from the content of a URL + * Returns the hash and the file a Blob + * @param url + */ + +export async function hashFromUrl(url: string): Promise<{ imageHash: string, imageFile: File }> { + const response = await fetch(url) + const imageBlob = await response.blob() + const imageFile = new File([imageBlob], 'avatar', { type: imageBlob.type }) + const imageHash = await hashFromFile(imageFile) + return { imageHash, imageFile } +} + +/** + * Generates a random hash from a set of characters + * @param length The length of the hash + * @param lower Whether to use only lowercase characters + */ +export function hashGenerate(length: number = 32, lower = false): string { + const charsetAll = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + const charsetLower = 'abcdefghijklmnopqrstuvwxyz0123456789' + const charset = lower ? charsetLower : charsetAll + const bytes = randomBytes(length) + let result = '' + + for (let i = 0; i < length; i++) { + result += charset[bytes[i] % charset.length] + } + + return result +}