@zmdb/nuxt 1.0.0-beta.1
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/LICENSE +674 -0
- package/README.md +82 -0
- package/dist/client/index.d.ts +26 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +95 -0
- package/dist/client/index.js.map +1 -0
- package/dist/forwarding.d.ts +3 -0
- package/dist/forwarding.d.ts.map +1 -0
- package/dist/forwarding.js +29 -0
- package/dist/forwarding.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +81 -0
- package/dist/index.js.map +1 -0
- package/dist/server/index.d.ts +21 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +89 -0
- package/dist/server/index.js.map +1 -0
- package/package.json +62 -0
- package/src/client/index.ts +142 -0
- package/src/forwarding.ts +34 -0
- package/src/index.ts +112 -0
- package/src/server/index.ts +128 -0
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# @zmdb/nuxt
|
|
2
|
+
|
|
3
|
+
`@zmdb/nuxt` binds an application-generated zmdb client to Nuxt 4. It installs separate server and browser plugins, uses a request-local Nitro transport with explicit credential allow-lists, reuses
|
|
4
|
+
`@zmdb/vue`, and delegates SSR payload hydration to native `useAsyncData`.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
yarn add @zmdb/nuxt@1.0.0-beta.1 @zmdb/vue@1.0.0-beta.1 nuxt@^4.5 vue@^3.5
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
> **Prerelease** (`1.0.0-beta.1`). Requires **Node.js 26+**, is **ESM-only**, and declares Nuxt and Vue as required peers.
|
|
13
|
+
|
|
14
|
+
## Create the typed integration
|
|
15
|
+
|
|
16
|
+
Create one application module that exports the generated-client factory and a binding namespace. Passing Nuxt's own `useAsyncData` keeps payload storage, hydration de-duplication, cancellation, and
|
|
17
|
+
navigation refreshes inside Nuxt rather than adding another cache.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { createZmdbNuxt } from '@zmdb/nuxt/client';
|
|
21
|
+
import { useAsyncData } from '#app';
|
|
22
|
+
|
|
23
|
+
import { createApiClient } from './generated/api.generated.js';
|
|
24
|
+
import type { ApiClient } from './generated/api.generated.js';
|
|
25
|
+
|
|
26
|
+
export { createApiClient };
|
|
27
|
+
export const zmdb = createZmdbNuxt<ApiClient>({ useAsyncData });
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Register the module and name only credentials that may cross from the incoming request:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
export default defineNuxtConfig({
|
|
34
|
+
modules: [
|
|
35
|
+
[
|
|
36
|
+
'@zmdb/nuxt',
|
|
37
|
+
{
|
|
38
|
+
integration: '~/app/zmdb.ts',
|
|
39
|
+
baseUrl: '/api',
|
|
40
|
+
forwardHeaders: ['authorization', 'x-tenant-id'],
|
|
41
|
+
forwardCookies: ['session'],
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The module generates separate `.server` and `.client` plugins. The server plugin creates one generated client per Nitro request over Nitro's local fetch and forwards only the selected values. The
|
|
49
|
+
client plugin creates a browser-fetch client after hydration. Neither plugin starts a request during installation.
|
|
50
|
+
|
|
51
|
+
## Native hydration
|
|
52
|
+
|
|
53
|
+
Use an explicit operation key and serializable input:
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
const route = useRoute();
|
|
57
|
+
const widget = await zmdb.useZmdbAsyncData(
|
|
58
|
+
'getWidget',
|
|
59
|
+
() => ({ id: String(route.params.id) }),
|
|
60
|
+
(client, input, signal) => client.getWidget(input, { signal }),
|
|
61
|
+
);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The adapter derives a deterministic key from the operation key and canonical JSON input. A matching Nuxt payload result is reused during hydration, while a new navigation input selects a new key and
|
|
65
|
+
uses the browser client. Non-finite numbers, cycles, class instances, functions, symbols, bigints, sparse arrays, arrays with named properties, and `undefined` values are rejected before dispatch.
|
|
66
|
+
|
|
67
|
+
The inherited `useZmdbClient`, `useZmdbQuery`, and `useZmdbMutation` methods are the real `@zmdb/vue` bindings. Vue effect-scope cancellation, stale-result suppression, and mutation semantics are not
|
|
68
|
+
copied into this package.
|
|
69
|
+
|
|
70
|
+
## Entry points
|
|
71
|
+
|
|
72
|
+
- `@zmdb/nuxt` — Nuxt module.
|
|
73
|
+
- `@zmdb/nuxt/client` — typed bindings, native `useAsyncData`, and browser plugin.
|
|
74
|
+
- `@zmdb/nuxt/server` — Nitro request transport and server plugin.
|
|
75
|
+
|
|
76
|
+
## Documentation
|
|
77
|
+
|
|
78
|
+
See the [framework integration guide](https://ambasta.github.io/zmdb/docs/framework-integrations.html) and the package contract in `SPEC.md`.
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
GNU General Public License v3.0 or later (GPL-3.0-or-later) — see [LICENSE](./LICENSE).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ClientOptions } from '@zmdb/client';
|
|
2
|
+
import type { FetchLike } from '@zmdb/client/transport';
|
|
3
|
+
import type { QueryLoader, ZmdbVueBindings } from '@zmdb/vue';
|
|
4
|
+
import type { AsyncData, NuxtError, useAsyncData as useNuxtAsyncData } from 'nuxt/app';
|
|
5
|
+
import type { App, MaybeRefOrGetter } from 'vue';
|
|
6
|
+
export type NuxtGeneratedClientFactory<Client extends object> = (options: ClientOptions) => Client;
|
|
7
|
+
export interface ZmdbNuxtBindingOptions {
|
|
8
|
+
readonly useAsyncData: typeof useNuxtAsyncData;
|
|
9
|
+
readonly bindingName?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ZmdbNuxtAsyncData<Output> extends AsyncData<Output | undefined, NuxtError<unknown> | undefined> {
|
|
12
|
+
}
|
|
13
|
+
export interface ZmdbNuxtBindings<Client extends object> extends ZmdbVueBindings<Client> {
|
|
14
|
+
useZmdbAsyncData<Input, Output>(operationKey: string, input: MaybeRefOrGetter<Input>, load: QueryLoader<Client, Input, Output>): ZmdbNuxtAsyncData<Output>;
|
|
15
|
+
}
|
|
16
|
+
export interface NuxtClientApplication {
|
|
17
|
+
readonly vueApp: Pick<App, 'use'>;
|
|
18
|
+
}
|
|
19
|
+
export interface ZmdbNuxtClientPluginOptions {
|
|
20
|
+
readonly baseUrl: string | URL;
|
|
21
|
+
readonly fetch?: FetchLike;
|
|
22
|
+
}
|
|
23
|
+
export declare function createNuxtDataKey(operationKey: string, input: unknown): string;
|
|
24
|
+
export declare function createZmdbNuxt<Client extends object>(options: ZmdbNuxtBindingOptions): ZmdbNuxtBindings<Client>;
|
|
25
|
+
export declare function createZmdbNuxtClientPlugin<Client extends object>(bindings: Pick<ZmdbNuxtBindings<Client>, 'createZmdbPlugin'>, createClient: NuxtGeneratedClientFactory<Client>, options: ZmdbNuxtClientPluginOptions): (nuxtApp: NuxtClientApplication) => void;
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEvF,OAAO,KAAK,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,KAAK,CAAC;AAEjD,MAAM,MAAM,0BAA0B,CAAC,MAAM,SAAS,MAAM,IAAI,CAAC,OAAO,EAAE,aAAa,KAAK,MAAM,CAAC;AAEnG,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,YAAY,EAAE,OAAO,gBAAgB,CAAC;IAC/C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB,CAAC,MAAM,CAAE,SAAQ,SAAS,CAAC,MAAM,GAAG,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;CAAG;AAEnH,MAAM,WAAW,gBAAgB,CAAC,MAAM,SAAS,MAAM,CAAE,SAAQ,eAAe,CAAC,MAAM,CAAC;IACtF,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAC5B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAC9B,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,GACvC,iBAAiB,CAAC,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;CAC5B;AAkDD,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAM9E;AAeD,wBAAgB,cAAc,CAAC,MAAM,SAAS,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAsB/G;AAED,wBAAgB,0BAA0B,CAAC,MAAM,SAAS,MAAM,EAC9D,QAAQ,EAAE,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC,EAC5D,YAAY,EAAE,0BAA0B,CAAC,MAAM,CAAC,EAChD,OAAO,EAAE,2BAA2B,GACnC,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAS1C"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { createFetchTransport } from '@zmdb/client';
|
|
2
|
+
import { createZmdbVue } from '@zmdb/vue';
|
|
3
|
+
import { computed, toValue } from 'vue';
|
|
4
|
+
function encoded(value, seen) {
|
|
5
|
+
if (value === null)
|
|
6
|
+
return 'null';
|
|
7
|
+
if (typeof value === 'string' || typeof value === 'boolean') {
|
|
8
|
+
const result = JSON.stringify(value);
|
|
9
|
+
if (result === undefined)
|
|
10
|
+
throw new Error('@zmdb/nuxt could not serialize a hydration input');
|
|
11
|
+
return result;
|
|
12
|
+
}
|
|
13
|
+
if (typeof value === 'number') {
|
|
14
|
+
if (!Number.isFinite(value))
|
|
15
|
+
throw new Error('@zmdb/nuxt hydration input numbers must be finite');
|
|
16
|
+
return Object.is(value, -0) ? '0' : String(value);
|
|
17
|
+
}
|
|
18
|
+
if (typeof value !== 'object') {
|
|
19
|
+
throw new Error(`@zmdb/nuxt hydration input contains non-serializable ${typeof value}`);
|
|
20
|
+
}
|
|
21
|
+
if (seen.has(value))
|
|
22
|
+
throw new Error('@zmdb/nuxt hydration input contains a cycle');
|
|
23
|
+
seen.add(value);
|
|
24
|
+
try {
|
|
25
|
+
if (Array.isArray(value)) {
|
|
26
|
+
const keys = Object.keys(value);
|
|
27
|
+
if (keys.length !== value.length || keys.some((key, index) => key !== String(index))) {
|
|
28
|
+
throw new Error('@zmdb/nuxt hydration input arrays must be dense and contain no named properties');
|
|
29
|
+
}
|
|
30
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
31
|
+
throw new Error('@zmdb/nuxt hydration input contains non-serializable symbol keys');
|
|
32
|
+
}
|
|
33
|
+
return `[${value.map(item => encoded(item, seen)).join(',')}]`;
|
|
34
|
+
}
|
|
35
|
+
const prototype = Object.getPrototypeOf(value);
|
|
36
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
37
|
+
throw new Error('@zmdb/nuxt hydration input must contain only plain objects and arrays');
|
|
38
|
+
}
|
|
39
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
40
|
+
throw new Error('@zmdb/nuxt hydration input contains non-serializable symbol keys');
|
|
41
|
+
}
|
|
42
|
+
const entries = Object.entries(value).toSorted(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0));
|
|
43
|
+
return `{${entries
|
|
44
|
+
.map(([key, item]) => {
|
|
45
|
+
const encodedKey = JSON.stringify(key);
|
|
46
|
+
if (encodedKey === undefined)
|
|
47
|
+
throw new Error('@zmdb/nuxt could not serialize a hydration key');
|
|
48
|
+
return `${encodedKey}:${encoded(item, seen)}`;
|
|
49
|
+
})
|
|
50
|
+
.join(',')}}`;
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
seen.delete(value);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function createNuxtDataKey(operationKey, input) {
|
|
57
|
+
const selectedOperation = operationKey.trim();
|
|
58
|
+
if (selectedOperation.length === 0) {
|
|
59
|
+
throw new Error('@zmdb/nuxt operation key must be a non-empty string');
|
|
60
|
+
}
|
|
61
|
+
return `zmdb:${encoded([selectedOperation, input], new Set())}`;
|
|
62
|
+
}
|
|
63
|
+
function invoke(load, client, input, signal) {
|
|
64
|
+
try {
|
|
65
|
+
return Promise.resolve(load(client, input, signal));
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
return Promise.reject(error);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export function createZmdbNuxt(options) {
|
|
72
|
+
const vue = createZmdbVue(options.bindingName ?? '@zmdb/nuxt');
|
|
73
|
+
return Object.freeze({
|
|
74
|
+
...vue,
|
|
75
|
+
useZmdbAsyncData(operationKey, input, load) {
|
|
76
|
+
const client = vue.useZmdbClient();
|
|
77
|
+
const key = computed(() => createNuxtDataKey(operationKey, toValue(input)));
|
|
78
|
+
return options.useAsyncData(key, (_nuxtApp, context) => invoke(load, client, toValue(input), context.signal), {
|
|
79
|
+
dedupe: 'cancel',
|
|
80
|
+
deep: false,
|
|
81
|
+
});
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
export function createZmdbNuxtClientPlugin(bindings, createClient, options) {
|
|
86
|
+
return nuxtApp => {
|
|
87
|
+
const transport = createFetchTransport(options.fetch);
|
|
88
|
+
const client = createClient({
|
|
89
|
+
baseUrl: options.baseUrl,
|
|
90
|
+
transport,
|
|
91
|
+
});
|
|
92
|
+
nuxtApp.vueApp.use(bindings.createZmdbPlugin(client));
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forwarding.d.ts","sourceRoot":"","sources":["../src/forwarding.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAc1D,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EACrC,IAAI,EAAE,uBAAuB,GAC5B,SAAS,MAAM,EAAE,CAgBnB"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const HEADER_NAME = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
2
|
+
const COOKIE_NAME = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
3
|
+
const RESERVED_FORWARD_HEADERS = new Set([
|
|
4
|
+
'accept',
|
|
5
|
+
'connection',
|
|
6
|
+
'content-length',
|
|
7
|
+
'content-type',
|
|
8
|
+
'cookie',
|
|
9
|
+
'host',
|
|
10
|
+
'transfer-encoding',
|
|
11
|
+
]);
|
|
12
|
+
export function normalizeForwardNames(values, kind) {
|
|
13
|
+
const selected = values ?? [];
|
|
14
|
+
const normalized = selected.map(value => (kind === 'header' ? value.trim().toLowerCase() : value.trim()));
|
|
15
|
+
const pattern = kind === 'header' ? HEADER_NAME : COOKIE_NAME;
|
|
16
|
+
for (const value of normalized) {
|
|
17
|
+
if (!pattern.test(value)) {
|
|
18
|
+
throw new Error(`@zmdb/nuxt forward ${kind} name ${JSON.stringify(value)} is invalid`);
|
|
19
|
+
}
|
|
20
|
+
if (kind === 'header' && RESERVED_FORWARD_HEADERS.has(value)) {
|
|
21
|
+
throw new Error(`@zmdb/nuxt forward header ${value} is transport-owned; use forwardCookies for cookies`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (new Set(normalized).size !== normalized.length) {
|
|
25
|
+
throw new Error(`@zmdb/nuxt forward ${kind} names must not contain duplicates`);
|
|
26
|
+
}
|
|
27
|
+
return Object.freeze(normalized);
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=forwarding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forwarding.js","sourceRoot":"","sources":["../src/forwarding.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,GAAG,gCAAgC,CAAC;AACrD,MAAM,WAAW,GAAG,gCAAgC,CAAC;AACrD,MAAM,wBAAwB,GAAG,IAAI,GAAG,CAAC;IACvC,QAAQ;IACR,YAAY;IACZ,gBAAgB;IAChB,cAAc;IACd,QAAQ;IACR,MAAM;IACN,mBAAmB;CACpB,CAAC,CAAC;AAEH,MAAM,UAAU,qBAAqB,CACnC,MAAqC,EACrC,IAA6B;IAE7B,MAAM,QAAQ,GAAG,MAAM,IAAI,EAAE,CAAC;IAC9B,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1G,MAAM,OAAO,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;IAC9D,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACzF,CAAC;QACD,IAAI,IAAI,KAAK,QAAQ,IAAI,wBAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,6BAA6B,KAAK,qDAAqD,CAAC,CAAC;QAC3G,CAAC;IACH,CAAC;IACD,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,oCAAoC,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;AACnC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface ZmdbNuxtModuleOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Application module exporting both the typed bindings and generated-client
|
|
4
|
+
* factory named below.
|
|
5
|
+
*/
|
|
6
|
+
readonly integration: string;
|
|
7
|
+
readonly bindingExport?: string;
|
|
8
|
+
readonly clientFactoryExport?: string;
|
|
9
|
+
readonly baseUrl?: string;
|
|
10
|
+
readonly forwardHeaders?: readonly string[];
|
|
11
|
+
readonly forwardCookies?: readonly string[];
|
|
12
|
+
}
|
|
13
|
+
export declare const zmdbNuxtModule: import("@nuxt/schema").NuxtModule<ZmdbNuxtModuleOptions, ZmdbNuxtModuleOptions, false>;
|
|
14
|
+
export default zmdbNuxtModule;
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7C;AA2ED,eAAO,MAAM,cAAc,wFAmBzB,CAAC;eAEY,cAAc"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { addPluginTemplate, defineNuxtModule, resolvePath } from 'nuxt/kit';
|
|
2
|
+
import { normalizeForwardNames } from './forwarding.js';
|
|
3
|
+
const IDENTIFIER = /^[$A-Z_a-z][$\w]*$/;
|
|
4
|
+
function requiredText(value, label) {
|
|
5
|
+
const selected = value?.trim();
|
|
6
|
+
if (selected === undefined || selected.length === 0) {
|
|
7
|
+
throw new Error(`@zmdb/nuxt ${label} must be a non-empty string`);
|
|
8
|
+
}
|
|
9
|
+
return selected;
|
|
10
|
+
}
|
|
11
|
+
function exportName(value, fallback, label) {
|
|
12
|
+
const selected = value ?? fallback;
|
|
13
|
+
if (!IDENTIFIER.test(selected)) {
|
|
14
|
+
throw new Error(`@zmdb/nuxt ${label} must be a JavaScript identifier`);
|
|
15
|
+
}
|
|
16
|
+
return selected;
|
|
17
|
+
}
|
|
18
|
+
async function resolvedOptions(options) {
|
|
19
|
+
const integration = await resolvePath(requiredText(options.integration, 'integration module'));
|
|
20
|
+
return Object.freeze({
|
|
21
|
+
integration,
|
|
22
|
+
bindingExport: exportName(options.bindingExport, 'zmdb', 'bindingExport'),
|
|
23
|
+
clientFactoryExport: exportName(options.clientFactoryExport, 'createApiClient', 'clientFactoryExport'),
|
|
24
|
+
baseUrl: requiredText(options.baseUrl ?? '/api', 'baseUrl'),
|
|
25
|
+
forwardHeaders: normalizeForwardNames(options.forwardHeaders, 'header'),
|
|
26
|
+
forwardCookies: normalizeForwardNames(options.forwardCookies, 'cookie'),
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
function integrationImport(options) {
|
|
30
|
+
return `import { ${options.bindingExport} as zmdbBindings, ${options.clientFactoryExport} as createZmdbClient } from ${JSON.stringify(options.integration)};`;
|
|
31
|
+
}
|
|
32
|
+
function clientPlugin(options) {
|
|
33
|
+
return [
|
|
34
|
+
"import { defineNuxtPlugin } from '#app';",
|
|
35
|
+
"import { createZmdbNuxtClientPlugin } from '@zmdb/nuxt/client';",
|
|
36
|
+
integrationImport(options),
|
|
37
|
+
'',
|
|
38
|
+
`export default defineNuxtPlugin(createZmdbNuxtClientPlugin(zmdbBindings, createZmdbClient, ${JSON.stringify({ baseUrl: options.baseUrl })}));`,
|
|
39
|
+
'',
|
|
40
|
+
].join('\n');
|
|
41
|
+
}
|
|
42
|
+
function serverPlugin(options) {
|
|
43
|
+
return [
|
|
44
|
+
"import { defineNuxtPlugin } from '#app';",
|
|
45
|
+
"import { useNitroApp } from 'nitropack/runtime';",
|
|
46
|
+
"import { createZmdbNuxtServerPlugin } from '@zmdb/nuxt/server';",
|
|
47
|
+
integrationImport(options),
|
|
48
|
+
'',
|
|
49
|
+
'export default defineNuxtPlugin(',
|
|
50
|
+
' createZmdbNuxtServerPlugin(zmdbBindings, createZmdbClient, {',
|
|
51
|
+
` baseUrl: ${JSON.stringify(options.baseUrl)},`,
|
|
52
|
+
` forwardHeaders: ${JSON.stringify(options.forwardHeaders)},`,
|
|
53
|
+
` forwardCookies: ${JSON.stringify(options.forwardCookies)},`,
|
|
54
|
+
' fetch: useNitroApp().localFetch,',
|
|
55
|
+
' }),',
|
|
56
|
+
');',
|
|
57
|
+
'',
|
|
58
|
+
].join('\n');
|
|
59
|
+
}
|
|
60
|
+
export const zmdbNuxtModule = defineNuxtModule({
|
|
61
|
+
meta: {
|
|
62
|
+
name: '@zmdb/nuxt',
|
|
63
|
+
configKey: 'zmdb',
|
|
64
|
+
compatibility: {
|
|
65
|
+
nuxt: '>=4.5.2 <5.0.0',
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
async setup(options) {
|
|
69
|
+
const resolved = await resolvedOptions(options);
|
|
70
|
+
addPluginTemplate({
|
|
71
|
+
filename: 'zmdb.client.mjs',
|
|
72
|
+
getContents: () => clientPlugin(resolved),
|
|
73
|
+
});
|
|
74
|
+
addPluginTemplate({
|
|
75
|
+
filename: 'zmdb.server.mjs',
|
|
76
|
+
getContents: () => serverPlugin(resolved),
|
|
77
|
+
});
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
export default zmdbNuxtModule;
|
|
81
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ClientTransport } from '@zmdb/client';
|
|
2
|
+
import type { FetchLike } from '@zmdb/client/transport';
|
|
3
|
+
import type { App } from 'vue';
|
|
4
|
+
import type { NuxtGeneratedClientFactory, ZmdbNuxtBindings } from '../client/index.js';
|
|
5
|
+
export interface ZmdbNuxtForwardingOptions {
|
|
6
|
+
readonly forwardHeaders?: readonly string[];
|
|
7
|
+
readonly forwardCookies?: readonly string[];
|
|
8
|
+
}
|
|
9
|
+
export interface ZmdbNuxtServerPluginOptions extends ZmdbNuxtForwardingOptions {
|
|
10
|
+
readonly baseUrl: string | URL;
|
|
11
|
+
readonly fetch: FetchLike;
|
|
12
|
+
}
|
|
13
|
+
export interface NuxtServerApplication {
|
|
14
|
+
readonly vueApp: Pick<App, 'use'>;
|
|
15
|
+
readonly ssrContext?: {
|
|
16
|
+
readonly event?: unknown;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export declare function createNuxtServerTransport(fetch: FetchLike, incomingHeaders: Headers, options?: ZmdbNuxtForwardingOptions): ClientTransport;
|
|
20
|
+
export declare function createZmdbNuxtServerPlugin<Client extends object>(bindings: Pick<ZmdbNuxtBindings<Client>, 'createZmdbPlugin'>, createClient: NuxtGeneratedClientFactory<Client>, options: ZmdbNuxtServerPluginOptions): (nuxtApp: NuxtServerApplication) => void;
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,eAAe,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE/B,OAAO,KAAK,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGvF,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7C;AAED,MAAM,WAAW,2BAA4B,SAAQ,yBAAyB;IAC5E,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE;QACpB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;KAC1B,CAAC;CACH;AAyED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,SAAS,EAChB,eAAe,EAAE,OAAO,EACxB,OAAO,GAAE,yBAA8B,GACtC,eAAe,CAWjB;AAED,wBAAgB,0BAA0B,CAAC,MAAM,SAAS,MAAM,EAC9D,QAAQ,EAAE,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC,EAC5D,YAAY,EAAE,0BAA0B,CAAC,MAAM,CAAC,EAChD,OAAO,EAAE,2BAA2B,GACnC,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAU1C"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { createFetchTransport } from '@zmdb/client';
|
|
2
|
+
import { normalizeForwardNames } from '../forwarding.js';
|
|
3
|
+
function cookiePairs(value) {
|
|
4
|
+
const pairs = new Map();
|
|
5
|
+
for (const segment of value?.split(';') ?? []) {
|
|
6
|
+
const separator = segment.indexOf('=');
|
|
7
|
+
if (separator <= 0)
|
|
8
|
+
continue;
|
|
9
|
+
const name = segment.slice(0, separator).trim();
|
|
10
|
+
if (name.length === 0 || pairs.has(name))
|
|
11
|
+
continue;
|
|
12
|
+
pairs.set(name, segment.slice(separator + 1).trim());
|
|
13
|
+
}
|
|
14
|
+
return pairs;
|
|
15
|
+
}
|
|
16
|
+
function selectedCookieHeader(incoming, names, operationCookie) {
|
|
17
|
+
const selected = new Map();
|
|
18
|
+
for (const name of names) {
|
|
19
|
+
const value = incoming.get(name);
|
|
20
|
+
if (value !== undefined)
|
|
21
|
+
selected.set(name, value);
|
|
22
|
+
}
|
|
23
|
+
for (const [name, value] of cookiePairs(operationCookie))
|
|
24
|
+
selected.set(name, value);
|
|
25
|
+
if (selected.size === 0)
|
|
26
|
+
return undefined;
|
|
27
|
+
return [...selected].map(([name, value]) => `${name}=${value}`).join('; ');
|
|
28
|
+
}
|
|
29
|
+
function forwardedHeaders(incoming, names) {
|
|
30
|
+
const selected = new Headers();
|
|
31
|
+
for (const name of names) {
|
|
32
|
+
const value = incoming.get(name);
|
|
33
|
+
if (value !== null)
|
|
34
|
+
selected.set(name, value);
|
|
35
|
+
}
|
|
36
|
+
return selected;
|
|
37
|
+
}
|
|
38
|
+
function requestInit(init, forwarded, cookie) {
|
|
39
|
+
const headers = new Headers(init?.headers);
|
|
40
|
+
forwarded.forEach((value, name) => {
|
|
41
|
+
if (!headers.has(name))
|
|
42
|
+
headers.set(name, value);
|
|
43
|
+
});
|
|
44
|
+
if (cookie !== undefined && !headers.has('cookie'))
|
|
45
|
+
headers.set('cookie', cookie);
|
|
46
|
+
return init === undefined ? { headers } : { ...init, headers };
|
|
47
|
+
}
|
|
48
|
+
function withoutCookie(request) {
|
|
49
|
+
if (request.headers.cookie === undefined)
|
|
50
|
+
return request;
|
|
51
|
+
const headers = Object.freeze(Object.fromEntries(Object.entries(request.headers).filter(([name]) => name !== 'cookie')));
|
|
52
|
+
return Object.freeze({
|
|
53
|
+
...request,
|
|
54
|
+
headers,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function requestEvent(value) {
|
|
58
|
+
if (typeof value !== 'object' || value === null || !('headers' in value)) {
|
|
59
|
+
throw new Error('@zmdb/nuxt server plugin requires the current Nitro request event');
|
|
60
|
+
}
|
|
61
|
+
const headers = value.headers;
|
|
62
|
+
if (!(headers instanceof Headers)) {
|
|
63
|
+
throw new Error('@zmdb/nuxt server plugin requires the current Nitro request event');
|
|
64
|
+
}
|
|
65
|
+
return Object.freeze({ headers });
|
|
66
|
+
}
|
|
67
|
+
export function createNuxtServerTransport(fetch, incomingHeaders, options = {}) {
|
|
68
|
+
const headerNames = normalizeForwardNames(options.forwardHeaders, 'header');
|
|
69
|
+
const cookieNames = normalizeForwardNames(options.forwardCookies, 'cookie');
|
|
70
|
+
const forwarded = forwardedHeaders(incomingHeaders, headerNames);
|
|
71
|
+
const incomingCookies = cookiePairs(incomingHeaders.get('cookie'));
|
|
72
|
+
return request => {
|
|
73
|
+
const cookie = selectedCookieHeader(incomingCookies, cookieNames, request.headers.cookie);
|
|
74
|
+
const requestFetch = (input, init) => fetch(input, requestInit(init, forwarded, cookie));
|
|
75
|
+
return createFetchTransport(requestFetch)(withoutCookie(request));
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export function createZmdbNuxtServerPlugin(bindings, createClient, options) {
|
|
79
|
+
return nuxtApp => {
|
|
80
|
+
const event = requestEvent(nuxtApp.ssrContext?.event);
|
|
81
|
+
const transport = createNuxtServerTransport(options.fetch, event.headers, options);
|
|
82
|
+
const client = createClient({
|
|
83
|
+
baseUrl: options.baseUrl,
|
|
84
|
+
transport,
|
|
85
|
+
});
|
|
86
|
+
nuxtApp.vueApp.use(bindings.createZmdbPlugin(client));
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zmdb/nuxt",
|
|
3
|
+
"version": "1.0.0-beta.1",
|
|
4
|
+
"description": "Nuxt module, request-scoped Nitro transport, Vue bindings, and native hydration for generated zmdb clients.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"client",
|
|
7
|
+
"nitro",
|
|
8
|
+
"nuxt",
|
|
9
|
+
"ssr",
|
|
10
|
+
"typescript",
|
|
11
|
+
"vue",
|
|
12
|
+
"zmdb"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://github.com/ambasta/zmdb#readme",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/ambasta/zmdb/issues"
|
|
17
|
+
},
|
|
18
|
+
"license": "GPL-3.0-or-later",
|
|
19
|
+
"author": "zmdb contributors",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/ambasta/zmdb.git",
|
|
23
|
+
"directory": "packages/nuxt"
|
|
24
|
+
},
|
|
25
|
+
"type": "module",
|
|
26
|
+
"sideEffects": false,
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./client": {
|
|
33
|
+
"types": "./dist/client/index.d.ts",
|
|
34
|
+
"import": "./dist/client/index.js"
|
|
35
|
+
},
|
|
36
|
+
"./server": {
|
|
37
|
+
"types": "./dist/server/index.d.ts",
|
|
38
|
+
"import": "./dist/server/index.js"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public",
|
|
43
|
+
"tag": "beta"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "node ../../scripts/build-package.mjs",
|
|
47
|
+
"test": "vitest run"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@zmdb/client": "1.0.0-beta.1",
|
|
51
|
+
"@zmdb/vue": "1.0.0-beta.1"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"nuxt": ">=4.5.2 <5.0.0",
|
|
55
|
+
"vue": ">=3.5.42 <4.0.0"
|
|
56
|
+
},
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">=26"
|
|
59
|
+
},
|
|
60
|
+
"main": "./dist/index.js",
|
|
61
|
+
"types": "./dist/index.d.ts"
|
|
62
|
+
}
|