nuxt-feathers-zod 0.1.0
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 +283 -0
- package/dist/module.d.mts +17 -0
- package/dist/module.json +12 -0
- package/dist/module.mjs +124 -0
- package/dist/runtime/adapters/ofetch.d.ts +5 -0
- package/dist/runtime/adapters/ofetch.js +18 -0
- package/dist/runtime/composables/feathers.d.ts +5 -0
- package/dist/runtime/composables/feathers.js +9 -0
- package/dist/runtime/composables/pinia.d.ts +1 -0
- package/dist/runtime/composables/pinia.js +11 -0
- package/dist/runtime/errors.d.ts +3 -0
- package/dist/runtime/errors.js +5 -0
- package/dist/runtime/options/authentication/client.d.ts +13 -0
- package/dist/runtime/options/authentication/client.js +12 -0
- package/dist/runtime/options/authentication/index.d.ts +42 -0
- package/dist/runtime/options/authentication/index.js +71 -0
- package/dist/runtime/options/authentication/jwt-types.d.ts +29 -0
- package/dist/runtime/options/authentication/jwt-types.js +0 -0
- package/dist/runtime/options/authentication/jwt.d.ts +7 -0
- package/dist/runtime/options/authentication/jwt.js +19 -0
- package/dist/runtime/options/authentication/local.d.ts +8 -0
- package/dist/runtime/options/authentication/local.js +8 -0
- package/dist/runtime/options/client/index.d.ts +14 -0
- package/dist/runtime/options/client/index.js +33 -0
- package/dist/runtime/options/client/pinia.d.ts +14 -0
- package/dist/runtime/options/client/pinia.js +22 -0
- package/dist/runtime/options/database/index.d.ts +6 -0
- package/dist/runtime/options/database/index.js +8 -0
- package/dist/runtime/options/database/mongodb.d.ts +12 -0
- package/dist/runtime/options/database/mongodb.js +3 -0
- package/dist/runtime/options/index.d.ts +44 -0
- package/dist/runtime/options/index.js +63 -0
- package/dist/runtime/options/plugins.d.ts +20 -0
- package/dist/runtime/options/plugins.js +69 -0
- package/dist/runtime/options/server.d.ts +7 -0
- package/dist/runtime/options/server.js +11 -0
- package/dist/runtime/options/services.d.ts +6 -0
- package/dist/runtime/options/services.js +13 -0
- package/dist/runtime/options/transports/index.d.ts +23 -0
- package/dist/runtime/options/transports/index.js +14 -0
- package/dist/runtime/options/transports/rest.d.ts +9 -0
- package/dist/runtime/options/transports/rest.js +22 -0
- package/dist/runtime/options/transports/utils.d.ts +1 -0
- package/dist/runtime/options/transports/utils.js +7 -0
- package/dist/runtime/options/transports/websocket.d.ts +8 -0
- package/dist/runtime/options/transports/websocket.js +17 -0
- package/dist/runtime/options/utils.d.ts +11 -0
- package/dist/runtime/options/utils.js +22 -0
- package/dist/runtime/options/validator.d.ts +13 -0
- package/dist/runtime/options/validator.js +29 -0
- package/dist/runtime/plugins/feathers-auth.d.ts +11 -0
- package/dist/runtime/plugins/feathers-auth.js +13 -0
- package/dist/runtime/server/tsconfig.json +3 -0
- package/dist/runtime/services.d.ts +4 -0
- package/dist/runtime/services.js +14 -0
- package/dist/runtime/stores/auth.d.ts +28 -0
- package/dist/runtime/stores/auth.js +47 -0
- package/dist/runtime/templates/client/authentication.d.ts +2 -0
- package/dist/runtime/templates/client/authentication.js +28 -0
- package/dist/runtime/templates/client/client.d.ts +2 -0
- package/dist/runtime/templates/client/client.js +50 -0
- package/dist/runtime/templates/client/connection.d.ts +3 -0
- package/dist/runtime/templates/client/connection.js +39 -0
- package/dist/runtime/templates/client/index.d.ts +4 -0
- package/dist/runtime/templates/client/index.js +33 -0
- package/dist/runtime/templates/client/plugin.d.ts +2 -0
- package/dist/runtime/templates/client/plugin.js +81 -0
- package/dist/runtime/templates/server/authentication.d.ts +2 -0
- package/dist/runtime/templates/server/authentication.js +32 -0
- package/dist/runtime/templates/server/index.d.ts +3 -0
- package/dist/runtime/templates/server/index.js +33 -0
- package/dist/runtime/templates/server/mongodb.d.ts +2 -0
- package/dist/runtime/templates/server/mongodb.js +26 -0
- package/dist/runtime/templates/server/plugin.d.ts +2 -0
- package/dist/runtime/templates/server/plugin.js +110 -0
- package/dist/runtime/templates/server/server.d.ts +2 -0
- package/dist/runtime/templates/server/server.js +61 -0
- package/dist/runtime/templates/server/validators.d.ts +2 -0
- package/dist/runtime/templates/server/validators.js +30 -0
- package/dist/runtime/templates/types.d.ts +6 -0
- package/dist/runtime/templates/types.js +0 -0
- package/dist/runtime/templates/utils.d.ts +4 -0
- package/dist/runtime/templates/utils.js +6 -0
- package/dist/runtime/zod/format.d.ts +10 -0
- package/dist/runtime/zod/format.js +7 -0
- package/dist/runtime/zod/index.d.ts +4 -0
- package/dist/runtime/zod/index.js +4 -0
- package/dist/runtime/zod/objectId.d.ts +9 -0
- package/dist/runtime/zod/objectId.js +17 -0
- package/dist/runtime/zod/query.d.ts +43 -0
- package/dist/runtime/zod/query.js +75 -0
- package/dist/runtime/zod/validators.d.ts +17 -0
- package/dist/runtime/zod/validators.js +46 -0
- package/dist/types.d.mts +7 -0
- package/package.json +111 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { addImports, addServerImports } from "@nuxt/kit";
|
|
2
|
+
import { scanDirExports } from "unimport";
|
|
3
|
+
export async function getServicesImports(servicesDirs) {
|
|
4
|
+
const exports = await scanDirExports(servicesDirs, {
|
|
5
|
+
filePatterns: ["**/*.schema.ts"]
|
|
6
|
+
});
|
|
7
|
+
const typeExports = exports.filter(({ type }) => type);
|
|
8
|
+
console.log("Services typeExports", typeExports.map(({ as }) => as));
|
|
9
|
+
return typeExports;
|
|
10
|
+
}
|
|
11
|
+
export async function addServicesImports(imports) {
|
|
12
|
+
addImports(imports);
|
|
13
|
+
addServerImports(imports);
|
|
14
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const useAuthStore: import("pinia").StoreDefinition<"auth", Pick<{
|
|
2
|
+
userId: import("vue").ComputedRef<any>;
|
|
3
|
+
authenticate: (payload: any) => Promise<void>;
|
|
4
|
+
reAuthenticate: () => Promise<void>;
|
|
5
|
+
logout: () => void;
|
|
6
|
+
user: import("vue").Ref<any, any>;
|
|
7
|
+
authenticated: import("vue").Ref<boolean, boolean>;
|
|
8
|
+
accessToken: import("vue").Ref<string | null, string | null>;
|
|
9
|
+
error: import("vue").Ref<any, any>;
|
|
10
|
+
}, "user" | "error" | "authenticated" | "accessToken">, Pick<{
|
|
11
|
+
userId: import("vue").ComputedRef<any>;
|
|
12
|
+
authenticate: (payload: any) => Promise<void>;
|
|
13
|
+
reAuthenticate: () => Promise<void>;
|
|
14
|
+
logout: () => void;
|
|
15
|
+
user: import("vue").Ref<any, any>;
|
|
16
|
+
authenticated: import("vue").Ref<boolean, boolean>;
|
|
17
|
+
accessToken: import("vue").Ref<string | null, string | null>;
|
|
18
|
+
error: import("vue").Ref<any, any>;
|
|
19
|
+
}, "userId">, Pick<{
|
|
20
|
+
userId: import("vue").ComputedRef<any>;
|
|
21
|
+
authenticate: (payload: any) => Promise<void>;
|
|
22
|
+
reAuthenticate: () => Promise<void>;
|
|
23
|
+
logout: () => void;
|
|
24
|
+
user: import("vue").Ref<any, any>;
|
|
25
|
+
authenticated: import("vue").Ref<boolean, boolean>;
|
|
26
|
+
accessToken: import("vue").Ref<string | null, string | null>;
|
|
27
|
+
error: import("vue").Ref<any, any>;
|
|
28
|
+
}, "authenticate" | "reAuthenticate" | "logout">>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { acceptHMRUpdate, defineStore } from "pinia";
|
|
2
|
+
import { computed, reactive, toRefs } from "vue";
|
|
3
|
+
export const useAuthStore = defineStore("auth", () => {
|
|
4
|
+
const state = reactive({
|
|
5
|
+
user: null,
|
|
6
|
+
authenticated: false,
|
|
7
|
+
accessToken: null,
|
|
8
|
+
error: null
|
|
9
|
+
});
|
|
10
|
+
const userId = computed(
|
|
11
|
+
() => state.user?.id ?? state.user?._id ?? null
|
|
12
|
+
);
|
|
13
|
+
async function authenticate(payload) {
|
|
14
|
+
const api = useNuxtApp().$api;
|
|
15
|
+
const result = await api.authenticate(payload);
|
|
16
|
+
state.accessToken = result.accessToken;
|
|
17
|
+
state.user = result.user;
|
|
18
|
+
state.authenticated = true;
|
|
19
|
+
}
|
|
20
|
+
async function reAuthenticate() {
|
|
21
|
+
try {
|
|
22
|
+
const api = useNuxtApp().$api;
|
|
23
|
+
const result = await api.reAuthenticate();
|
|
24
|
+
state.accessToken = result.accessToken;
|
|
25
|
+
state.user = result.user;
|
|
26
|
+
state.authenticated = true;
|
|
27
|
+
} catch {
|
|
28
|
+
logout();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function logout() {
|
|
32
|
+
const api = useNuxtApp().$api;
|
|
33
|
+
api.logout?.();
|
|
34
|
+
state.user = null;
|
|
35
|
+
state.accessToken = null;
|
|
36
|
+
state.authenticated = false;
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
...toRefs(state),
|
|
40
|
+
userId,
|
|
41
|
+
authenticate,
|
|
42
|
+
reAuthenticate,
|
|
43
|
+
logout
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
if (import.meta.hot)
|
|
47
|
+
import.meta.hot.accept(acceptHMRUpdate(useAuthStore, import.meta.hot));
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { put } from "../utils.js";
|
|
2
|
+
export function getClientAuthContents(options) {
|
|
3
|
+
return () => {
|
|
4
|
+
const jwt = options.auth?.authStrategies?.includes("jwt");
|
|
5
|
+
return `// ! Generated by nuxt-feathers-zod - do not change manually
|
|
6
|
+
import type { ClientApplication } from './client.js'
|
|
7
|
+
import {${put(jwt, `useCookie,`)} useRuntimeConfig } from '#app'
|
|
8
|
+
import authenticationClient, { type AuthenticationClientOptions } from '@feathersjs/authentication-client'
|
|
9
|
+
import { klona } from 'klona'
|
|
10
|
+
|
|
11
|
+
export function authentication(client: ClientApplication) {
|
|
12
|
+
const clientOptions = useRuntimeConfig().public._feathers.auth?.client
|
|
13
|
+
const authClientOptions = klona(clientOptions) as AuthenticationClientOptions
|
|
14
|
+
|
|
15
|
+
${put(jwt, ` // Store JWT in a cookie for SSR.
|
|
16
|
+
const jwt = useCookie<string | null>(authClientOptions.storageKey)
|
|
17
|
+
const storage = {
|
|
18
|
+
getItem: () => jwt.value,
|
|
19
|
+
setItem: (key: string, val: string) => (jwt.value = val),
|
|
20
|
+
removeItem: () => (jwt.value = null),
|
|
21
|
+
}
|
|
22
|
+
authClientOptions.storage = storage
|
|
23
|
+
`)}
|
|
24
|
+
client.configure(authenticationClient(authClientOptions))
|
|
25
|
+
}
|
|
26
|
+
`;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { put } from "../utils.js";
|
|
2
|
+
export function getClientContents(options) {
|
|
3
|
+
return () => {
|
|
4
|
+
const pinia = !!options?.client?.pinia;
|
|
5
|
+
const apiType = pinia ? "FeathersPiniaClient<ClientApplication>" : "ClientApplication";
|
|
6
|
+
let entity, entityImport;
|
|
7
|
+
const auth = options?.auth;
|
|
8
|
+
if (auth) {
|
|
9
|
+
entity = auth.entity;
|
|
10
|
+
entityImport = auth.entityImport;
|
|
11
|
+
}
|
|
12
|
+
return `// ! Generated by nuxt-feathers-zod - do not change manually
|
|
13
|
+
${put(auth, `import type { User } from '${entityImport?.from}'`)}
|
|
14
|
+
import type { Application, TransportConnection } from '@feathersjs/feathers'
|
|
15
|
+
${put(pinia, `import type { FeathersPiniaClient } from 'feathers-pinia'`)}
|
|
16
|
+
|
|
17
|
+
export interface Configuration {
|
|
18
|
+
connection: TransportConnection<ServiceTypes>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ServiceTypes {}
|
|
22
|
+
|
|
23
|
+
export type ClientApplication = Application<ServiceTypes, Configuration>
|
|
24
|
+
|
|
25
|
+
export type FeathersClientPlugin = Parameters<ClientApplication['configure']>['0']
|
|
26
|
+
|
|
27
|
+
export function defineFeathersClientPlugin(def: FeathersClientPlugin): FeathersClientPlugin {
|
|
28
|
+
return def;
|
|
29
|
+
}
|
|
30
|
+
${put(auth, `
|
|
31
|
+
declare module '@feathersjs/feathers' {
|
|
32
|
+
interface Params {
|
|
33
|
+
${entity}?: ${entityImport?.as}
|
|
34
|
+
}
|
|
35
|
+
}`)}
|
|
36
|
+
|
|
37
|
+
declare module '#app' {
|
|
38
|
+
interface NuxtApp {
|
|
39
|
+
$api: ${apiType}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
declare module 'vue' {
|
|
44
|
+
interface ComponentCustomProperties {
|
|
45
|
+
$api: ${apiType}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
`;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { put, puts } from "../utils.js";
|
|
2
|
+
export function getClientConnectionContents(options, resolver) {
|
|
3
|
+
return () => {
|
|
4
|
+
const pinia = !!options.client?.pinia;
|
|
5
|
+
const transports = options?.transports;
|
|
6
|
+
const rest = !!transports?.rest;
|
|
7
|
+
const sio = !!transports?.websocket;
|
|
8
|
+
const restPath = transports?.rest?.path;
|
|
9
|
+
const sioPath = transports?.websocket?.path;
|
|
10
|
+
const restConnection = `rest(new URL('${restPath}', origin).href).fetch($fetch, OFetch)`;
|
|
11
|
+
const sioConnection = `socketioClient(io(origin, { path: '${sioPath}', transports: ['websocket'] }))`;
|
|
12
|
+
return `// ! Generated by nuxt-feathers-zod - do not change manually
|
|
13
|
+
// You can set it in nuxt.config.js with the feathers.transports option
|
|
14
|
+
import type { ClientApplication } from './client.js'
|
|
15
|
+
${puts([
|
|
16
|
+
[rest, `import rest from '@feathersjs/rest-client'
|
|
17
|
+
import { $fetch } from 'ofetch'`],
|
|
18
|
+
[sio, `import socketioClient from '@feathersjs/socketio-client'
|
|
19
|
+
import { io } from 'socket.io-client'`],
|
|
20
|
+
[rest, `import { OFetch } from '${put(pinia, "feathers-pinia", resolver.resolve("./runtime/adapters/ofetch"))}'`]
|
|
21
|
+
])}
|
|
22
|
+
|
|
23
|
+
export function connection(origin?: string) {
|
|
24
|
+
return function (client: ClientApplication) {
|
|
25
|
+
const connection = ${put(rest && sio, `import.meta.server
|
|
26
|
+
? ${restConnection}
|
|
27
|
+
: ${sioConnection}`, puts([
|
|
28
|
+
[rest || !sio, restConnection],
|
|
29
|
+
[sio, sioConnection]
|
|
30
|
+
]))}
|
|
31
|
+
|
|
32
|
+
client.configure(connection)
|
|
33
|
+
|
|
34
|
+
client.set('connection', connection)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { getClientAuthContents } from "./authentication.js";
|
|
2
|
+
import { getClientContents } from "./client.js";
|
|
3
|
+
import { getClientConnectionContents } from "./connection.js";
|
|
4
|
+
import { getClientPluginContents } from "./plugin.js";
|
|
5
|
+
export function getClientTemplates(options, resolver) {
|
|
6
|
+
const clientTemplates = [
|
|
7
|
+
{
|
|
8
|
+
filename: "feathers/client/client.ts",
|
|
9
|
+
getContents: getClientContents(options),
|
|
10
|
+
write: true
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
filename: "feathers/client/connection.ts",
|
|
14
|
+
getContents: getClientConnectionContents(options, resolver),
|
|
15
|
+
write: true
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
filename: "feathers/client/plugin.ts",
|
|
19
|
+
getContents: getClientPluginContents(options),
|
|
20
|
+
write: true
|
|
21
|
+
}
|
|
22
|
+
];
|
|
23
|
+
if (options.auth) {
|
|
24
|
+
clientTemplates.push(
|
|
25
|
+
{
|
|
26
|
+
filename: "feathers/client/authentication.ts",
|
|
27
|
+
getContents: getClientAuthContents(options),
|
|
28
|
+
write: true
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
return clientTemplates;
|
|
33
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { scanDirExports } from "unimport";
|
|
2
|
+
import { setImportsMeta } from "../../options/utils.js";
|
|
3
|
+
import { put } from "../utils.js";
|
|
4
|
+
async function getServices(servicesDirs) {
|
|
5
|
+
const services = await scanDirExports(servicesDirs, {
|
|
6
|
+
filePatterns: ["**/*.shared.ts"],
|
|
7
|
+
fileFilter: (file) => /\.shared\.ts$/.test(file),
|
|
8
|
+
types: false
|
|
9
|
+
});
|
|
10
|
+
return services.filter(({ name }) => /Client|default$/.test(name));
|
|
11
|
+
}
|
|
12
|
+
export function getClientPluginContents(options) {
|
|
13
|
+
return async () => {
|
|
14
|
+
const services = setImportsMeta(await getServices(options.servicesDirs));
|
|
15
|
+
const plugins = options.client.plugins;
|
|
16
|
+
const modules = [...services, ...plugins];
|
|
17
|
+
const auth = (options?.auth?.authStrategies || []).length > 0;
|
|
18
|
+
const pinia = !!options?.client?.pinia;
|
|
19
|
+
return `// ! Generated by nuxt-feathers-zod - do not change manually
|
|
20
|
+
// For more information about this file see https://dove.feathersjs.com/guides/cli/client.html
|
|
21
|
+
|
|
22
|
+
import { useRequestURL } from "#imports"
|
|
23
|
+
import type { ClientApplication } from './client.js'
|
|
24
|
+
import { feathers } from '@feathersjs/feathers'
|
|
25
|
+
import { defineNuxtPlugin${put(pinia, `, useRuntimeConfig`)} } from '#app'
|
|
26
|
+
${put(pinia, `import { createPiniaClient, type CreatePiniaClientConfig } from 'feathers-pinia'`)}
|
|
27
|
+
|
|
28
|
+
import { connection } from './connection.js'
|
|
29
|
+
${put(auth, `import { authentication } from './authentication.js'`)}
|
|
30
|
+
|
|
31
|
+
${modules.map((module) => module.meta.import).join("\n")}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Returns a typed client for the feathers-api app.
|
|
35
|
+
*
|
|
36
|
+
* @param connection The REST or Socket.io Feathers client connection
|
|
37
|
+
* @param authenticationOptions Additional settings for the authentication client
|
|
38
|
+
* @see https://dove.feathersjs.com/api/client.html
|
|
39
|
+
* @returns The Feathers client application
|
|
40
|
+
*/
|
|
41
|
+
function createFeathersClient(): ClientApplication {
|
|
42
|
+
const feathersClient: ClientApplication = feathers()
|
|
43
|
+
|
|
44
|
+
// Init connection
|
|
45
|
+
const { origin } = useRequestURL()
|
|
46
|
+
feathersClient.configure(connection(origin))
|
|
47
|
+
|
|
48
|
+
// Init authentication
|
|
49
|
+
${put(auth, `feathersClient.configure(authentication)`)}
|
|
50
|
+
|
|
51
|
+
// Init services
|
|
52
|
+
${services.map((service) => `feathersClient.configure(${service.meta.importId})`).join("\n ")}
|
|
53
|
+
|
|
54
|
+
// Init plugins
|
|
55
|
+
${plugins.map((plugin) => `feathersClient.configure(${plugin.meta.importId})`).join("\n ")}
|
|
56
|
+
|
|
57
|
+
return feathersClient
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Creates a Feathers Rest client for the SSR server and a Socket.io client for the browser.
|
|
62
|
+
* Also provides a cookie-storage adapter for JWT SSR using Nuxt APIs.
|
|
63
|
+
*/
|
|
64
|
+
export default defineNuxtPlugin(async (nuxt) => {
|
|
65
|
+
// create the feathers client
|
|
66
|
+
const feathersClient: ClientApplication = createFeathersClient()
|
|
67
|
+
${put(pinia, `
|
|
68
|
+
const piniaOptions = useRuntimeConfig().public._feathers.pinia
|
|
69
|
+
`)}
|
|
70
|
+
// wrap the feathers client
|
|
71
|
+
const api = ${put(pinia, `createPiniaClient(feathersClient, {
|
|
72
|
+
ssr: !!import.meta.server,
|
|
73
|
+
...piniaOptions as CreatePiniaClientConfig,
|
|
74
|
+
pinia: nuxt.$pinia,
|
|
75
|
+
})`, `feathersClient`)}
|
|
76
|
+
|
|
77
|
+
return { provide: { api } }
|
|
78
|
+
})
|
|
79
|
+
`;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { put, puts } from "../utils.js";
|
|
2
|
+
export function getServerAuthContents(options) {
|
|
3
|
+
return () => {
|
|
4
|
+
const authStrategies = options.auth.authStrategies;
|
|
5
|
+
const jwt = authStrategies.includes("jwt");
|
|
6
|
+
const local = authStrategies.includes("local");
|
|
7
|
+
return `// ! Generated by nuxt-feathers-zod - do not change manually
|
|
8
|
+
import { useRuntimeConfig } from '#imports'
|
|
9
|
+
import { defineFeathersServerPlugin } from './server.js'
|
|
10
|
+
import { AuthenticationService ${put(jwt, `, JWTStrategy `)}} from '@feathersjs/authentication'
|
|
11
|
+
${put(local, `import { LocalStrategy } from '@feathersjs/authentication-local'`)}
|
|
12
|
+
|
|
13
|
+
export default defineFeathersServerPlugin((app) => {
|
|
14
|
+
const authOptions = useRuntimeConfig()._feathers.auth
|
|
15
|
+
const authentication = new AuthenticationService(app, 'authentication', authOptions)
|
|
16
|
+
|
|
17
|
+
${puts([
|
|
18
|
+
[jwt, ` authentication.register('jwt', new JWTStrategy())`],
|
|
19
|
+
[local, ` authentication.register('local', new LocalStrategy())`]
|
|
20
|
+
])}
|
|
21
|
+
|
|
22
|
+
app.use('authentication', authentication)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
declare module './server' {
|
|
26
|
+
interface ServiceTypes {
|
|
27
|
+
authentication: AuthenticationService
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
`;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { getServerAuthContents } from "./authentication.js";
|
|
2
|
+
import { getServerMongodbContents } from "./mongodb.js";
|
|
3
|
+
import { getServerPluginContents } from "./plugin.js";
|
|
4
|
+
import { getServerContents } from "./server.js";
|
|
5
|
+
export function getServerTemplates(options) {
|
|
6
|
+
const serverTemplates = [
|
|
7
|
+
{
|
|
8
|
+
filename: "feathers/server/server.ts",
|
|
9
|
+
getContents: getServerContents(options),
|
|
10
|
+
write: true
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
filename: "feathers/server/plugin.ts",
|
|
14
|
+
getContents: getServerPluginContents(options),
|
|
15
|
+
write: true
|
|
16
|
+
}
|
|
17
|
+
];
|
|
18
|
+
if (options.database.mongo) {
|
|
19
|
+
serverTemplates.push({
|
|
20
|
+
filename: "feathers/server/mongodb.ts",
|
|
21
|
+
getContents: getServerMongodbContents(options),
|
|
22
|
+
write: true
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
if (options.auth) {
|
|
26
|
+
serverTemplates.push({
|
|
27
|
+
filename: "feathers/server/authentication.ts",
|
|
28
|
+
getContents: getServerAuthContents(options),
|
|
29
|
+
write: true
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return serverTemplates;
|
|
33
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { klona } from "klona/json";
|
|
2
|
+
export function getServerMongodbContents(options) {
|
|
3
|
+
return () => {
|
|
4
|
+
const mongoUrl = options?.database?.mongo?.url;
|
|
5
|
+
const mongoOptions = klona(options?.database?.mongo);
|
|
6
|
+
delete mongoOptions.url;
|
|
7
|
+
const mongoClientOptions = mongoOptions;
|
|
8
|
+
return `// ! Generated by nuxt-feathers-zod - do not change manually
|
|
9
|
+
// For more information about this file see https://dove.feathersjs.com/guides/cli/databases.html
|
|
10
|
+
|
|
11
|
+
import { MongoClient } from 'mongodb'
|
|
12
|
+
import { defineFeathersServerPlugin } from './server.js'
|
|
13
|
+
|
|
14
|
+
const url = '${mongoUrl}'
|
|
15
|
+
const options = ${JSON.stringify(mongoClientOptions, null, 2)}
|
|
16
|
+
|
|
17
|
+
export default defineFeathersServerPlugin((app) => {
|
|
18
|
+
const database = new URL(url).pathname.substring(1)
|
|
19
|
+
|
|
20
|
+
const mongoClient = MongoClient.connect(url, options).then(client => client.db(database))
|
|
21
|
+
|
|
22
|
+
app.set('mongodbClient', mongoClient)
|
|
23
|
+
})
|
|
24
|
+
`;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { scanDirExports } from "unimport";
|
|
2
|
+
import { filterExports, setImportsMeta } from "../../options/utils.js";
|
|
3
|
+
import { put, puts } from "../utils.js";
|
|
4
|
+
async function getServices(servicesDirs) {
|
|
5
|
+
const services = await scanDirExports(servicesDirs, {
|
|
6
|
+
filePatterns: ["**/*.ts"],
|
|
7
|
+
types: false
|
|
8
|
+
});
|
|
9
|
+
return services.filter(({ from }) => !/\w+\.\w+\.ts$/.test(from)).filter(filterExports);
|
|
10
|
+
}
|
|
11
|
+
export function getServerPluginContents(options) {
|
|
12
|
+
return async () => {
|
|
13
|
+
const services = setImportsMeta(await getServices(options.servicesDirs));
|
|
14
|
+
const plugins = options.server.plugins;
|
|
15
|
+
const modules = [...services, ...plugins];
|
|
16
|
+
const transports = options?.transports;
|
|
17
|
+
const rest = !!transports?.rest;
|
|
18
|
+
const framework = transports?.rest?.framework;
|
|
19
|
+
const exp = framework === "express";
|
|
20
|
+
const koa = framework === "koa";
|
|
21
|
+
const sio = !!transports?.websocket;
|
|
22
|
+
const routers = [exp && "createExpressRouter", koa && "createKoaRouter", sio && "createSocketIoRouter"].filter(Boolean);
|
|
23
|
+
const mongo = !!options.database?.mongo;
|
|
24
|
+
const authStrategies = options?.auth?.authStrategies;
|
|
25
|
+
const auth = (authStrategies || []).length > 0;
|
|
26
|
+
const authService = options?.auth?.service;
|
|
27
|
+
const restPath = transports?.rest?.path;
|
|
28
|
+
const websocketPath = transports?.websocket?.path;
|
|
29
|
+
return `// ! Generated by nuxt-feathers-zod - do not change manually
|
|
30
|
+
import type { NitroApp } from 'nitropack'
|
|
31
|
+
import type { Application } from './server.js'
|
|
32
|
+
${put(options.loadFeathersConfig, `import configuration from '@feathersjs/configuration'`)}
|
|
33
|
+
import { feathers } from '@feathersjs/feathers'
|
|
34
|
+
${puts([
|
|
35
|
+
[koa, `import { bodyParser, koa as feathersKoa, rest } from '@feathersjs/koa'`],
|
|
36
|
+
[exp, `import feathersExpress, { json, rest, urlencoded } from '@feathersjs/express'`],
|
|
37
|
+
[sio, `import socketio from '@feathersjs/socketio'`]
|
|
38
|
+
])}
|
|
39
|
+
${put(rest, `import { ${framework}ErrorHandler } from '@gabortorma/feathers-nitro-adapter/handlers'`)}
|
|
40
|
+
${put(auth, `import authentication from './authentication.js'`)}
|
|
41
|
+
import { ${routers.join(", ")} } from '@gabortorma/feathers-nitro-adapter/routers'
|
|
42
|
+
import { defineNitroPlugin } from 'nitropack/dist/runtime/plugin'
|
|
43
|
+
${put(mongo, `import mongodb from './mongodb.js'`)}
|
|
44
|
+
${modules.map((module) => module.meta.import).join("\n")}
|
|
45
|
+
|
|
46
|
+
export default defineNitroPlugin((nitroApp: NitroApp) => {
|
|
47
|
+
const app: Application = ${puts([
|
|
48
|
+
[koa, `feathersKoa(feathers())`],
|
|
49
|
+
[exp, `feathersExpress(feathers())`],
|
|
50
|
+
[!rest, `feathers()`]
|
|
51
|
+
])}
|
|
52
|
+
${put(options.loadFeathersConfig, `
|
|
53
|
+
app.configure(configuration())
|
|
54
|
+
`)}
|
|
55
|
+
// Add nitroApp to feathers app
|
|
56
|
+
app.nitroApp = nitroApp;
|
|
57
|
+
${put(rest, `${put(koa, `
|
|
58
|
+
// Set up Koa middleware
|
|
59
|
+
app.configure(koaErrorHandler)
|
|
60
|
+
app.use(bodyParser())`)}
|
|
61
|
+
${put(exp, ` // Set up Express middleware
|
|
62
|
+
app.use(json())
|
|
63
|
+
app.use(urlencoded({ extended: true }))
|
|
64
|
+
`)}
|
|
65
|
+
${put(rest, `// Init rest server
|
|
66
|
+
app.set('framework', '${framework}')
|
|
67
|
+
app.configure(rest(${put(auth, `{
|
|
68
|
+
authentication: {
|
|
69
|
+
strategies: ['${authStrategies?.join(`', '`)}'],
|
|
70
|
+
},
|
|
71
|
+
}`)}))
|
|
72
|
+
`)}`)}
|
|
73
|
+
// Init socket.io server for real-time functionality
|
|
74
|
+
app.set('websocket', ${!!sio})${put(sio, `
|
|
75
|
+
app.configure(socketio({
|
|
76
|
+
path: '${websocketPath}',
|
|
77
|
+
transports: ['websocket']
|
|
78
|
+
}))`)}
|
|
79
|
+
|
|
80
|
+
${put(auth, `// Init auth
|
|
81
|
+
app.configure(authentication)
|
|
82
|
+
`)}
|
|
83
|
+
${put(mongo, `// Init mongodb
|
|
84
|
+
app.configure(mongodb)
|
|
85
|
+
`)}
|
|
86
|
+
// Init services
|
|
87
|
+
${services.map((service) => `app.configure(${service.meta.importId})`).join("\n ")}
|
|
88
|
+
|
|
89
|
+
// Init plugins
|
|
90
|
+
${plugins.map((plugin) => `app.configure(${plugin.meta.importId})`).join("\n ")}
|
|
91
|
+
${put(exp, `
|
|
92
|
+
// Set up Express middleware for 404s and the error handler
|
|
93
|
+
app.configure(expressErrorHandler)
|
|
94
|
+
`)}
|
|
95
|
+
void app.setup().then(()=> { // TODO: make async in Nitro v3
|
|
96
|
+
${puts([
|
|
97
|
+
[koa, ` // Init koa router
|
|
98
|
+
createKoaRouter(app, '${restPath}')`],
|
|
99
|
+
[exp, ` // Init express router
|
|
100
|
+
createExpressRouter(app, '${restPath}')`],
|
|
101
|
+
[sio, ` // Init socket.io router
|
|
102
|
+
createSocketIoRouter(app)`]
|
|
103
|
+
])}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
nitroApp.hooks.hook("close", async () => app.teardown());
|
|
107
|
+
})
|
|
108
|
+
`;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { put, puts } from "../utils.js";
|
|
2
|
+
export function getServerContents(options) {
|
|
3
|
+
return () => {
|
|
4
|
+
const transports = options?.transports;
|
|
5
|
+
const rest = !!transports?.rest;
|
|
6
|
+
const exp = (transports?.rest).framework === "express";
|
|
7
|
+
const koa = (transports?.rest).framework === "koa";
|
|
8
|
+
const mongo = !!options.database?.mongo;
|
|
9
|
+
let entity, entityImport;
|
|
10
|
+
const auth = options?.auth;
|
|
11
|
+
if (auth) {
|
|
12
|
+
entity = auth.entity;
|
|
13
|
+
entityImport = auth.entityImport;
|
|
14
|
+
}
|
|
15
|
+
return `// ! Generated by nuxt-feathers-zod - do not change manually
|
|
16
|
+
import type { ${put(!rest, `Application as FeathersApplication, `)}HookContext as FeathersHookContext, NextFunction } from '@feathersjs/feathers'
|
|
17
|
+
${put(mongo, `import type { Db } from 'mongodb'`)}
|
|
18
|
+
${puts([
|
|
19
|
+
[koa, `import type { Application as FeathersApplication } from '@feathersjs/koa'`],
|
|
20
|
+
[exp, `import type { Application as FeathersApplication } from '@feathersjs/express'`]
|
|
21
|
+
])}
|
|
22
|
+
${put(auth, `import type { User } from '${entityImport?.from}'`)}
|
|
23
|
+
// import type { ModuleOptions } from '???'
|
|
24
|
+
import type { NitroApp } from 'nitropack'
|
|
25
|
+
|
|
26
|
+
export type { NextFunction }
|
|
27
|
+
|
|
28
|
+
export interface Configuration {
|
|
29
|
+
framework?: 'express' | 'koa'
|
|
30
|
+
websocket?: boolean${put(mongo, `
|
|
31
|
+
mongodbClient: Promise<Db>`)}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// A mapping of service names to types. Will be extended in service files.
|
|
35
|
+
export interface ServiceTypes {}
|
|
36
|
+
|
|
37
|
+
export interface ApplicationAddons {
|
|
38
|
+
nitroApp?: NitroApp
|
|
39
|
+
// moduleOptions: ModuleOptions
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// The application instance type that will be used everywhere else
|
|
43
|
+
export type Application = FeathersApplication<ServiceTypes, Configuration> & ApplicationAddons
|
|
44
|
+
|
|
45
|
+
// The context for hook functions - can be typed with a service class
|
|
46
|
+
export type HookContext<S = any> = FeathersHookContext<Application, S>
|
|
47
|
+
|
|
48
|
+
export type FeathersServerPlugin = Parameters<Application['configure']>['0']
|
|
49
|
+
|
|
50
|
+
export function defineFeathersServerPlugin(def: FeathersServerPlugin): FeathersServerPlugin {
|
|
51
|
+
return def
|
|
52
|
+
}
|
|
53
|
+
${put(auth, `
|
|
54
|
+
declare module '@feathersjs/feathers' {
|
|
55
|
+
interface Params {
|
|
56
|
+
${entity}?: ${entityImport?.as}
|
|
57
|
+
}
|
|
58
|
+
}`)}
|
|
59
|
+
`;
|
|
60
|
+
};
|
|
61
|
+
}
|