diff --git a/packages/fieldlens-core/tsconfig.app.json b/packages/fieldlens-core/tsconfig.app.json new file mode 100644 index 0000000..cfba3d5 --- /dev/null +++ b/packages/fieldlens-core/tsconfig.app.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "es2023", + "lib": ["ES2023", "DOM"], + "module": "esnext", + "types": ["vite/client", "vite-plugin-pwa/react"], + "allowArbitraryExtensions": true, + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + "strict": true, + + /* Linting */ + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"] +} diff --git a/packages/fieldlens-core/tsconfig.json b/packages/fieldlens-core/tsconfig.json new file mode 100644 index 0000000..1ffef60 --- /dev/null +++ b/packages/fieldlens-core/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/packages/fieldlens-core/tsconfig.node.json b/packages/fieldlens-core/tsconfig.node.json new file mode 100644 index 0000000..8455dcb --- /dev/null +++ b/packages/fieldlens-core/tsconfig.node.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "es2023", + "lib": ["ES2023"], + "types": ["node"], + "skipLibCheck": true, + + /* Bundler mode */ + "module": "nodenext", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["vite.config.ts"] +} diff --git a/packages/fieldlens-core/vite.config.ts b/packages/fieldlens-core/vite.config.ts new file mode 100644 index 0000000..3f0d4aa --- /dev/null +++ b/packages/fieldlens-core/vite.config.ts @@ -0,0 +1,47 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import { VitePWA } from 'vite-plugin-pwa' + +export default defineConfig({ + plugins: [ + react(), + VitePWA({ + registerType: 'prompt', + includeAssets: ['fieldlens-mark.svg', 'apple-touch-icon.png', 'pwa-192.png', 'pwa-512.png'], + manifest: { + name: 'FieldLens Capture', + short_name: 'FieldLens', + description: 'Offline barcode capture and duplicate detection.', + theme_color: '#17211f', + background_color: '#f7f7f2', + display: 'standalone', + start_url: '/', + icons: [ + { + src: '/pwa-192.png', + sizes: '192x192', + type: 'image/png', + purpose: 'any', + }, + { + src: '/pwa-512.png', + sizes: '512x512', + type: 'image/png', + purpose: 'any', + }, + { + src: '/pwa-512.png', + sizes: '512x512', + type: 'image/png', + purpose: 'maskable', + }, + ], + }, + workbox: { + cleanupOutdatedCaches: true, + navigateFallback: '/index.html', + globPatterns: ['**/*.{js,css,html,svg,wasm}'], + }, + }), + ], +}) diff --git a/scripts/validate-migrations.mjs b/scripts/validate-migrations.mjs new file mode 100644 index 0000000..ffd3bcf --- /dev/null +++ b/scripts/validate-migrations.mjs @@ -0,0 +1,17 @@ +import { readdir, readFile } from 'node:fs/promises' + +const files = (await readdir(new URL('../migrations/', import.meta.url))) + .filter((name) => /^\d{3}_.+\.sql$/.test(name)) + .sort() + +if (files.length === 0) throw new Error('No migrations found') + +for (const file of files) { + const sql = await readFile(new URL(`../migrations/${file}`, import.meta.url), 'utf8') + if (!sql.trim()) throw new Error(`${file} is empty`) + if (/\bDROP\s+(DATABASE|SCHEMA)\b/i.test(sql)) { + throw new Error(`${file} contains destructive database/schema DDL`) + } +} + +console.log(JSON.stringify({ ok: true, migrations: files }))