@@ -24,37 +24,53 @@ export async function generateTpcContent(input: TpcDescriptor) {
24
24
'import { withQuery } from \'ufo\'' ,
25
25
'import { useRegistryScript } from \'#nuxt-scripts-utils\'' ,
26
26
'import type { RegistryScriptInput } from \'#nuxt-scripts\'' ,
27
- `import type { ${ input . tpcTypeImport } } from 'third-party-capital'` ,
28
27
] )
28
+ const tpcTypes = new Set < string > ( )
29
29
30
30
const chunks : string [ ] = [ ]
31
31
const functionBody : string [ ] = [ ]
32
32
33
+ if ( input . tpcTypeAugmentation ) {
34
+ tpcTypes . add ( input . tpcTypeAugmentation )
35
+
36
+ chunks . push ( `
37
+ declare global {
38
+ interface Window extends ${ input . tpcTypeAugmentation } {}
39
+ }` )
40
+ }
41
+
42
+ if ( input . tpcTypesImport ) {
43
+ for ( const typeImport of input . tpcTypesImport ) {
44
+ tpcTypes . add ( typeImport )
45
+ }
46
+ }
47
+
48
+ if ( tpcTypes . size ) {
49
+ imports . add ( genImport ( 'third-party-capital' , [ ...tpcTypes ] ) )
50
+ }
51
+
33
52
if ( input . defaultOptions ) {
34
53
imports . add ( genImport ( 'defu' , [ 'defu' ] ) )
35
54
functionBody . push ( `_options = defu(_options, ${ JSON . stringify ( input . defaultOptions ) } )` )
36
55
}
37
56
38
57
const params = [ ...new Set ( input . tpcData . scripts ?. map ( s => s . params || [ ] ) . flat ( ) || [ ] ) ]
58
+ const optionalParams = [ ...new Set ( input . tpcData . scripts ?. map ( s => Object . keys ( s . optionalParams ) || [ ] ) . flat ( ) || [ ] ) ]
39
59
40
- if ( params . length ) {
60
+ if ( params . length || optionalParams . length ) {
41
61
const validatorImports = new Set < string > ( [ 'object' , 'string' ] )
62
+ if ( optionalParams . length ) {
63
+ validatorImports . add ( 'optional' )
64
+ }
65
+
66
+ const properties = params . filter ( p => ! optionalParams . includes ( p ) ) . map ( p => `${ p } : string()` ) . concat ( optionalParams . map ( o => `${ o } : optional(string())` ) )
42
67
// need schema validation from tpc
43
- chunks . push ( `export const ${ titleKey } Options = object({${ params . map ( ( p ) => {
44
- if ( input . defaultOptions && p in input . defaultOptions ) {
45
- validatorImports . add ( 'optional' )
46
- return `${ p } : optional(string())`
47
- }
48
- return `${ p } : string()`
49
- } ) } })`)
68
+ chunks . push ( `export const ${ titleKey } Options = object({
69
+ ${ properties . join ( ',\n' ) }
70
+ })` )
50
71
imports . add ( genImport ( '#nuxt-scripts-validator' , [ ...validatorImports ] ) )
51
72
}
52
73
53
- chunks . push ( `
54
- declare global {
55
- interface Window extends ${ input . tpcTypeImport } {}
56
- }` )
57
-
58
74
const clientInitCode : string [ ] = [ ]
59
75
60
76
if ( input . tpcData . stylesheets ) {
@@ -66,7 +82,7 @@ declare global {
66
82
67
83
for ( const script of input . tpcData . scripts ) {
68
84
if ( 'code' in script )
69
- clientInitCode . push ( replaceTokenToRuntime ( script . code ) )
85
+ clientInitCode . push ( replaceTokenToRuntime ( script . code , script . optionalParams ) )
70
86
71
87
if ( script === mainScript )
72
88
continue
@@ -78,21 +94,33 @@ declare global {
78
94
79
95
chunks . push ( `export type ${ titleKey } Input = RegistryScriptInput${ params . length ? `<typeof ${ titleKey } Options>` : '' } ` )
80
96
97
+ if ( input . useBody ) {
98
+ chunks . push ( `
99
+ function use(options: ${ titleKey } Input) {
100
+ ${ input . useBody }
101
+ }
102
+ ` )
103
+ }
104
+
105
+ const srcQueries = [ ...new Set < string > ( [ ...mainScript . params , ...Object . keys ( mainScript . optionalParams ) ] ) ] . map ( p => `${ p } : options?.${ p } ` )
106
+
81
107
chunks . push ( `
82
- export function ${ input . registry . import ! . name } <T extends ${ input . tpcTypeImport } > (_options?: ${ titleKey } Input) {
108
+ export function ${ input . registry . import ! . name } (_options?: ${ titleKey } Input) {
83
109
${ functionBody . join ( '\n' ) }
84
- return useRegistryScript${ params . length ? `<T, typeof ${ titleKey } Options> ` : '' } (_options?.key || '${ input . key } ', options => ({
110
+ return useRegistryScript< ${ input . useBody ? `ReturnType<typeof use>` : `Record<string | symbol, any>` } , ${ params . length ? ` typeof ${ titleKey } Options` : '' } > (_options?.key || '${ input . key } ', options => ({
85
111
scriptInput: {
86
- src: withQuery('${ mainScript . url } ', {${ mainScript . params ?. map ( p => ` ${ p } : options?. ${ p } ` ) } })
112
+ src: withQuery('${ mainScript . url } ', {${ srcQueries . join ( ', ' ) } }),
87
113
},
88
114
schema: import.meta.dev ? ${ titleKey } Options : undefined,
89
115
scriptOptions: {
90
- use: () => { return ${ input . returnUse } },
116
+ ${ input . useBody ? ` use: () => use(options),` : '' }
91
117
stub: import.meta.client ? undefined : ({fn}) => { return ${ input . returnStub } },
92
118
${ input . performanceMarkFeature ? `performanceMarkFeature: ${ JSON . stringify ( input . performanceMarkFeature ) } ,` : '' }
93
119
${ mainScriptOptions ? `...(${ JSON . stringify ( mainScriptOptions ) } )` : '' }
94
120
},
95
121
// eslint-disable-next-line
122
+ // @ts-ignore
123
+ // eslint-disable-next-line
96
124
${ clientInitCode . length ? `clientInit: import.meta.server ? undefined : () => {${ clientInitCode . join ( '\n' ) } },` : '' }
97
125
}), _options)
98
126
}` )
@@ -102,8 +130,10 @@ ${functionBody.join('\n')}
102
130
return chunks . join ( '\n' )
103
131
}
104
132
105
- function replaceTokenToRuntime ( code : string ) {
106
- return code . split ( ';' ) . map ( c => c . replaceAll ( / ' ? \{ \{ ( .* ?) \} \} ' ? / g, 'options.$1!' ) ) . join ( ';' )
133
+ function replaceTokenToRuntime ( code : string , defaultValues ?: Record < string , string | number | undefined > ) {
134
+ return code . split ( ';' ) . map ( c => c . replaceAll ( / ' ? \{ \{ ( .* ?) \} \} ' ? / g, ( _ , token ) => {
135
+ return `options?.${ token } ${ defaultValues ?. [ token ] ? `?? ${ JSON . stringify ( defaultValues ?. [ token ] ) } ` : '' } `
136
+ } ) ) . join ( ';' )
107
137
}
108
138
109
139
function getScriptInputOption ( script : Script ) : HeadEntryOptions | undefined {
0 commit comments