@softwareproduction/nuxt-introspection-forms 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 +344 -0
- package/dist/module.cjs +5 -0
- package/dist/module.d.mts +30 -0
- package/dist/module.d.ts +30 -0
- package/dist/module.json +12 -0
- package/dist/module.mjs +49 -0
- package/dist/runtime/composables/index.d.ts +0 -0
- package/dist/runtime/composables/index.js +2 -0
- package/dist/runtime/composables/useIntrospectionForm.d.ts +0 -0
- package/dist/runtime/composables/useIntrospectionForm.js +1 -0
- package/dist/runtime/composables/useIntrospectionFormsEnumFilter.d.ts +0 -0
- package/dist/runtime/composables/useIntrospectionFormsEnumFilter.js +1 -0
- package/dist/runtime/plugins/introspection-forms.client.d.ts +0 -0
- package/dist/runtime/plugins/introspection-forms.client.js +11 -0
- package/dist/types.d.mts +7 -0
- package/dist/types.d.ts +7 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# @softwareproduction/nuxt-introspection-forms
|
|
2
|
+
|
|
3
|
+
Nuxt module that wraps [@softwareproduction/introspection-forms](../introspection-forms) for seamless integration with Nuxt 3 and 4 applications. It handles component registration, composable auto-imports, alias configuration, and global defaults injection — so you can use schema-driven forms with zero boilerplate.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Installation](#installation)
|
|
8
|
+
- [Module Setup](#module-setup)
|
|
9
|
+
- [Component Mapping Plugin](#component-mapping-plugin)
|
|
10
|
+
- [Usage in Pages & Components](#usage-in-pages--components)
|
|
11
|
+
- [GraphQL Codegen Integration](#graphql-codegen-integration)
|
|
12
|
+
- [Module Options](#module-options)
|
|
13
|
+
- [Provided Aliases](#provided-aliases)
|
|
14
|
+
- [Auto-Imports](#auto-imports)
|
|
15
|
+
- [Validation with Dryv](#validation-with-dryv)
|
|
16
|
+
- [Advanced Configuration](#advanced-configuration)
|
|
17
|
+
- [License](#license)
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
yarn add @softwareproduction/nuxt-introspection-forms @softwareproduction/introspection-forms
|
|
23
|
+
yarn add -D @graphql-codegen/cli graphql
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Peer dependencies: `vue >= 3.4`, `nuxt >= 3.9`.
|
|
27
|
+
|
|
28
|
+
## Module Setup
|
|
29
|
+
|
|
30
|
+
Add the module to your `nuxt.config.ts`:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
export default defineNuxtConfig({
|
|
34
|
+
modules: ['@softwareproduction/nuxt-introspection-forms'],
|
|
35
|
+
|
|
36
|
+
introspectionForms: {
|
|
37
|
+
// Path to generated introspection types (relative to rootDir)
|
|
38
|
+
generatedPath: 'types/generated/introspection',
|
|
39
|
+
},
|
|
40
|
+
})
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The module will:
|
|
44
|
+
|
|
45
|
+
1. Register `<IntrospectionForm>` and `<IntrospectionField>` as global components.
|
|
46
|
+
2. Auto-import `useIntrospectionForm` and `useIntrospectionFormsEnumFilter` composables.
|
|
47
|
+
3. Create `#introspection-types` and `#introspection-forms` aliases for convenient imports.
|
|
48
|
+
4. Register a client-side plugin that provides global defaults via `inject`.
|
|
49
|
+
|
|
50
|
+
## Component Mapping Plugin
|
|
51
|
+
|
|
52
|
+
Create a Nuxt plugin to define which UI components render which field types. This is where you connect `@softwareproduction/introspection-forms` to your design system.
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
// app/plugins/configure-forms.ts
|
|
56
|
+
import {
|
|
57
|
+
FormInput,
|
|
58
|
+
FormCheckbox,
|
|
59
|
+
FormRadio,
|
|
60
|
+
FormSelect,
|
|
61
|
+
FormTextarea,
|
|
62
|
+
FormDateInput,
|
|
63
|
+
} from '#components'
|
|
64
|
+
import type { IntrospectionFormsDefaults, IntrospectionField } from '@softwareproduction/introspection-forms'
|
|
65
|
+
import { withProps, useIntrospectionFormsEnumFilter } from '@softwareproduction/introspection-forms'
|
|
66
|
+
|
|
67
|
+
export default defineNuxtPlugin(nuxtApp => {
|
|
68
|
+
const { filterEnumValues } = useIntrospectionFormsEnumFilter()
|
|
69
|
+
|
|
70
|
+
nuxtApp.provide('introspection-forms', {
|
|
71
|
+
// Map by TypeScript scalar type
|
|
72
|
+
byFieldType: {
|
|
73
|
+
string: { component: FormInput },
|
|
74
|
+
number: { component: FormInput, props: { type: 'number' } },
|
|
75
|
+
boolean: { component: FormCheckbox },
|
|
76
|
+
enum: (introspection: IntrospectionField) => ({
|
|
77
|
+
component: introspection.enumValues.length > 5 ? FormSelect : FormRadio,
|
|
78
|
+
props: withProps<typeof FormRadio>(() => ({
|
|
79
|
+
options: (_, t) =>
|
|
80
|
+
filterEnumValues(introspection).map(value => ({
|
|
81
|
+
value,
|
|
82
|
+
label: t(`forms.${introspection.originalType}.${value}`),
|
|
83
|
+
})),
|
|
84
|
+
})),
|
|
85
|
+
}),
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
// Map by original GraphQL type name
|
|
89
|
+
byOriginalType: {
|
|
90
|
+
DateTime: { component: FormDateInput },
|
|
91
|
+
Float: { component: FormInput, props: { type: 'number', step: '0.01' } },
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
// Map by field name (regex matching, first match wins)
|
|
95
|
+
byFieldName: [
|
|
96
|
+
{ regexp: /^email/i, config: { component: FormInput, props: { type: 'email' } } },
|
|
97
|
+
{ regexp: /phone|telefon/i, config: { component: FormInput, props: { type: 'tel' } } },
|
|
98
|
+
{ regexp: /^(body|message|notes)/i, config: { component: FormTextarea } },
|
|
99
|
+
{ regexp: /files/i, config: { component: FormInput, props: { type: 'file', multiple: true } } },
|
|
100
|
+
{ regexp: /^(password|passwort)/i, config: { component: FormInput, props: { type: 'password' } } },
|
|
101
|
+
],
|
|
102
|
+
|
|
103
|
+
// Global enum value filters
|
|
104
|
+
enumFilters: {
|
|
105
|
+
Salutation: values => values.filter(v => v !== 'None'),
|
|
106
|
+
},
|
|
107
|
+
} satisfies IntrospectionFormsDefaults)
|
|
108
|
+
})
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Usage in Pages & Components
|
|
112
|
+
|
|
113
|
+
The module auto-imports everything you need. Import only the generated introspection type:
|
|
114
|
+
|
|
115
|
+
```vue
|
|
116
|
+
<script setup lang="ts">
|
|
117
|
+
import { TypeOfContactFormInput } from '#introspection-types'
|
|
118
|
+
|
|
119
|
+
const data = ref(TypeOfContactFormInput.create())
|
|
120
|
+
|
|
121
|
+
const form = useIntrospectionForm(TypeOfContactFormInput, {
|
|
122
|
+
firstName: true,
|
|
123
|
+
lastName: true,
|
|
124
|
+
email: true,
|
|
125
|
+
body: true,
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
async function submit() {
|
|
129
|
+
// data.value now contains the form values
|
|
130
|
+
await $fetch('/api/contact', { method: 'POST', body: data.value })
|
|
131
|
+
}
|
|
132
|
+
</script>
|
|
133
|
+
|
|
134
|
+
<template>
|
|
135
|
+
<IntrospectionForm :form="form" :model="data">
|
|
136
|
+
<button @click.prevent="submit">Send</button>
|
|
137
|
+
</IntrospectionForm>
|
|
138
|
+
</template>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### With Field Overrides
|
|
142
|
+
|
|
143
|
+
Override defaults for specific fields without losing the auto-resolved component:
|
|
144
|
+
|
|
145
|
+
```vue
|
|
146
|
+
<script setup lang="ts">
|
|
147
|
+
import { TypeOfRegistrationFormInput } from '#introspection-types'
|
|
148
|
+
|
|
149
|
+
const data = ref(TypeOfRegistrationFormInput.create({ useSameAddress: true }))
|
|
150
|
+
|
|
151
|
+
const form = useIntrospectionForm(TypeOfRegistrationFormInput, {
|
|
152
|
+
firstName: { span: 1 }, // Keep default component, adjust layout
|
|
153
|
+
lastName: { span: 1 },
|
|
154
|
+
email: true, // Use defaults entirely
|
|
155
|
+
phone: {
|
|
156
|
+
visible: model => model.preferredContact === 'Phone', // Conditional visibility
|
|
157
|
+
},
|
|
158
|
+
acceptTerms: { span: 2 },
|
|
159
|
+
})
|
|
160
|
+
</script>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### With Nested Forms
|
|
164
|
+
|
|
165
|
+
```vue
|
|
166
|
+
<script setup lang="ts">
|
|
167
|
+
import { TypeOfOrderInput, TypeOfAddressInput } from '#introspection-types'
|
|
168
|
+
|
|
169
|
+
const data = ref(TypeOfOrderInput.create())
|
|
170
|
+
|
|
171
|
+
const addressForm = useIntrospectionForm(TypeOfAddressInput, {
|
|
172
|
+
street: true,
|
|
173
|
+
houseNumber: true,
|
|
174
|
+
zipCode: true,
|
|
175
|
+
city: true,
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
const form = useIntrospectionForm(TypeOfOrderInput, {
|
|
179
|
+
productId: true,
|
|
180
|
+
quantity: true,
|
|
181
|
+
shippingAddress: { form: addressForm },
|
|
182
|
+
})
|
|
183
|
+
</script>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## GraphQL Codegen Integration
|
|
187
|
+
|
|
188
|
+
Set up the codegen plugin to generate introspection metadata from your schema:
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
// codegen.config.ts
|
|
192
|
+
import type { CodegenConfig } from '@graphql-codegen/cli'
|
|
193
|
+
|
|
194
|
+
const config: CodegenConfig = {
|
|
195
|
+
schema: './schema.graphql',
|
|
196
|
+
generates: {
|
|
197
|
+
'./types/generated/introspection/_placeholder.ts': {
|
|
198
|
+
plugins: ['@softwareproduction/introspection-forms/codegen'],
|
|
199
|
+
config: {
|
|
200
|
+
output: './types/generated/introspection',
|
|
201
|
+
typesImport: '../graphql-types',
|
|
202
|
+
introspectionTypeImport: '@softwareproduction/introspection-forms',
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export default config
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Add scripts to your `package.json`:
|
|
212
|
+
|
|
213
|
+
```json
|
|
214
|
+
{
|
|
215
|
+
"scripts": {
|
|
216
|
+
"gen:forms": "graphql-codegen --config codegen.config.ts",
|
|
217
|
+
"gen:types": "graphql-codegen --config codegen-types.config.ts"
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Run both generators when your schema changes:
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
yarn gen:types && yarn gen:forms
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Module Options
|
|
229
|
+
|
|
230
|
+
Configure via `introspectionForms` in `nuxt.config.ts`:
|
|
231
|
+
|
|
232
|
+
| Option | Type | Default | Description |
|
|
233
|
+
|--------|------|---------|-------------|
|
|
234
|
+
| `generatedPath` | `string` | `'types/generated/introspection'` | Path to generated introspection files (relative to `rootDir`) |
|
|
235
|
+
| `defaults` | `IntrospectionFormsDefaults` | `undefined` | Static component mapping defaults (alternative to the plugin approach for simple configs) |
|
|
236
|
+
|
|
237
|
+
## Provided Aliases
|
|
238
|
+
|
|
239
|
+
The module registers two aliases for convenient imports:
|
|
240
|
+
|
|
241
|
+
| Alias | Resolves To | Usage |
|
|
242
|
+
|-------|-------------|-------|
|
|
243
|
+
| `#introspection-types` | `<rootDir>/<generatedPath>` | `import { TypeOfXxx } from '#introspection-types'` |
|
|
244
|
+
| `#introspection-forms` | `@softwareproduction/introspection-forms` package | `import { withProps } from '#introspection-forms'` |
|
|
245
|
+
|
|
246
|
+
## Auto-Imports
|
|
247
|
+
|
|
248
|
+
These are available globally without manual imports:
|
|
249
|
+
|
|
250
|
+
| Import | Source | Description |
|
|
251
|
+
|--------|--------|-------------|
|
|
252
|
+
| `useIntrospectionForm` | `@softwareproduction/introspection-forms` | Create a form runtime |
|
|
253
|
+
| `useIntrospectionFormsEnumFilter` | `@softwareproduction/introspection-forms` | Access enum filters |
|
|
254
|
+
|
|
255
|
+
Components registered globally:
|
|
256
|
+
|
|
257
|
+
| Component | Description |
|
|
258
|
+
|-----------|-------------|
|
|
259
|
+
| `<IntrospectionForm>` | Top-level form renderer |
|
|
260
|
+
| `<IntrospectionField>` | Individual field renderer |
|
|
261
|
+
|
|
262
|
+
## Validation with Dryv
|
|
263
|
+
|
|
264
|
+
The module integrates with [Dryv](https://github.com/mhusseini/dryvjs) for client-side validation. Pass a `DryvValidationRuleSet` to `useIntrospectionForm` and use `v-model:validate` to receive the validate command from the component:
|
|
265
|
+
|
|
266
|
+
```vue
|
|
267
|
+
<script setup lang="ts">
|
|
268
|
+
import { TypeOfContactFormInput } from '#introspection-types'
|
|
269
|
+
import { ContactFormValidationSet } from '#validation'
|
|
270
|
+
|
|
271
|
+
const data = ref(TypeOfContactFormInput.create())
|
|
272
|
+
const validate = ref<(checkOnly?: boolean) => Promise<boolean>>()
|
|
273
|
+
|
|
274
|
+
const form = useIntrospectionForm(
|
|
275
|
+
TypeOfContactFormInput,
|
|
276
|
+
ContactFormValidationSet,
|
|
277
|
+
{
|
|
278
|
+
firstName: true,
|
|
279
|
+
lastName: true,
|
|
280
|
+
email: true,
|
|
281
|
+
},
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
async function submit() {
|
|
285
|
+
const success = await validate.value?.()
|
|
286
|
+
if (!success) return
|
|
287
|
+
await $fetch('/api/submit', { method: 'POST', body: data.value })
|
|
288
|
+
}
|
|
289
|
+
</script>
|
|
290
|
+
|
|
291
|
+
<template>
|
|
292
|
+
<IntrospectionForm :form="form" :model="data" v-model:validate="validate">
|
|
293
|
+
<button @click.prevent="submit">Submit</button>
|
|
294
|
+
</IntrospectionForm>
|
|
295
|
+
</template>
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
The component internally creates a Dryv validation session when rules are provided and exposes the `validate` function via `v-model:validate`. Validation errors appear inline beneath each field automatically.
|
|
299
|
+
|
|
300
|
+
## Advanced Configuration
|
|
301
|
+
|
|
302
|
+
### Multiple Form Configs (Spread Pattern)
|
|
303
|
+
|
|
304
|
+
Break large forms into logical groups:
|
|
305
|
+
|
|
306
|
+
```ts
|
|
307
|
+
const personalFields = { firstName: true, lastName: true, dateOfBirth: true }
|
|
308
|
+
const contactFields = { email: true, phone: true, preferredContact: true }
|
|
309
|
+
const consentFields = { acceptTerms: { span: 2 }, acceptNewsletter: { span: 2 } }
|
|
310
|
+
|
|
311
|
+
const form = useIntrospectionForm(TypeOfRegistrationFormInput, {
|
|
312
|
+
...personalFields,
|
|
313
|
+
...contactFields,
|
|
314
|
+
...consentFields,
|
|
315
|
+
})
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Form-Level Visibility and Disabled
|
|
319
|
+
|
|
320
|
+
```ts
|
|
321
|
+
const form = useIntrospectionForm({
|
|
322
|
+
introspection: TypeOfPaymentInput,
|
|
323
|
+
config: { cardNumber: true, cvv: true, expiryDate: true },
|
|
324
|
+
visible: model => model.paymentMethod === 'creditCard',
|
|
325
|
+
disabled: model => model.isProcessing,
|
|
326
|
+
})
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Storage Persistence per Form
|
|
330
|
+
|
|
331
|
+
```vue
|
|
332
|
+
<IntrospectionForm
|
|
333
|
+
:form="form"
|
|
334
|
+
:model="data"
|
|
335
|
+
storage="session"
|
|
336
|
+
:interceptStorage="(stored) => ({ ...stored, acceptTerms: false })"
|
|
337
|
+
>
|
|
338
|
+
...
|
|
339
|
+
</IntrospectionForm>
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
## License
|
|
343
|
+
|
|
344
|
+
MIT
|
package/dist/module.cjs
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
+
|
|
3
|
+
interface ModuleOptions {
|
|
4
|
+
/**
|
|
5
|
+
* The folder where the generated introspection types are located (relative to rootDir).
|
|
6
|
+
* @default 'types/generated/introspection'
|
|
7
|
+
*/
|
|
8
|
+
generatedPath?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Component mapping configuration for automatic field resolution.
|
|
11
|
+
* Configure which Vue components render which field types.
|
|
12
|
+
*/
|
|
13
|
+
defaults?: {
|
|
14
|
+
/** Map field TypeScript types (string, number, boolean, enum) to component configs. */
|
|
15
|
+
byFieldType?: Record<string, unknown>;
|
|
16
|
+
/** Map original GraphQL types (DateTime, etc.) to component configs. */
|
|
17
|
+
byOriginalType?: Record<string, unknown>;
|
|
18
|
+
/** Match field names by regex to component configs. */
|
|
19
|
+
byFieldName?: {
|
|
20
|
+
regexp: RegExp;
|
|
21
|
+
config: unknown;
|
|
22
|
+
}[];
|
|
23
|
+
/** Filter enum values by original type name. */
|
|
24
|
+
enumFilters?: Record<string, (values: string[]) => string[]>;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
28
|
+
|
|
29
|
+
export { _default as default };
|
|
30
|
+
export type { ModuleOptions };
|
package/dist/module.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
+
|
|
3
|
+
interface ModuleOptions {
|
|
4
|
+
/**
|
|
5
|
+
* The folder where the generated introspection types are located (relative to rootDir).
|
|
6
|
+
* @default 'types/generated/introspection'
|
|
7
|
+
*/
|
|
8
|
+
generatedPath?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Component mapping configuration for automatic field resolution.
|
|
11
|
+
* Configure which Vue components render which field types.
|
|
12
|
+
*/
|
|
13
|
+
defaults?: {
|
|
14
|
+
/** Map field TypeScript types (string, number, boolean, enum) to component configs. */
|
|
15
|
+
byFieldType?: Record<string, unknown>;
|
|
16
|
+
/** Map original GraphQL types (DateTime, etc.) to component configs. */
|
|
17
|
+
byOriginalType?: Record<string, unknown>;
|
|
18
|
+
/** Match field names by regex to component configs. */
|
|
19
|
+
byFieldName?: {
|
|
20
|
+
regexp: RegExp;
|
|
21
|
+
config: unknown;
|
|
22
|
+
}[];
|
|
23
|
+
/** Filter enum values by original type name. */
|
|
24
|
+
enumFilters?: Record<string, (values: string[]) => string[]>;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
28
|
+
|
|
29
|
+
export { _default as default };
|
|
30
|
+
export type { ModuleOptions };
|
package/dist/module.json
ADDED
package/dist/module.mjs
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { defineNuxtModule, createResolver, addComponent, addImportsDir, addPlugin } from '@nuxt/kit';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
|
|
4
|
+
const module = defineNuxtModule({
|
|
5
|
+
meta: {
|
|
6
|
+
name: "@softwareproduction/nuxt-introspection-forms",
|
|
7
|
+
configKey: "introspectionForms",
|
|
8
|
+
compatibility: {
|
|
9
|
+
nuxt: "^3.16.0 || ^4.0.0"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
defaults: {
|
|
13
|
+
generatedPath: "types/generated/introspection"
|
|
14
|
+
},
|
|
15
|
+
setup(options, nuxt) {
|
|
16
|
+
const resolver = createResolver(import.meta.url);
|
|
17
|
+
addComponent({
|
|
18
|
+
name: "IntrospectionForm",
|
|
19
|
+
filePath: "@softwareproduction/introspection-forms",
|
|
20
|
+
export: "IntrospectionForm"
|
|
21
|
+
});
|
|
22
|
+
addComponent({
|
|
23
|
+
name: "IntrospectionField",
|
|
24
|
+
filePath: "@softwareproduction/introspection-forms",
|
|
25
|
+
export: "IntrospectionField"
|
|
26
|
+
});
|
|
27
|
+
nuxt.options.alias["#introspection-types"] = join(nuxt.options.rootDir, options.generatedPath);
|
|
28
|
+
nuxt.options.alias["#introspection-forms"] = "@softwareproduction/introspection-forms";
|
|
29
|
+
addImportsDir(resolver.resolve("./runtime/composables"));
|
|
30
|
+
addPlugin({
|
|
31
|
+
src: resolver.resolve("./runtime/plugins/introspection-forms.client"),
|
|
32
|
+
mode: "all"
|
|
33
|
+
});
|
|
34
|
+
nuxt.options.runtimeConfig.public = nuxt.options.runtimeConfig.public || {};
|
|
35
|
+
nuxt.options.runtimeConfig.__introspectionFormsDefaults = options.defaults ? JSON.parse(JSON.stringify(options.defaults, (_key, value) => {
|
|
36
|
+
if (value instanceof RegExp)
|
|
37
|
+
return `__REGEXP__${value.source}__FLAGS__${value.flags}`;
|
|
38
|
+
if (typeof value === "function")
|
|
39
|
+
return `__FUNCTION__${value.toString()}`;
|
|
40
|
+
return value;
|
|
41
|
+
})) : void 0;
|
|
42
|
+
nuxt.options.appConfig = nuxt.options.appConfig || {};
|
|
43
|
+
nuxt.options.appConfig.introspectionForms = {
|
|
44
|
+
hasDefaults: !!options.defaults
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export { module as default };
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useIntrospectionForm } from "@softwareproduction/introspection-forms";
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useIntrospectionFormsEnumFilter } from "@softwareproduction/introspection-forms";
|
|
File without changes
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { defineNuxtPlugin } from "#app";
|
|
2
|
+
import { INTROSPECTION_FORMS_KEY } from "@softwareproduction/introspection-forms";
|
|
3
|
+
export default defineNuxtPlugin({
|
|
4
|
+
name: "introspection-forms",
|
|
5
|
+
setup(nuxtApp) {
|
|
6
|
+
const existingDefaults = nuxtApp.$introspectionForms;
|
|
7
|
+
if (existingDefaults) {
|
|
8
|
+
nuxtApp.vueApp.provide(INTROSPECTION_FORMS_KEY, existingDefaults);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
});
|
package/dist/types.d.mts
ADDED
package/dist/types.d.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@softwareproduction/nuxt-introspection-forms",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Nuxt module for introspection-forms — schema-driven form generation from GraphQL",
|
|
5
|
+
"author": "Munir Husseini (https://github.com/mhusseini)",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/mhusseini/introspection-forms.git",
|
|
10
|
+
"directory": "packages/nuxt-introspection-forms"
|
|
11
|
+
},
|
|
12
|
+
"type": "module",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/types.d.ts",
|
|
16
|
+
"import": "./dist/module.mjs"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"main": "./dist/module.mjs",
|
|
20
|
+
"types": "./dist/types.d.ts",
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "nuxt-module-build build",
|
|
26
|
+
"dev": "nuxt-module-build build --watch",
|
|
27
|
+
"typecheck": "tsc --noEmit"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@nuxt/kit": "^3.16.0",
|
|
31
|
+
"@softwareproduction/introspection-forms": "0.1.0"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"nuxt": "^3.16.0 || ^4.0.0",
|
|
35
|
+
"vue": "^3.4.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@nuxt/module-builder": "^0.8.0",
|
|
39
|
+
"nuxt": "^3.16.0",
|
|
40
|
+
"typescript": "^5.7.0",
|
|
41
|
+
"vue": "^3.5.0"
|
|
42
|
+
}
|
|
43
|
+
}
|