2026-04-12 08:58:41 +01:00
|
|
|
import path from 'node:path';
|
|
|
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
|
|
|
|
|
|
import tailwindcss from '@tailwindcss/vite';
|
|
|
|
|
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
|
|
|
|
import { defineConfig } from 'vite';
|
|
|
|
|
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js';
|
|
|
|
|
|
|
|
|
|
const dirname = path.dirname(fileURLToPath(import.meta.url));
|
2026-06-12 02:04:42 +01:00
|
|
|
const devApiUrl = process.env.API_URL ?? 'http://localhost:3002';
|
|
|
|
|
|
|
|
|
|
function embedApiUrlInjectPlugin() {
|
|
|
|
|
const bootstrapFiles = [
|
|
|
|
|
path.resolve(dirname, 'src/widgets/course-widget/bootstrap.ts'),
|
|
|
|
|
path.resolve(dirname, 'src/widgets/question-type-picker/bootstrap.ts')
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
name: 'embed-api-url-inject',
|
|
|
|
|
transform(code: string, id: string) {
|
|
|
|
|
if (!bootstrapFiles.includes(id) || !devApiUrl) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const snippet = `window.CIO=window.CIO||{};window.CIO.apiBaseUrl=${JSON.stringify(devApiUrl.replace(/\/$/, ''))};`;
|
|
|
|
|
return { code: `${snippet}\n${code}`, map: null };
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
2026-04-27 11:40:38 +01:00
|
|
|
const embedEntries = {
|
|
|
|
|
'question-type-picker': path.resolve(dirname, 'src/widgets/question-type-picker/bootstrap.ts'),
|
|
|
|
|
'course-widget': path.resolve(dirname, 'src/widgets/course-widget/bootstrap.ts')
|
|
|
|
|
} as const;
|
|
|
|
|
const embedDevEntrypoints = {
|
2026-06-12 02:04:42 +01:00
|
|
|
'/question-type-picker': '/src/widgets/question-type-picker/bootstrap.ts',
|
|
|
|
|
'/course-widget': '/src/widgets/course-widget/bootstrap.ts',
|
2026-04-27 11:40:38 +01:00
|
|
|
'/embeds/question-type-picker/question-type-picker.js': '/src/widgets/question-type-picker/bootstrap.ts',
|
2026-05-19 16:32:42 +01:00
|
|
|
'/embeds/course-widget/course-widget.js': '/src/widgets/course-widget/bootstrap.ts',
|
|
|
|
|
'/embeds/course-widget/embed.html': '/src/widgets/course-widget/embed.html'
|
2026-04-27 11:40:38 +01:00
|
|
|
} as const;
|
2026-04-12 08:58:41 +01:00
|
|
|
|
2026-04-27 11:40:38 +01:00
|
|
|
function embedDevEntryPlugin() {
|
|
|
|
|
return {
|
|
|
|
|
name: 'embed-dev-entry-plugin',
|
|
|
|
|
configureServer(server: {
|
|
|
|
|
middlewares: { use: (handler: (req: { url?: string }, res: unknown, next: () => void) => void) => void };
|
|
|
|
|
}) {
|
|
|
|
|
server.middlewares.use((req, _res, next) => {
|
|
|
|
|
const requestUrl = req.url ?? '';
|
|
|
|
|
const [pathname, search = ''] = requestUrl.split('?');
|
2026-06-12 02:04:42 +01:00
|
|
|
const querySuffix = search ? `?${search}` : '';
|
|
|
|
|
|
|
|
|
|
if (pathname === '/course-widget') {
|
|
|
|
|
const params = new URLSearchParams(search);
|
|
|
|
|
const target = params.has('key')
|
|
|
|
|
? '/src/widgets/course-widget/embed.html'
|
|
|
|
|
: '/src/widgets/course-widget/bootstrap.ts';
|
|
|
|
|
req.url = `${target}${querySuffix}`;
|
|
|
|
|
next();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pathname === '/question-type-picker') {
|
|
|
|
|
req.url = `/src/widgets/question-type-picker/bootstrap.ts${querySuffix}`;
|
|
|
|
|
next();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-27 11:40:38 +01:00
|
|
|
const rewrittenPath = embedDevEntrypoints[pathname as keyof typeof embedDevEntrypoints];
|
|
|
|
|
|
|
|
|
|
if (rewrittenPath) {
|
2026-06-12 02:04:42 +01:00
|
|
|
req.url = `${rewrittenPath}${querySuffix}`;
|
2026-04-27 11:40:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default defineConfig(({ command, mode }) => {
|
|
|
|
|
const buildTarget = mode in embedEntries ? (mode as keyof typeof embedEntries) : null;
|
|
|
|
|
const buildEntry = buildTarget ? { [buildTarget]: embedEntries[buildTarget] } : embedEntries;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
root: dirname,
|
2026-06-12 02:04:42 +01:00
|
|
|
plugins: [
|
|
|
|
|
embedDevEntryPlugin(),
|
|
|
|
|
...(command === 'serve' ? [embedApiUrlInjectPlugin()] : []),
|
|
|
|
|
tailwindcss(),
|
|
|
|
|
svelte(),
|
|
|
|
|
cssInjectedByJsPlugin()
|
|
|
|
|
],
|
2026-04-27 11:40:38 +01:00
|
|
|
resolve: {
|
|
|
|
|
alias: {
|
|
|
|
|
'@cio/ui': path.resolve(dirname, 'node_modules/@cio/ui/src'),
|
|
|
|
|
'@cio/ui/*': path.resolve(dirname, 'node_modules/@cio/ui/src/*'),
|
|
|
|
|
$src: path.resolve(dirname, 'node_modules/@cio/ui/src')
|
|
|
|
|
},
|
|
|
|
|
conditions: ['svelte', 'browser', 'import']
|
2026-04-12 08:58:41 +01:00
|
|
|
},
|
2026-04-27 11:40:38 +01:00
|
|
|
optimizeDeps: {
|
|
|
|
|
include: ['svelte-tiptap'],
|
|
|
|
|
exclude: ['@tiptap/core', '@tiptap/pm']
|
|
|
|
|
},
|
|
|
|
|
build:
|
|
|
|
|
command === 'build'
|
|
|
|
|
? {
|
|
|
|
|
outDir: buildTarget ? `dist/${buildTarget}` : 'dist',
|
|
|
|
|
emptyOutDir: false,
|
|
|
|
|
cssCodeSplit: false,
|
|
|
|
|
lib: {
|
|
|
|
|
entry: buildEntry,
|
|
|
|
|
name: 'CIOEmbeds',
|
|
|
|
|
formats: ['es'],
|
|
|
|
|
fileName: (_format, entryName) => `${entryName}.js`
|
|
|
|
|
},
|
|
|
|
|
rollupOptions: {
|
|
|
|
|
output: {
|
|
|
|
|
inlineDynamicImports: false,
|
2026-06-12 02:04:42 +01:00
|
|
|
chunkFileNames: buildTarget ? `${buildTarget}-[name]-[hash].js` : '[name]-[hash].js'
|
2026-04-27 11:40:38 +01:00
|
|
|
}
|
2026-04-12 08:58:41 +01:00
|
|
|
}
|
|
|
|
|
}
|
2026-04-27 11:40:38 +01:00
|
|
|
: {},
|
|
|
|
|
server: {
|
|
|
|
|
port: 5180,
|
|
|
|
|
cors: true
|
|
|
|
|
},
|
|
|
|
|
preview: {
|
|
|
|
|
port: 4180,
|
|
|
|
|
cors: true
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
});
|