@wervt/nuxt 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/dev.d.ts +4 -4
- package/dist/dev.js +33 -11
- package/dist/env-types.js +13 -0
- package/dist/icons.js +30 -0
- package/dist/loading.js +30 -0
- package/dist/module.d.ts +0 -2
- package/dist/module.js +42 -2
- package/dist/node_modules/.pnpm/nitro@3.0.260903-beta/node_modules/nitro/dist/runtime/internal/task.js +1 -2
- package/dist/node_modules/.pnpm/nitro@3.0.260903-beta/node_modules/nitro/dist/runtime/task.js +1 -2
- package/dist/og-image.js +38 -0
- package/dist/preview.d.ts +1 -3
- package/dist/preview.js +1 -2
- package/dist/provision.d.ts +31 -4
- package/dist/provision.js +82 -21
- package/dist/route-tools.js +1 -2
- package/dist/runtime/app/plugins/analytics.client.d.ts +0 -2
- package/dist/runtime/app/plugins/analytics.client.js +1 -2
- package/dist/runtime/app/plugins/feedback.client.d.ts +0 -2
- package/dist/runtime/app/plugins/feedback.client.js +1 -2
- package/dist/runtime/app/plugins/update.client.d.ts +0 -2
- package/dist/runtime/app/plugins/update.client.js +1 -2
- package/dist/runtime/app/plugins/user.client.d.ts +0 -2
- package/dist/runtime/app/plugins/user.client.js +1 -2
- package/dist/runtime/app/plugins/webmcp.client.d.ts +0 -2
- package/dist/runtime/app/plugins/webmcp.client.js +1 -2
- package/dist/runtime/app/preview-error.d.ts +26 -0
- package/dist/runtime/app/preview-error.js +69 -0
- package/dist/runtime/app/snapshot.d.ts +15 -0
- package/dist/runtime/app/snapshot.js +63 -0
- package/dist/runtime/app/useShape.d.ts +8 -3
- package/dist/runtime/app/useShape.js +10 -55
- package/dist/runtime/app/useWervtFeedback.d.ts +1 -2
- package/dist/runtime/app/useWervtFeedback.js +1 -2
- package/dist/runtime/app/useWervtTrack.d.ts +1 -3
- package/dist/runtime/app/useWervtTrack.js +1 -2
- package/dist/runtime/app/useWervtUpdate.d.ts +1 -3
- package/dist/runtime/app/useWervtUpdate.js +2 -3
- package/dist/runtime/app/useWervtUser.d.ts +1 -3
- package/dist/runtime/app/useWervtUser.js +1 -2
- package/dist/runtime/email/components.d.ts +1 -3
- package/dist/runtime/email/components.js +1 -2
- package/dist/runtime/email/index.d.ts +2 -1
- package/dist/runtime/email/index.js +2 -1
- package/dist/runtime/email/invite.d.ts +73 -0
- package/dist/runtime/email/invite.js +59 -0
- package/dist/runtime/email/render.d.ts +1 -3
- package/dist/runtime/email/render.js +1 -2
- package/dist/runtime/server/access.d.ts +4 -5
- package/dist/runtime/server/access.js +4 -4
- package/dist/runtime/server/agent-token-plugin.d.ts +11 -0
- package/dist/runtime/server/agent-token-plugin.js +9 -0
- package/dist/runtime/server/anthropic.d.ts +19 -0
- package/dist/runtime/server/anthropic.js +52 -0
- package/dist/runtime/server/boot.d.ts +0 -2
- package/dist/runtime/server/boot.js +1 -2
- package/dist/runtime/server/db.d.ts +1 -3
- package/dist/runtime/server/db.js +1 -2
- package/dist/runtime/server/dev-auth.d.ts +0 -2
- package/dist/runtime/server/dev-auth.js +1 -2
- package/dist/runtime/server/email-preview.d.ts +0 -2
- package/dist/runtime/server/email-preview.js +1 -2
- package/dist/runtime/server/identity.d.ts +18 -0
- package/dist/runtime/server/identity.js +36 -0
- package/dist/runtime/server/index.d.ts +4 -3
- package/dist/runtime/server/index.js +4 -3
- package/dist/runtime/server/logger.d.ts +0 -2
- package/dist/runtime/server/logger.js +1 -2
- package/dist/runtime/server/mail.d.ts +1 -3
- package/dist/runtime/server/mail.js +1 -2
- package/dist/runtime/server/mcp-auth-server.d.ts +0 -2
- package/dist/runtime/server/mcp-auth-server.js +1 -2
- package/dist/runtime/server/mcp-auth.d.ts +1 -3
- package/dist/runtime/server/mcp-auth.js +1 -2
- package/dist/runtime/server/mcp-claims.d.ts +1 -3
- package/dist/runtime/server/mcp-claims.js +1 -2
- package/dist/runtime/server/mcp-metadata.d.ts +0 -2
- package/dist/runtime/server/mcp-metadata.js +1 -2
- package/dist/runtime/server/mcp.d.ts +0 -2
- package/dist/runtime/server/mcp.js +1 -2
- package/dist/runtime/server/preview-errors-plugin.d.ts +13 -0
- package/dist/runtime/server/preview-errors-plugin.js +19 -0
- package/dist/runtime/server/seed.d.ts +1 -3
- package/dist/runtime/server/seed.js +1 -2
- package/dist/runtime/server/shape.d.ts +1 -3
- package/dist/runtime/server/shape.js +1 -2
- package/dist/runtime/server/storage-plugin.d.ts +1 -3
- package/dist/runtime/server/storage-plugin.js +1 -2
- package/dist/runtime/server/task-handlers.d.ts +2 -3
- package/dist/runtime/server/task-handlers.js +1 -2
- package/dist/runtime/server/task-list-nitro2.d.ts +0 -2
- package/dist/runtime/server/task-list-nitro2.js +1 -2
- package/dist/runtime/server/task-list-nitro3.d.ts +0 -2
- package/dist/runtime/server/task-list-nitro3.js +1 -2
- package/dist/runtime/server/task-run-nitro2.d.ts +0 -2
- package/dist/runtime/server/task-run-nitro2.js +1 -2
- package/dist/runtime/server/task-run-nitro3.d.ts +0 -2
- package/dist/runtime/server/task-run-nitro3.js +1 -2
- package/dist/runtime/server/tasks.d.ts +1 -3
- package/dist/runtime/server/tasks.js +1 -2
- package/dist/runtime/server/tool-handlers.d.ts +1 -3
- package/dist/runtime/server/tool-handlers.js +1 -2
- package/dist/runtime/server/tool-list.js +1 -2
- package/dist/runtime/server/tool-run.js +1 -2
- package/dist/runtime/server/tools.d.ts +1 -2
- package/dist/runtime/server/tools.js +1 -2
- package/dist/runtime/server/user-route.d.ts +0 -2
- package/dist/runtime/server/user-route.js +1 -2
- package/dist/runtime/server/user.d.ts +9 -5
- package/dist/runtime/server/user.js +29 -5
- package/dist/runtime/server/validate.d.ts +1 -2
- package/dist/runtime/server/validate.js +1 -2
- package/dist/runtime/shared/agent-token.d.ts +7 -0
- package/dist/runtime/shared/agent-token.js +16 -0
- package/dist/runtime/shared/mark.d.ts +1 -0
- package/dist/runtime/shared/mark.js +3 -0
- package/dist/runtime/shared/preview-errors.d.ts +10 -0
- package/dist/runtime/shared/preview-errors.js +14 -0
- package/dist/runtime/shared/shape.d.ts +1 -2
- package/dist/runtime/shared/shape.js +1 -2
- package/dist/runtime/shared/user.d.ts +9 -3
- package/dist/runtime/shared/user.js +5 -3
- package/dist/seed.js +1 -2
- package/dist/shapes.js +1 -2
- package/dist/storage.d.ts +50 -4
- package/dist/storage.js +224 -5
- package/dist/studio-preview.js +34 -0
- package/package.json +17 -8
package/README.md
CHANGED
|
@@ -20,6 +20,8 @@ export default defineNuxtConfig({
|
|
|
20
20
|
- `useWervtUser()`: the signed-in wervt user, on the server and in the app.
|
|
21
21
|
- `useWervtAccess(event)`: invites on invite-only apps (`wervt access <app> --invite`), as the
|
|
22
22
|
signed-in user.
|
|
23
|
+
- `useAnthropic()` (`@wervt/nuxt/anthropic`): an Anthropic client without an API key, through the
|
|
24
|
+
app's wervt identity (`wervt identity enable <app>`); `useWorkloadIdentity()` for the raw token.
|
|
23
25
|
- `useValidatedBody()` / `useValidatedQuery()` / `useValidatedParams()`: valibot validation.
|
|
24
26
|
- `useWervtTrack()`: custom events for wervt's cookieless analytics (page views are counted automatically).
|
|
25
27
|
- `wervt: { feedback: { key } }` and `useWervtFeedback()`: the kontor feedback widget, reports go into a kontor project's triage.
|
package/dist/dev.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { WervtRole } from "./runtime/shared/user.js";
|
|
1
2
|
import "nuxt/schema";
|
|
2
|
-
//#region src/dev.d.ts
|
|
3
3
|
export interface DevOptions {
|
|
4
4
|
/** Superuser URL of the local wervt Postgres. */
|
|
5
5
|
adminUrl?: string;
|
|
@@ -18,7 +18,7 @@ export interface DevOptions {
|
|
|
18
18
|
seed?: boolean;
|
|
19
19
|
/**
|
|
20
20
|
* Who `/_wervt/login` signs in as during `nuxt dev` (there's no wervt auth locally).
|
|
21
|
-
* Defaults to a dev user with a Twitch account linked.
|
|
21
|
+
* Defaults to a dev user with a Twitch account linked. Without `role`, they're the app's owner.
|
|
22
22
|
*/
|
|
23
23
|
user?: {
|
|
24
24
|
id: string;
|
|
@@ -26,6 +26,6 @@ export interface DevOptions {
|
|
|
26
26
|
name?: string;
|
|
27
27
|
image?: string;
|
|
28
28
|
accounts?: Record<string, string>;
|
|
29
|
+
role?: WervtRole;
|
|
29
30
|
};
|
|
30
|
-
}
|
|
31
|
-
//#endregion
|
|
31
|
+
}
|
package/dist/dev.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { createStorage } from "./storage.js";
|
|
2
|
-
import { appDatabaseUrl, dbRole, provisionDatabase, storageCredentials } from "./provision.js";
|
|
2
|
+
import { appDatabaseUrl, dbRole, migrateAs, provisionDatabase, storageCredentials } from "./provision.js";
|
|
3
3
|
import { SEED_TASK, runDevSeed } from "./seed.js";
|
|
4
4
|
import { useLogger } from "nuxt/kit";
|
|
5
5
|
import { existsSync, watch } from "node:fs";
|
|
6
6
|
import { readFile } from "node:fs/promises";
|
|
7
7
|
import { join } from "node:path";
|
|
8
|
-
|
|
8
|
+
// src/dev.ts
|
|
9
9
|
const DEFAULTS = {
|
|
10
10
|
adminUrl: "postgres://postgres:postgres@localhost:5432/wervt",
|
|
11
11
|
dbSecret: "dev-secret",
|
|
@@ -22,6 +22,7 @@ const logger = useLogger("wervt");
|
|
|
22
22
|
* points the dev server at the app's database and Electric.
|
|
23
23
|
*/
|
|
24
24
|
async function setupDev(nuxt, app, options, features = {}) {
|
|
25
|
+
forgetOwnEnv(nuxt.options.rootDir);
|
|
25
26
|
const config = {
|
|
26
27
|
adminUrl: process.env.WERVT_PG_ADMIN_URL ?? options.adminUrl ?? DEFAULTS.adminUrl,
|
|
27
28
|
dbSecret: process.env.WERVT_DB_SECRET ?? options.dbSecret ?? DEFAULTS.dbSecret,
|
|
@@ -43,13 +44,18 @@ async function setupDev(nuxt, app, options, features = {}) {
|
|
|
43
44
|
secret: config.dbSecret,
|
|
44
45
|
migrationsFolder
|
|
45
46
|
};
|
|
47
|
+
const given = process.env.DATABASE_URL && process.env.WERVT_DB_SCHEMA ? {
|
|
48
|
+
url: process.env.DATABASE_URL,
|
|
49
|
+
schema: process.env.WERVT_DB_SCHEMA
|
|
50
|
+
} : void 0;
|
|
51
|
+
const database = given?.schema ?? dbRole(app);
|
|
46
52
|
let serverUrl;
|
|
47
53
|
let seedPending = false;
|
|
48
54
|
const seed = async () => {
|
|
49
55
|
if (!seedPending || !serverUrl) return;
|
|
50
56
|
seedPending = false;
|
|
51
57
|
try {
|
|
52
|
-
if ((await runDevSeed(serverUrl)).status === "seeded") logger.success(`Seeded \`${
|
|
58
|
+
if ((await runDevSeed(serverUrl)).status === "seeded") logger.success(`Seeded \`${database}\` (${SEED_TASK})`);
|
|
53
59
|
} catch (e) {
|
|
54
60
|
logger.warn(`\`${SEED_TASK}\` failed:`, e instanceof Error ? e.message : e);
|
|
55
61
|
}
|
|
@@ -60,21 +66,29 @@ async function setupDev(nuxt, app, options, features = {}) {
|
|
|
60
66
|
});
|
|
61
67
|
const migrate = async () => {
|
|
62
68
|
try {
|
|
63
|
-
const { fresh } = await
|
|
64
|
-
|
|
69
|
+
const { fresh } = given ? await migrateAs({
|
|
70
|
+
...given,
|
|
71
|
+
migrationsFolder
|
|
72
|
+
}) : await provisionDatabase(provision);
|
|
73
|
+
logger.success(`Database \`${database}\` is up to date`);
|
|
65
74
|
if (fresh && options.seed !== false) {
|
|
66
75
|
seedPending = true;
|
|
67
76
|
seed();
|
|
68
77
|
}
|
|
69
78
|
} catch (e) {
|
|
70
|
-
logger.warn(`Could not migrate \`${
|
|
79
|
+
logger.warn(given ? `Could not migrate \`${database}\`.` : `Could not migrate \`${database}\`. Is the wervt stack running (docker compose up -d)?`, e instanceof Error ? e.message : e);
|
|
71
80
|
}
|
|
72
81
|
};
|
|
73
82
|
await migrate();
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
83
|
+
const own = {
|
|
84
|
+
DATABASE_URL: await appDatabaseUrl(provision),
|
|
85
|
+
WERVT_DB_SCHEMA: dbRole(app),
|
|
86
|
+
ELECTRIC_URL: config.electricUrl,
|
|
87
|
+
ELECTRIC_SECRET: config.electricSecret
|
|
88
|
+
};
|
|
89
|
+
const set = Object.fromEntries(Object.entries(own).filter(([key]) => process.env[key] === void 0));
|
|
90
|
+
Object.assign(process.env, set);
|
|
91
|
+
process.env[OWN_ENV] = JSON.stringify(set);
|
|
78
92
|
let timer;
|
|
79
93
|
const watcher = watch(migrationsFolder, { recursive: true }, (_event, file) => {
|
|
80
94
|
if (!file?.endsWith(".sql")) return;
|
|
@@ -86,6 +100,15 @@ async function setupDev(nuxt, app, options, features = {}) {
|
|
|
86
100
|
});
|
|
87
101
|
nuxt.hook("close", () => watcher.close());
|
|
88
102
|
}
|
|
103
|
+
const OWN_ENV = "WERVT_DEV_OWN_ENV";
|
|
104
|
+
function forgetOwnEnv(rootDir) {
|
|
105
|
+
const own = process.env[OWN_ENV];
|
|
106
|
+
if (!own) return;
|
|
107
|
+
for (const [key, value] of Object.entries(JSON.parse(own))) if (process.env[key] === value) delete process.env[key];
|
|
108
|
+
delete process.env[OWN_ENV];
|
|
109
|
+
const file = join(rootDir, ".env");
|
|
110
|
+
if (existsSync(file)) process.loadEnvFile(file);
|
|
111
|
+
}
|
|
89
112
|
/** The app's bucket in the local Garage, and WERVT_S3_* for ablage, like in production. */
|
|
90
113
|
async function setupStorage(app, secret, options) {
|
|
91
114
|
const s3Url = process.env.WERVT_S3_URL ?? options.s3Url ?? DEFAULTS.s3Url;
|
|
@@ -118,5 +141,4 @@ async function resolveAppName(rootDir, name) {
|
|
|
118
141
|
}
|
|
119
142
|
return name.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
120
143
|
}
|
|
121
|
-
//#endregion
|
|
122
144
|
export { resolveAppName, setupDev };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// src/env-types.ts
|
|
2
|
+
/** `.nuxt/types/wervt-env.d.ts`: types for the `process.env` the isolate provides. */
|
|
3
|
+
const PROCESS_ENV_TYPES = `declare namespace NodeJS {
|
|
4
|
+
interface ProcessEnv {
|
|
5
|
+
[key: string]: string | undefined
|
|
6
|
+
}
|
|
7
|
+
interface Process {
|
|
8
|
+
env: ProcessEnv
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
declare var process: NodeJS.Process
|
|
12
|
+
`;
|
|
13
|
+
export { PROCESS_ENV_TYPES };
|
package/dist/icons.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { dependencyNames } from "./og-image.js";
|
|
2
|
+
// src/icons.ts
|
|
3
|
+
const ICONIFY_JSON = "@iconify-json/";
|
|
4
|
+
/** The whole Iconify set in one package; @nuxt/icon finds every collection in it. */
|
|
5
|
+
const ICONIFY_ALL = "@iconify/json";
|
|
6
|
+
/** Where the app's icons can come from without the Iconify API. */
|
|
7
|
+
async function iconSources(rootDir) {
|
|
8
|
+
const names = await dependencyNames(rootDir);
|
|
9
|
+
return {
|
|
10
|
+
collections: names.filter((name) => name.startsWith(ICONIFY_JSON)).map((name) => name.slice(14)).toSorted(),
|
|
11
|
+
everything: names.includes(ICONIFY_ALL)
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* @nuxt/icon defaults for a wervt build. Its `serverBundle: 'auto'` already resolves to the
|
|
16
|
+
* locally installed collections on the Deno preset (auto-discovery also covers layers and
|
|
17
|
+
* transitive deps), so only the API fallback needs changing: the isolate can't reach the Iconify
|
|
18
|
+
* API, and a server request would time out for every icon of a missing collection. The browser
|
|
19
|
+
* may still fall back. An app's own `icon` config wins over these.
|
|
20
|
+
*/
|
|
21
|
+
function iconDefaults() {
|
|
22
|
+
return { fallbackToApi: "client-only" };
|
|
23
|
+
}
|
|
24
|
+
/** Why icons won't render on wervt, if they won't. Nuxt UI's own icons are Lucide icons. */
|
|
25
|
+
function iconWarning(sources, nuxtUi) {
|
|
26
|
+
if (sources.everything) return void 0;
|
|
27
|
+
if (nuxtUi && !sources.collections.includes("lucide")) return "Nuxt UI uses Lucide icons, but `@iconify-json/lucide` is not installed, so they won't render on wervt (the isolate can't reach the Iconify API). Run `pnpm add -D @iconify-json/lucide`, plus `@iconify-json/<name>` for every other icon collection the app uses.";
|
|
28
|
+
if (sources.collections.length === 0) return "No icon collection is installed, so icons won't render on wervt (the isolate can't reach the Iconify API). Install the collections the app uses, e.g. `pnpm add -D @iconify-json/lucide`.";
|
|
29
|
+
}
|
|
30
|
+
export { iconDefaults, iconSources, iconWarning };
|
package/dist/loading.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { WERVT_MARK } from "./runtime/shared/mark.js";
|
|
2
|
+
// src/loading.ts
|
|
3
|
+
const previewLoadingTemplate = () => `<!doctype html>
|
|
4
|
+
<html lang="de">
|
|
5
|
+
<head>
|
|
6
|
+
<meta charset="utf-8">
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
|
8
|
+
<title>Einen Moment …</title>
|
|
9
|
+
<style>
|
|
10
|
+
:root { color-scheme: light dark; --fg: #0a0a0b; --muted: #6b6b70; --bg: #fafaf9; --a: #2f5bff; }
|
|
11
|
+
@media (prefers-color-scheme: dark) { :root { --fg: #fafaf9; --muted: #a1a1a6; --bg: #0a0a0b; --a: #5885ff; } }
|
|
12
|
+
html, body { height: 100%; margin: 0; }
|
|
13
|
+
body { display: grid; place-content: center; justify-items: center; gap: 1rem; background: var(--bg);
|
|
14
|
+
color: var(--fg); font: 500 1rem/1.4 system-ui, -apple-system, sans-serif; text-align: center; }
|
|
15
|
+
svg { width: 3rem; height: 3rem; color: var(--fg); animation: pulse 1.6s ease-in-out infinite; }
|
|
16
|
+
p { margin: 0; color: var(--muted); }
|
|
17
|
+
@keyframes pulse { 50% { opacity: .45; transform: scale(.94); } }
|
|
18
|
+
@media (prefers-reduced-motion: reduce) { svg { animation: none; } }
|
|
19
|
+
</style>
|
|
20
|
+
</head>
|
|
21
|
+
<body>
|
|
22
|
+
${WERVT_MARK}
|
|
23
|
+
<p id="m">Einen Moment, die App wird gerade aktualisiert …</p>
|
|
24
|
+
<script>
|
|
25
|
+
if (!navigator.language.toLowerCase().startsWith('de'))
|
|
26
|
+
document.getElementById('m').textContent = 'One moment, the app is being updated …'
|
|
27
|
+
<\/script>
|
|
28
|
+
</body>
|
|
29
|
+
</html>`;
|
|
30
|
+
export { previewLoadingTemplate };
|
package/dist/module.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { DevOptions } from "./dev.js";
|
|
2
2
|
import { PreviewOptions } from "./preview.js";
|
|
3
|
-
//#region src/module.d.ts
|
|
4
3
|
export interface ModuleOptions {
|
|
5
4
|
/** App name on wervt. Defaults to the package.json name. */
|
|
6
5
|
app?: string;
|
|
@@ -82,5 +81,4 @@ export interface TasksManifest {
|
|
|
82
81
|
timezone?: string;
|
|
83
82
|
}
|
|
84
83
|
declare const _default: import("nuxt/schema").NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
85
|
-
//#endregion
|
|
86
84
|
export { _default as default };
|
package/dist/module.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { SEED_TASK, unscheduleSeed } from "./seed.js";
|
|
2
2
|
import { resolveAppName, setupDev } from "./dev.js";
|
|
3
|
+
import { setupStudioPreview } from "./studio-preview.js";
|
|
4
|
+
import { PROCESS_ENV_TYPES } from "./env-types.js";
|
|
5
|
+
import { dependencyNames, ogImageDefaults, ogImageWarning } from "./og-image.js";
|
|
6
|
+
import { iconDefaults, iconSources, iconWarning } from "./icons.js";
|
|
3
7
|
import { findRouteTools } from "./route-tools.js";
|
|
4
8
|
import { localFiles, previewManifest } from "./preview.js";
|
|
5
9
|
import { findShapeRoutes, shapeRoutesTypes, shapesManifest } from "./shapes.js";
|
|
@@ -9,7 +13,7 @@ import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
|
|
|
9
13
|
import { builtinModules, createRequire } from "node:module";
|
|
10
14
|
import { dirname, extname, join, relative, resolve, sep } from "node:path";
|
|
11
15
|
import evlog from "evlog/nuxt";
|
|
12
|
-
|
|
16
|
+
// src/module.ts
|
|
13
17
|
const CONTENT_DATABASE = {
|
|
14
18
|
type: "postgres",
|
|
15
19
|
url: "{{DATABASE_URL}}"
|
|
@@ -19,6 +23,19 @@ var module_default = defineNuxtModule({
|
|
|
19
23
|
name: "@wervt/nuxt",
|
|
20
24
|
configKey: "wervt"
|
|
21
25
|
},
|
|
26
|
+
async moduleDependencies(nuxt) {
|
|
27
|
+
if (nuxt.options.dev) return {};
|
|
28
|
+
return {
|
|
29
|
+
"@nuxt/icon": {
|
|
30
|
+
optional: true,
|
|
31
|
+
defaults: iconDefaults()
|
|
32
|
+
},
|
|
33
|
+
"nuxt-og-image": {
|
|
34
|
+
optional: true,
|
|
35
|
+
defaults: ogImageDefaults()
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
},
|
|
22
39
|
async setup(options, nuxt) {
|
|
23
40
|
const resolver = createResolver(import.meta.url);
|
|
24
41
|
const nitro = nuxt.options.nitro;
|
|
@@ -51,6 +68,7 @@ var module_default = defineNuxtModule({
|
|
|
51
68
|
});
|
|
52
69
|
}
|
|
53
70
|
}
|
|
71
|
+
addServerPlugin(resolver.resolve("./runtime/server/agent-token-plugin"));
|
|
54
72
|
const useContentDatabase = !nuxt.options.dev && hasNuxtModule("@nuxt/content", nuxt);
|
|
55
73
|
if (useContentDatabase) {
|
|
56
74
|
const options = nuxt.options;
|
|
@@ -123,6 +141,16 @@ var module_default = defineNuxtModule({
|
|
|
123
141
|
};
|
|
124
142
|
});
|
|
125
143
|
}
|
|
144
|
+
const nuxtUi = hasNuxtModule("@nuxt/ui", nuxt);
|
|
145
|
+
if (!nuxt.options.dev && !nuxt.options._prepare && (nuxtUi || hasNuxtModule("@nuxt/icon", nuxt))) {
|
|
146
|
+
const warning = iconWarning(await iconSources(nuxt.options.rootDir), nuxtUi);
|
|
147
|
+
if (warning) logger.warn(warning);
|
|
148
|
+
}
|
|
149
|
+
nuxt.hook("modules:done", async () => {
|
|
150
|
+
if (nuxt.options.dev || nuxt.options._prepare || !hasNuxtModule("nuxt-og-image", nuxt)) return;
|
|
151
|
+
const warning = ogImageWarning(await dependencyNames(nuxt.options.rootDir));
|
|
152
|
+
if (warning) logger.warn(warning);
|
|
153
|
+
});
|
|
126
154
|
addServerHandler({
|
|
127
155
|
route: "/_wervt/boot",
|
|
128
156
|
method: "get",
|
|
@@ -248,6 +276,7 @@ var module_default = defineNuxtModule({
|
|
|
248
276
|
if (nuxt.options.dev && nitroMajor >= 3) {
|
|
249
277
|
if (!hasPackage(nuxt.options.rootDir, "vue")) logger.warn("`vue` is not a dependency of this app, so `nuxt dev` fails with \"module is not defined\". Run `pnpm add vue`.");
|
|
250
278
|
}
|
|
279
|
+
if (nuxt.options.dev && process.env.WERVT_PREVIEW) setupStudioPreview(nuxt);
|
|
251
280
|
if (nuxt.options.dev && !nuxt.options._prepare) {
|
|
252
281
|
const app = await resolveAppName(nuxt.options.rootDir, options.app);
|
|
253
282
|
await setupDev(nuxt, app, options.dev ?? {}, { storage: useAblage });
|
|
@@ -256,6 +285,18 @@ var module_default = defineNuxtModule({
|
|
|
256
285
|
filename: "types/wervt-email.d.ts",
|
|
257
286
|
getContents: () => "declare module '*.vue' {\n import type { DefineComponent } from 'vue'\n const component: DefineComponent<Record<string, unknown>>\n export default component\n}\n"
|
|
258
287
|
}, { nitro: true });
|
|
288
|
+
addTypeTemplate({
|
|
289
|
+
filename: "types/wervt-env.d.ts",
|
|
290
|
+
getContents: () => PROCESS_ENV_TYPES
|
|
291
|
+
}, { nitro: true });
|
|
292
|
+
const sourceEnv = resolver.resolve("./env.d.ts");
|
|
293
|
+
if (existsSync(sourceEnv)) addTypeTemplate({
|
|
294
|
+
filename: "types/wervt-source-env.d.ts",
|
|
295
|
+
getContents: () => `/// <reference path=${JSON.stringify(sourceEnv)} />\n`
|
|
296
|
+
}, {
|
|
297
|
+
nitro: true,
|
|
298
|
+
nuxt: true
|
|
299
|
+
});
|
|
259
300
|
if (nuxt.options.dev) {
|
|
260
301
|
const templates = await findEmailTemplates([join(nuxt.options.srcDir, "emails"), join(nuxt.options.rootDir, "emails")]);
|
|
261
302
|
addServerTemplate({
|
|
@@ -496,5 +537,4 @@ function exceptRuntime(pattern) {
|
|
|
496
537
|
if (pattern.source.startsWith("^")) return pattern;
|
|
497
538
|
return new RegExp(`^(?![\\s\\S]*[\\\\/]@wervt[\\\\/]nuxt[\\\\/]src[\\\\/]runtime[\\\\/])[\\s\\S]*?(?:${pattern.source})`, pattern.flags);
|
|
498
539
|
}
|
|
499
|
-
//#endregion
|
|
500
540
|
export { module_default as default };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { tasks } from "#nitro/virtual/tasks";
|
|
2
2
|
import { HTTPError } from "h3";
|
|
3
|
-
|
|
3
|
+
// ../../node_modules/.pnpm/nitro@3.0.260903-beta/node_modules/nitro/dist/runtime/internal/task.mjs
|
|
4
4
|
const __runningTasks__ = {};
|
|
5
5
|
async function runTask(name, { payload = {}, context = {} } = {}) {
|
|
6
6
|
if (__runningTasks__[name]) return __runningTasks__[name];
|
|
@@ -25,5 +25,4 @@ async function runTask(name, { payload = {}, context = {} } = {}) {
|
|
|
25
25
|
delete __runningTasks__[name];
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
//#endregion
|
|
29
28
|
export { runTask };
|
package/dist/node_modules/.pnpm/nitro@3.0.260903-beta/node_modules/nitro/dist/runtime/task.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { runTask };
|
|
1
|
+
export { runTask } from "./internal/task.js";
|
package/dist/og-image.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
// src/og-image.ts
|
|
4
|
+
/** The app's dependencies and devDependencies, by name. */
|
|
5
|
+
async function dependencyNames(rootDir) {
|
|
6
|
+
const pkg = JSON.parse(await readFile(join(rootDir, "package.json"), "utf8").catch(() => "{}"));
|
|
7
|
+
return Object.keys({
|
|
8
|
+
...pkg.dependencies,
|
|
9
|
+
...pkg.devDependencies
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* nuxt-og-image defaults for a wervt build. It treats the deno-server preset like Node and picks
|
|
14
|
+
* the native renderers (N-API bindings, sharp, a local Chrome), which an Edge Runtime isolate
|
|
15
|
+
* can't load, so OG image requests fail with a 500. The WebAssembly builds run there; without
|
|
16
|
+
* sharp, images are PNG only. An app's own `ogImage` config wins over these.
|
|
17
|
+
*/
|
|
18
|
+
function ogImageDefaults() {
|
|
19
|
+
return { compatibility: { runtime: {
|
|
20
|
+
takumi: "wasm",
|
|
21
|
+
satori: "wasm",
|
|
22
|
+
resvg: "wasm",
|
|
23
|
+
sharp: false,
|
|
24
|
+
browser: false
|
|
25
|
+
} } };
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Why OG images won't render on wervt, if they won't. The WebAssembly package renders; the native
|
|
29
|
+
* one is needed too because nuxt-og-image checks for the packages of the preset's own defaults
|
|
30
|
+
* (Node for deno-server) and fails the build without them, whatever `compatibility` says.
|
|
31
|
+
*/
|
|
32
|
+
function ogImageWarning(dependencies) {
|
|
33
|
+
const has = (name) => dependencies.includes(name);
|
|
34
|
+
const missing = [...has("@takumi-rs/core") || has("@takumi-rs/wasm") || !has("satori") ? ["@takumi-rs/core", "@takumi-rs/wasm"] : [], ...has("satori") ? ["@resvg/resvg-js", "@resvg/resvg-wasm"] : []].filter((name) => !has(name));
|
|
35
|
+
if (missing.length === 0) return void 0;
|
|
36
|
+
return `OG images render with WebAssembly on wervt (an isolate can't load native renderers), and nuxt-og-image's build also wants the native package, but ${missing.map((name) => `\`${name}\``).join(", ")} ${missing.length > 1 ? "are" : "is"} not installed. Run \`pnpm add ${missing.join(" ")}\`.`;
|
|
37
|
+
}
|
|
38
|
+
export { dependencyNames, ogImageDefaults, ogImageWarning };
|
package/dist/preview.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
//#region src/preview.d.ts
|
|
2
1
|
export interface PreviewOptions {
|
|
3
2
|
/** Defaults to the app's `app.head.title`. */
|
|
4
3
|
title?: string;
|
|
@@ -10,5 +9,4 @@ export interface PreviewOptions {
|
|
|
10
9
|
icon?: string;
|
|
11
10
|
/** Defaults to the app's `theme-color` meta tag. */
|
|
12
11
|
themeColor?: string;
|
|
13
|
-
}
|
|
14
|
-
//#endregion
|
|
12
|
+
}
|
package/dist/preview.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/preview.ts
|
|
2
2
|
/**
|
|
3
3
|
* What the runtime shows. Without `preview`, only the app's name and icon: for some private apps
|
|
4
4
|
* the title alone says too much, so the rest of the head is only used once the app opts in.
|
|
@@ -35,5 +35,4 @@ function localFiles(manifest) {
|
|
|
35
35
|
if (!manifest) return [];
|
|
36
36
|
return [manifest.image, manifest.icon].filter((path) => !!path && path.startsWith("/") && !path.startsWith("//"));
|
|
37
37
|
}
|
|
38
|
-
//#endregion
|
|
39
38
|
export { localFiles, previewManifest };
|
package/dist/provision.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { StorageError, StorageOptions, StorageUsage, createStorage } from "./storage.js";
|
|
2
|
-
//#region src/provision.d.ts
|
|
1
|
+
import { MAX_KEY_BYTES, ObjectDetails, ObjectListing, StorageError, StorageOptions, StorageQuota, StorageUsage, StoredObject, createStorage } from "./storage.js";
|
|
3
2
|
export interface ProvisionOptions {
|
|
4
3
|
/** App name, `[a-z0-9-]+`. */
|
|
5
4
|
app: string;
|
|
@@ -9,7 +8,24 @@ export interface ProvisionOptions {
|
|
|
9
8
|
secret: string;
|
|
10
9
|
/** Drizzle migrations folder. Skipped when undefined. */
|
|
11
10
|
migrationsFolder?: string;
|
|
11
|
+
/** Timeouts for the app's role; DEFAULT_ROLE_TIMEOUTS where not given. */
|
|
12
|
+
timeouts?: Partial<RoleTimeouts>;
|
|
12
13
|
}
|
|
14
|
+
/** Postgres durations (`30s`, `500ms`, `2min`) for the app's role; `0` turns one off. */
|
|
15
|
+
export interface RoleTimeouts {
|
|
16
|
+
/** Longest a single statement may run. */
|
|
17
|
+
statement: string;
|
|
18
|
+
/** Longest a transaction may sit idle, holding its locks and its pooled connection. */
|
|
19
|
+
idleInTransaction: string;
|
|
20
|
+
}
|
|
21
|
+
export declare const DEFAULT_ROLE_TIMEOUTS: RoleTimeouts;
|
|
22
|
+
/** A Postgres duration as the env gives it, e.g. `WERVT_STATEMENT_TIMEOUT`; the fallback when empty. */
|
|
23
|
+
export declare function parseDuration(value: string | undefined, fallback: string, name?: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Sets the timeouts on an existing app role, for apps that aren't redeployed. New sessions get
|
|
26
|
+
* them; open ones keep theirs. Returns false when the app has no role.
|
|
27
|
+
*/
|
|
28
|
+
export declare function setRoleTimeouts({ app, adminUrl, timeouts }: Pick<ProvisionOptions, 'app' | 'adminUrl' | 'timeouts'>): Promise<boolean>;
|
|
13
29
|
export declare function dbRole(app: string): string;
|
|
14
30
|
export declare function hmac(secret: string, message: string): Promise<string>;
|
|
15
31
|
/** The app's Garage bucket and S3 key, derived from WERVT_DB_SECRET like role passwords. */
|
|
@@ -32,6 +48,18 @@ export declare function appDatabaseUrl({ app, adminUrl, secret }: ProvisionOptio
|
|
|
32
48
|
export declare function provisionDatabase(options: ProvisionOptions): Promise<{
|
|
33
49
|
fresh: boolean;
|
|
34
50
|
}>;
|
|
51
|
+
/**
|
|
52
|
+
* Runs the Drizzle migrations as the app's own role, into its schema. The role needs CREATE on
|
|
53
|
+
* the database while this runs (see `provisionDatabase`). `fresh` is true when no migration had
|
|
54
|
+
* been applied before.
|
|
55
|
+
*/
|
|
56
|
+
export declare function migrateAs({ url, schema, migrationsFolder }: {
|
|
57
|
+
url: string;
|
|
58
|
+
schema: string;
|
|
59
|
+
migrationsFolder: string;
|
|
60
|
+
}): Promise<{
|
|
61
|
+
fresh: boolean;
|
|
62
|
+
}>;
|
|
35
63
|
/** The role PgBouncer signs in with to look up app roles' password hashes (`auth_query`). */
|
|
36
64
|
export declare const POOLER_ROLE = "pgbouncer";
|
|
37
65
|
/**
|
|
@@ -46,5 +74,4 @@ export declare function setupPooler({ adminUrl, password }: {
|
|
|
46
74
|
}): Promise<void>;
|
|
47
75
|
/** Drops the app's schema (all its data) and role. */
|
|
48
76
|
export declare function dropDatabase({ app, adminUrl }: Pick<ProvisionOptions, 'app' | 'adminUrl'>): Promise<void>;
|
|
49
|
-
|
|
50
|
-
export { StorageError, type StorageOptions, type StorageUsage, createStorage };
|
|
77
|
+
export { MAX_KEY_BYTES, type ObjectDetails, type ObjectListing, StorageError, type StorageOptions, type StorageQuota, type StorageUsage, type StoredObject, createStorage };
|
package/dist/provision.js
CHANGED
|
@@ -1,8 +1,53 @@
|
|
|
1
|
-
import { StorageError, createStorage } from "./storage.js";
|
|
1
|
+
import { MAX_KEY_BYTES, StorageError, createStorage } from "./storage.js";
|
|
2
2
|
import { drizzle } from "drizzle-orm/postgres-js";
|
|
3
3
|
import { migrate } from "drizzle-orm/postgres-js/migrator";
|
|
4
4
|
import postgres from "postgres";
|
|
5
|
-
|
|
5
|
+
// src/provision.ts
|
|
6
|
+
const DEFAULT_ROLE_TIMEOUTS = {
|
|
7
|
+
statement: "30s",
|
|
8
|
+
idleInTransaction: "60s"
|
|
9
|
+
};
|
|
10
|
+
const DURATION_RE = /^\d+(?:ms|s|min|h)?$/;
|
|
11
|
+
/** A Postgres duration as the env gives it, e.g. `WERVT_STATEMENT_TIMEOUT`; the fallback when empty. */
|
|
12
|
+
function parseDuration(value, fallback, name = "timeout") {
|
|
13
|
+
const trimmed = value?.trim();
|
|
14
|
+
if (!trimmed) return fallback;
|
|
15
|
+
if (!DURATION_RE.test(trimmed)) throw new Error(`${name} must be a duration like 30s, 500ms or 2min (0 for none)`);
|
|
16
|
+
return trimmed;
|
|
17
|
+
}
|
|
18
|
+
function roleTimeouts(timeouts) {
|
|
19
|
+
const merged = {
|
|
20
|
+
...DEFAULT_ROLE_TIMEOUTS,
|
|
21
|
+
...timeouts
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
statement: parseDuration(merged.statement, DEFAULT_ROLE_TIMEOUTS.statement),
|
|
25
|
+
idleInTransaction: parseDuration(merged.idleInTransaction, DEFAULT_ROLE_TIMEOUTS.idleInTransaction)
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
async function applyRoleTimeouts(admin, role, timeouts) {
|
|
29
|
+
await admin.unsafe(`alter role "${role}" set statement_timeout = '${timeouts.statement}'`);
|
|
30
|
+
await admin.unsafe(`alter role "${role}" set idle_in_transaction_session_timeout = '${timeouts.idleInTransaction}'`);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Sets the timeouts on an existing app role, for apps that aren't redeployed. New sessions get
|
|
34
|
+
* them; open ones keep theirs. Returns false when the app has no role.
|
|
35
|
+
*/
|
|
36
|
+
async function setRoleTimeouts({ app, adminUrl, timeouts }) {
|
|
37
|
+
const role = dbRole(app);
|
|
38
|
+
const admin = postgres(adminUrl, {
|
|
39
|
+
max: 1,
|
|
40
|
+
onnotice: () => {}
|
|
41
|
+
});
|
|
42
|
+
try {
|
|
43
|
+
const [row] = await admin`select exists(select 1 from pg_roles where rolname = ${role})`;
|
|
44
|
+
if (!row?.exists) return false;
|
|
45
|
+
await applyRoleTimeouts(admin, role, roleTimeouts(timeouts));
|
|
46
|
+
return true;
|
|
47
|
+
} finally {
|
|
48
|
+
await admin.end();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
6
51
|
function dbRole(app) {
|
|
7
52
|
return `app_${app.replaceAll("-", "_")}`;
|
|
8
53
|
}
|
|
@@ -56,6 +101,7 @@ async function provisionDatabase(options) {
|
|
|
56
101
|
await admin.unsafe(`create schema if not exists "${role}" authorization "${role}"`);
|
|
57
102
|
await claimSchema(admin, role);
|
|
58
103
|
await admin.unsafe(`alter role "${role}" set search_path = "${role}"`);
|
|
104
|
+
await applyRoleTimeouts(admin, role, roleTimeouts(options.timeouts));
|
|
59
105
|
for (const db of [
|
|
60
106
|
database,
|
|
61
107
|
"postgres",
|
|
@@ -64,34 +110,50 @@ async function provisionDatabase(options) {
|
|
|
64
110
|
await admin.unsafe(`grant connect on database "${database}" to "${role}"`);
|
|
65
111
|
await admin.unsafe(`revoke all on schema public from public`);
|
|
66
112
|
if (!migrationsFolder) return { fresh: false };
|
|
67
|
-
const table = `"${role}"."__drizzle_migrations"`;
|
|
68
|
-
const [state] = await admin`
|
|
69
|
-
select to_regclass(${table}) is not null as exists`;
|
|
70
|
-
let fresh = !state?.exists;
|
|
71
|
-
if (!fresh) {
|
|
72
|
-
const [row] = await admin.unsafe(`select exists(select 1 from ${table}) as applied`);
|
|
73
|
-
fresh = !row?.applied;
|
|
74
|
-
}
|
|
75
113
|
await admin.unsafe(`grant create on database "${database}" to "${role}"`);
|
|
76
|
-
const client = postgres(await appDatabaseUrl(options), {
|
|
77
|
-
max: 1,
|
|
78
|
-
onnotice: () => {}
|
|
79
|
-
});
|
|
80
114
|
try {
|
|
81
|
-
await
|
|
82
|
-
|
|
83
|
-
|
|
115
|
+
return await migrateAs({
|
|
116
|
+
url: await appDatabaseUrl(options),
|
|
117
|
+
schema: role,
|
|
118
|
+
migrationsFolder
|
|
84
119
|
});
|
|
85
120
|
} finally {
|
|
86
|
-
await client.end();
|
|
87
121
|
await admin.unsafe(`revoke create on database "${database}" from "${role}"`);
|
|
88
122
|
}
|
|
89
|
-
return { fresh };
|
|
90
123
|
} finally {
|
|
91
124
|
await admin.end();
|
|
92
125
|
}
|
|
93
126
|
}
|
|
94
127
|
/**
|
|
128
|
+
* Runs the Drizzle migrations as the app's own role, into its schema. The role needs CREATE on
|
|
129
|
+
* the database while this runs (see `provisionDatabase`). `fresh` is true when no migration had
|
|
130
|
+
* been applied before.
|
|
131
|
+
*/
|
|
132
|
+
async function migrateAs({ url, schema, migrationsFolder }) {
|
|
133
|
+
const client = postgres(url, {
|
|
134
|
+
max: 1,
|
|
135
|
+
onnotice: () => {}
|
|
136
|
+
});
|
|
137
|
+
try {
|
|
138
|
+
const table = `"${schema}"."__drizzle_migrations"`;
|
|
139
|
+
const [state] = await client`
|
|
140
|
+
select to_regclass(${table}) is not null as exists`;
|
|
141
|
+
let fresh = !state?.exists;
|
|
142
|
+
if (!fresh) {
|
|
143
|
+
const [row] = await client.unsafe(`select exists(select 1 from ${table}) as applied`);
|
|
144
|
+
fresh = !row?.applied;
|
|
145
|
+
}
|
|
146
|
+
await client.unsafe("set statement_timeout = 0; set idle_in_transaction_session_timeout = 0");
|
|
147
|
+
await migrate(drizzle({ client }), {
|
|
148
|
+
migrationsFolder,
|
|
149
|
+
migrationsSchema: schema
|
|
150
|
+
});
|
|
151
|
+
return { fresh };
|
|
152
|
+
} finally {
|
|
153
|
+
await client.end();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
95
157
|
* Gives the role its schema and everything in it back. A dump restored with `--no-owner`
|
|
96
158
|
* (Coolify's backups) leaves all of it owned by the restoring superuser.
|
|
97
159
|
*/
|
|
@@ -173,5 +235,4 @@ async function dropDatabase({ app, adminUrl }) {
|
|
|
173
235
|
await admin.end();
|
|
174
236
|
}
|
|
175
237
|
}
|
|
176
|
-
|
|
177
|
-
export { POOLER_ROLE, StorageError, appDatabaseUrl, createStorage, dbPassword, dbRole, dropDatabase, hmac, provisionDatabase, setupPooler, storageCredentials };
|
|
238
|
+
export { DEFAULT_ROLE_TIMEOUTS, MAX_KEY_BYTES, POOLER_ROLE, StorageError, appDatabaseUrl, createStorage, dbPassword, dbRole, dropDatabase, hmac, migrateAs, parseDuration, provisionDatabase, setRoleTimeouts, setupPooler, storageCredentials };
|
package/dist/route-tools.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFile, readdir } from "node:fs/promises";
|
|
2
2
|
import { extname, join, sep } from "node:path";
|
|
3
|
-
|
|
3
|
+
// src/route-tools.ts
|
|
4
4
|
const EXTENSIONS = /* @__PURE__ */ new Set([
|
|
5
5
|
".ts",
|
|
6
6
|
".js",
|
|
@@ -40,5 +40,4 @@ async function findRouteTools(dir, prefix = []) {
|
|
|
40
40
|
}
|
|
41
41
|
return found;
|
|
42
42
|
}
|
|
43
|
-
//#endregion
|
|
44
43
|
export { findRouteTools, routeToolName };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineNuxtPlugin, useRouter, useRuntimeConfig } from "#app";
|
|
2
|
-
|
|
2
|
+
// src/runtime/app/plugins/analytics.client.ts
|
|
3
3
|
var analytics_client_default = defineNuxtPlugin({
|
|
4
4
|
name: "wervt:analytics",
|
|
5
5
|
setup() {
|
|
@@ -12,5 +12,4 @@ var analytics_client_default = defineNuxtPlugin({
|
|
|
12
12
|
});
|
|
13
13
|
}
|
|
14
14
|
});
|
|
15
|
-
//#endregion
|
|
16
15
|
export { analytics_client_default as default };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { pendingFeedbackContext } from "../useWervtFeedback.js";
|
|
2
2
|
import { defineNuxtPlugin, onNuxtReady, useRuntimeConfig } from "#app";
|
|
3
|
-
|
|
3
|
+
// src/runtime/app/plugins/feedback.client.ts
|
|
4
4
|
var feedback_client_default = defineNuxtPlugin({
|
|
5
5
|
name: "wervt:feedback",
|
|
6
6
|
setup() {
|
|
@@ -28,5 +28,4 @@ var feedback_client_default = defineNuxtPlugin({
|
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
});
|
|
31
|
-
//#endregion
|
|
32
31
|
export { feedback_client_default as default };
|