@nuxt/scripts 0.5.0 → 0.6.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 +2 -2
- package/dist/client/200.html +19 -16
- package/dist/client/404.html +19 -16
- package/dist/client/_nuxt/B474tPdy.js +66 -0
- package/dist/client/_nuxt/{DMNuDhJC.js → BN0jYG70.js} +1 -1
- package/dist/client/_nuxt/Buoqr_Oi.js +2 -0
- package/dist/client/_nuxt/C2pTd85Q.js +1 -0
- package/dist/client/_nuxt/{DCjyzNN-.js → D4FSFK-1.js} +1 -1
- package/dist/client/_nuxt/DAP_O-zg.js +1 -0
- package/dist/client/_nuxt/{o8H-iTt6.js → DG8tVHNj.js} +1 -1
- package/dist/client/_nuxt/DKGhHdqV.js +31 -0
- package/dist/client/_nuxt/DVC_qXWv.js +1 -0
- package/dist/client/_nuxt/{NL97_oaV.js → GPY1wEXZ.js} +1 -1
- package/dist/client/_nuxt/RyEv5ndP.js +1 -0
- package/dist/client/_nuxt/VQMr7AbF.js +1 -0
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/c409c2fe-d448-45a5-84ca-3e109a1e08ad.json +1 -0
- package/dist/client/_nuxt/cW9vKj3g.js +1 -0
- package/dist/client/_nuxt/entry.DvGwvmL9.css +1 -0
- package/dist/client/_nuxt/error-404.DXyehy0d.css +1 -0
- package/dist/client/_nuxt/error-500.a_92Fvyl.css +1 -0
- package/dist/client/index.html +19 -16
- package/dist/module.d.mts +3 -3
- package/dist/module.d.ts +3 -3
- package/dist/module.json +2 -2
- package/dist/module.mjs +191 -59
- package/dist/registry.mjs +15 -2
- package/dist/runtime/components/ScriptCarbonAds.vue +5 -4
- package/dist/runtime/components/ScriptCrisp.vue +84 -0
- package/dist/runtime/components/ScriptGoogleAdsense.vue +23 -4
- package/dist/runtime/components/ScriptGoogleMaps.vue +15 -14
- package/dist/runtime/components/ScriptIntercom.vue +93 -0
- package/dist/runtime/components/ScriptLemonSqueezy.vue +45 -0
- package/dist/runtime/components/ScriptLoadingIndicator.vue +12 -3
- package/dist/runtime/components/ScriptStripePricingTable.vue +30 -18
- package/dist/runtime/components/ScriptVimeoPlayer.vue +13 -3
- package/dist/runtime/components/ScriptYouTubePlayer.vue +13 -3
- package/dist/runtime/composables/useScript.js +6 -1
- package/dist/runtime/composables/useScriptEventPage.d.ts +5 -0
- package/dist/runtime/composables/{useAnalyticsPageEvent.js → useScriptEventPage.js} +1 -1
- package/dist/runtime/composables/{useConsentScriptTrigger.d.ts → useScriptTriggerConsent.d.ts} +1 -1
- package/dist/runtime/composables/{useConsentScriptTrigger.js → useScriptTriggerConsent.js} +1 -1
- package/dist/runtime/composables/{useElementScriptTrigger.d.ts → useScriptTriggerElement.d.ts} +1 -1
- package/dist/runtime/composables/{useElementScriptTrigger.js → useScriptTriggerElement.js} +5 -4
- package/dist/runtime/registry/crisp.d.ts +62 -0
- package/dist/runtime/registry/crisp.js +76 -0
- package/dist/runtime/registry/google-adsense.d.ts +1 -1
- package/dist/runtime/registry/intercom.d.ts +1 -1
- package/dist/runtime/registry/lemon-squeezy.d.ts +19 -12
- package/dist/runtime/registry/stripe.d.ts +0 -1
- package/dist/runtime/registry/vimeo-player.d.ts +1 -1
- package/dist/runtime/registry/youtube-player.d.ts +0 -1
- package/dist/runtime/types.d.ts +18 -8
- package/dist/runtime/utils.js +2 -1
- package/dist/types.d.mts +2 -10
- package/dist/types.d.ts +2 -10
- package/package.json +36 -28
- package/dist/client/_nuxt/Bn0B8vkx.js +0 -1
- package/dist/client/_nuxt/BvlfuC5v.js +0 -31
- package/dist/client/_nuxt/Bx89rGXK.js +0 -1
- package/dist/client/_nuxt/CoEqzGFw.js +0 -44
- package/dist/client/_nuxt/builds/meta/ba7f19ad-4701-4a37-b1b2-908f0cc701a8.json +0 -1
- package/dist/client/_nuxt/entry.8LvBfYHJ.css +0 -1
- package/dist/client/_nuxt/error-404.Dbi768NS.css +0 -1
- package/dist/client/_nuxt/error-500.C23YdqXl.css +0 -1
- package/dist/client/_nuxt/jmWmhCGR.js +0 -1
- package/dist/runtime/components/ScriptLemonSqueezyButton.vue +0 -41
- package/dist/runtime/composables/useAnalyticsPageEvent.d.ts +0 -2
package/dist/module.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { useNuxt, useLogger, addDevServerHandler, createResolver, addTemplate, tryUseNuxt, logger as logger$1, addImports, defineNuxtModule, addImportsDir, addComponentsDir, addPluginTemplate,
|
|
1
|
+
import { useNuxt, useLogger, addDevServerHandler, createResolver, addTemplate, tryUseNuxt, logger as logger$1, addImports, defineNuxtModule, addBuildPlugin, addImportsDir, addComponentsDir, addPluginTemplate, hasNuxtModule } from '@nuxt/kit';
|
|
2
2
|
import { resolvePackageJSON, readPackageJSON } from 'pkg-types';
|
|
3
3
|
import { lt } from 'semver';
|
|
4
4
|
import { resolvePath } from 'mlly';
|
|
5
|
-
import { join, relative } from 'pathe';
|
|
5
|
+
import { join, relative, extname } from 'pathe';
|
|
6
6
|
import { existsSync } from 'node:fs';
|
|
7
7
|
import { pathToFileURL } from 'node:url';
|
|
8
8
|
import { createUnplugin } from 'unplugin';
|
|
@@ -21,9 +21,12 @@ import { isCI, provider } from 'std-env';
|
|
|
21
21
|
import { registry } from './registry.mjs';
|
|
22
22
|
import { GooglaAnalyticsData, GoogleAnalytics, GoogleTagManagerData, GoogleTagManager } from 'third-party-capital';
|
|
23
23
|
import { genTypeImport, genImport } from 'knitwork';
|
|
24
|
+
import { parse } from 'acorn';
|
|
25
|
+
import { transform } from 'esbuild';
|
|
24
26
|
|
|
25
27
|
const DEVTOOLS_UI_ROUTE = "/__nuxt-scripts";
|
|
26
|
-
const DEVTOOLS_UI_LOCAL_PORT =
|
|
28
|
+
const DEVTOOLS_UI_LOCAL_PORT = 3300;
|
|
29
|
+
|
|
27
30
|
function setupDevToolsUI(options, resolve, nuxt = useNuxt()) {
|
|
28
31
|
const clientPath = resolve("./client");
|
|
29
32
|
const isProductionBuild = existsSync(clientPath);
|
|
@@ -87,7 +90,9 @@ function NuxtScriptBundleTransformer(options) {
|
|
|
87
90
|
walk(ast, {
|
|
88
91
|
enter(_node) {
|
|
89
92
|
const calleeName = _node.callee?.name;
|
|
90
|
-
|
|
93
|
+
if (!calleeName)
|
|
94
|
+
return;
|
|
95
|
+
const isValidCallee = calleeName === "useScript" || calleeName?.startsWith("useScript") && /^[A-Z]$/.test(calleeName?.charAt(9)) && !calleeName.startsWith("useScriptTrigger") && !calleeName.startsWith("useScriptEvent");
|
|
91
96
|
if (_node.type === "CallExpression" && _node.callee.type === "Identifier" && isValidCallee) {
|
|
92
97
|
const fnName = _node.callee?.name;
|
|
93
98
|
const node = _node;
|
|
@@ -357,6 +362,8 @@ function installNuxtModule(name, options) {
|
|
|
357
362
|
}, { rootDir: nuxt.options.rootDir, searchPaths: nuxt.options.modulesDir, ...options });
|
|
358
363
|
}
|
|
359
364
|
|
|
365
|
+
const HEAD_VAR = "__head";
|
|
366
|
+
const INJECTHEAD_CODE = `const ${HEAD_VAR} = injectHead()`;
|
|
360
367
|
function getTpcScriptContent(input) {
|
|
361
368
|
const nuxt = useNuxt();
|
|
362
369
|
if (!input.data.scripts)
|
|
@@ -364,6 +371,7 @@ function getTpcScriptContent(input) {
|
|
|
364
371
|
const mainScript = input.data.scripts?.find(({ key }) => key === input.tpcKey);
|
|
365
372
|
if (!mainScript)
|
|
366
373
|
throw new Error(`no main script found for ${input.tpcKey} in third-party-capital`);
|
|
374
|
+
const mainScriptOptions = getScriptInputOption(mainScript);
|
|
367
375
|
const imports = /* @__PURE__ */ new Set([
|
|
368
376
|
"import { withQuery } from 'ufo'",
|
|
369
377
|
"import { useRegistryScript } from '#nuxt-scripts-utils'",
|
|
@@ -379,37 +387,26 @@ function getTpcScriptContent(input) {
|
|
|
379
387
|
imports.add(genImport("#nuxt-scripts-validator", ["object", "any"]));
|
|
380
388
|
chunks.push(`const OptionSchema = object({${mainScript.params?.map((p) => `${p}: any()`)}})`);
|
|
381
389
|
}
|
|
382
|
-
|
|
383
|
-
chunks.push(`
|
|
390
|
+
chunks.push(`
|
|
384
391
|
declare global {
|
|
385
392
|
interface Window extends ${input.tpcTypeImport} {}
|
|
386
393
|
}`);
|
|
387
|
-
}
|
|
388
394
|
const clientInitCode = [];
|
|
389
|
-
const runtimeHead = {
|
|
390
|
-
script: [],
|
|
391
|
-
link: input.data.stylesheets?.map((s) => ({ ref: "stylesheet", href: s })) || []
|
|
392
|
-
};
|
|
393
395
|
if (input.data.stylesheets) {
|
|
394
|
-
|
|
396
|
+
if (!functionBody.includes(INJECTHEAD_CODE)) {
|
|
397
|
+
functionBody.unshift(INJECTHEAD_CODE);
|
|
398
|
+
}
|
|
399
|
+
functionBody.push(`${HEAD_VAR}.push({link: ${JSON.stringify(input.data.stylesheets.map((s) => ({ ref: "stylesheet", href: s })))}})`);
|
|
395
400
|
}
|
|
396
401
|
for (const script of input.data.scripts) {
|
|
397
402
|
if ("code" in script)
|
|
398
403
|
clientInitCode.push(replaceTokenToRuntime(script.code));
|
|
399
404
|
if (script === mainScript)
|
|
400
405
|
continue;
|
|
401
|
-
if ("url" in script
|
|
402
|
-
|
|
403
|
-
runtimeHead.script = [];
|
|
404
|
-
runtimeHead.script.push({
|
|
405
|
-
src: script.url,
|
|
406
|
-
async: true
|
|
407
|
-
});
|
|
406
|
+
if ("url" in script) {
|
|
407
|
+
functionBody.push(`${HEAD_VAR}.push({scripts:{ async: true, src: ${script.url} }},${JSON.stringify(getScriptInputOption(script))})`);
|
|
408
408
|
}
|
|
409
409
|
}
|
|
410
|
-
if (runtimeHead.script.length || runtimeHead.link.length) {
|
|
411
|
-
functionBody.push(`useHead(${JSON.stringify(runtimeHead)})`);
|
|
412
|
-
}
|
|
413
410
|
chunks.push(`export type Input = RegistryScriptInput${hasParams ? "<typeof OptionSchema>" : ""}`);
|
|
414
411
|
chunks.push(`
|
|
415
412
|
export function ${input.scriptFunctionName}<T extends ${input.tpcTypeImport}>(_options?: Input) {
|
|
@@ -421,7 +418,8 @@ ${functionBody.join("\n")}
|
|
|
421
418
|
${nuxt.options.dev ? "schema: OptionSchema," : ""}
|
|
422
419
|
scriptOptions: {
|
|
423
420
|
use: ${input.use.toString()},
|
|
424
|
-
stub: import.meta.client ? undefined : ${input.stub.toString()}
|
|
421
|
+
stub: import.meta.client ? undefined : ${input.stub.toString()},
|
|
422
|
+
${mainScriptOptions ? `...(${JSON.stringify(mainScriptOptions)})` : ""}
|
|
425
423
|
},
|
|
426
424
|
${clientInitCode.length ? `clientInit: import.meta.server ? undefined : () => {${clientInitCode.join("\n")}},` : ""}
|
|
427
425
|
}), _options)
|
|
@@ -432,6 +430,17 @@ ${functionBody.join("\n")}
|
|
|
432
430
|
function replaceTokenToRuntime(code) {
|
|
433
431
|
return code.split(";").map((c) => c.replaceAll(/'?\{\{(.*?)\}\}'?/g, "options.$1")).join(";");
|
|
434
432
|
}
|
|
433
|
+
function getScriptInputOption(script) {
|
|
434
|
+
if (script.location === "body") {
|
|
435
|
+
if (script.action === "append") {
|
|
436
|
+
return { tagPosition: "bodyClose" };
|
|
437
|
+
}
|
|
438
|
+
return { tagPosition: "bodyOpen" };
|
|
439
|
+
}
|
|
440
|
+
if (script.action === "append") {
|
|
441
|
+
return { tagPriority: 1 };
|
|
442
|
+
}
|
|
443
|
+
}
|
|
435
444
|
|
|
436
445
|
function googleAnalitycsRegistry() {
|
|
437
446
|
const nuxt = useNuxt();
|
|
@@ -448,11 +457,11 @@ function googleAnalitycsRegistry() {
|
|
|
448
457
|
return fn === "dataLayer" ? [] : void 0;
|
|
449
458
|
},
|
|
450
459
|
tpcKey: "gtag",
|
|
451
|
-
tpcTypeImport: "GoogleAnalyticsApi"
|
|
452
|
-
augmentWindowTypes: true
|
|
460
|
+
tpcTypeImport: "GoogleAnalyticsApi"
|
|
453
461
|
});
|
|
454
462
|
},
|
|
455
|
-
filename: "nuxt-scripts/tpc/google-analytics.ts"
|
|
463
|
+
filename: "nuxt-scripts/tpc/google-analytics.ts",
|
|
464
|
+
write: true
|
|
456
465
|
});
|
|
457
466
|
addImports({
|
|
458
467
|
from: dst,
|
|
@@ -493,11 +502,11 @@ function googleTagManagerRegistry() {
|
|
|
493
502
|
return fn === "dataLayer" ? [] : void 0;
|
|
494
503
|
},
|
|
495
504
|
tpcKey: "gtm",
|
|
496
|
-
tpcTypeImport: "GoogleTagManagerApi"
|
|
497
|
-
augmentWindowTypes: true
|
|
505
|
+
tpcTypeImport: "GoogleTagManagerApi"
|
|
498
506
|
});
|
|
499
507
|
},
|
|
500
|
-
filename: "nuxt-scripts/tpc/google-tag-manager.ts"
|
|
508
|
+
filename: "nuxt-scripts/tpc/google-tag-manager.ts",
|
|
509
|
+
write: true
|
|
501
510
|
});
|
|
502
511
|
addImports({
|
|
503
512
|
from: dst,
|
|
@@ -524,6 +533,142 @@ function googleTagManagerRegistry() {
|
|
|
524
533
|
});
|
|
525
534
|
}
|
|
526
535
|
|
|
536
|
+
const SCRIPT_RE = /<script[^>]*>([\s\S]*)<\/script>/;
|
|
537
|
+
const checkScripts = () => createUnplugin(() => {
|
|
538
|
+
return {
|
|
539
|
+
name: "nuxt-scripts:check-scripts",
|
|
540
|
+
enforce: "pre",
|
|
541
|
+
async transform(code, id) {
|
|
542
|
+
if (!code.includes("useScript"))
|
|
543
|
+
return;
|
|
544
|
+
const extName = extname(id);
|
|
545
|
+
if (extName === ".vue") {
|
|
546
|
+
const scriptAst = await extractScriptContentAst(code);
|
|
547
|
+
if (scriptAst) {
|
|
548
|
+
analyzeNodes(id, scriptAst);
|
|
549
|
+
}
|
|
550
|
+
} else if (extName === ".ts" || extName === ".js") {
|
|
551
|
+
if (!code.includes("defineComponent"))
|
|
552
|
+
return;
|
|
553
|
+
let result = code;
|
|
554
|
+
if (extName === ".ts") {
|
|
555
|
+
result = (await transform(code, { loader: "ts" })).code;
|
|
556
|
+
}
|
|
557
|
+
const setupFunction = extractSetupFunction(result);
|
|
558
|
+
if (setupFunction) {
|
|
559
|
+
analyzeNodes(id, setupFunction);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return void 0;
|
|
563
|
+
}
|
|
564
|
+
};
|
|
565
|
+
});
|
|
566
|
+
function analyzeNodes(id, nodes) {
|
|
567
|
+
let name;
|
|
568
|
+
for (const node of nodes) {
|
|
569
|
+
if (name) {
|
|
570
|
+
if (isAwaitingLoad(name, node)) {
|
|
571
|
+
throw new Error("Awaiting load should not be used at top level of a composable or <script>");
|
|
572
|
+
}
|
|
573
|
+
} else {
|
|
574
|
+
if (node.type === "VariableDeclaration") {
|
|
575
|
+
name = findScriptVar(node.declarations[0]);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
function findScriptVar(scriptDeclaration) {
|
|
581
|
+
if (scriptDeclaration.id.type === "ObjectPattern") {
|
|
582
|
+
for (const property of scriptDeclaration.id.properties) {
|
|
583
|
+
if (property.type === "Property" && property.key.type === "Identifier" && property.key.name === "$script" && property.value.type === "Identifier") {
|
|
584
|
+
return property.value.name;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
} else if (scriptDeclaration.id.type === "Identifier") {
|
|
588
|
+
return scriptDeclaration.id.name;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
function isAwaitingLoad(name, node) {
|
|
592
|
+
if (node.type === "ExpressionStatement" && node.expression.type === "AwaitExpression") {
|
|
593
|
+
const arg = node.expression.argument;
|
|
594
|
+
if (arg.type === "CallExpression") {
|
|
595
|
+
const callee = arg.callee;
|
|
596
|
+
if (callee.type === "MemberExpression" && callee.object.type === "Identifier" && callee.object.name === name) {
|
|
597
|
+
if (callee.property.type === "Identifier" && callee.property.name === "load") {
|
|
598
|
+
return true;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
async function extractScriptContentAst(code) {
|
|
605
|
+
const scriptCode = code.match(SCRIPT_RE);
|
|
606
|
+
return scriptCode ? parse((await transform(scriptCode[1], { loader: "ts" })).code, {
|
|
607
|
+
ecmaVersion: "latest",
|
|
608
|
+
sourceType: "module"
|
|
609
|
+
}).body : void 0;
|
|
610
|
+
}
|
|
611
|
+
function extractSetupFunction(code) {
|
|
612
|
+
const ast = parse(code, {
|
|
613
|
+
ecmaVersion: "latest",
|
|
614
|
+
sourceType: "module"
|
|
615
|
+
});
|
|
616
|
+
const defaultExport = ast.body.find((node) => node.type === "ExportDefaultDeclaration");
|
|
617
|
+
if (defaultExport && defaultExport.declaration.type === "CallExpression" && defaultExport.declaration.callee.type === "Identifier" && defaultExport.declaration.callee.name === "defineComponent") {
|
|
618
|
+
const arg = defaultExport.declaration.arguments[0];
|
|
619
|
+
if (arg && arg.type === "ObjectExpression") {
|
|
620
|
+
const setupProperty = arg.properties.find((prop) => prop.type === "Property" && prop.key.type === "Identifier" && prop.key.name === "setup");
|
|
621
|
+
if (setupProperty) {
|
|
622
|
+
const setupValue = setupProperty.value;
|
|
623
|
+
if (setupValue.type === "FunctionExpression") {
|
|
624
|
+
return setupValue.body.body;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
function templatePlugin(config, registry) {
|
|
632
|
+
if (Array.isArray(config.globals)) {
|
|
633
|
+
config.globals = Object.fromEntries(config.globals.map((i) => [hash(i), i]));
|
|
634
|
+
logger.warn("The `globals` array option is deprecated, please convert to an object.");
|
|
635
|
+
}
|
|
636
|
+
const imports = ["useScript", "defineNuxtPlugin"];
|
|
637
|
+
const inits = [];
|
|
638
|
+
for (const [k, c] of Object.entries(config.registry || {})) {
|
|
639
|
+
const importDefinition = registry.find((i) => i.import.name === `useScript${k.substring(0, 1).toUpperCase() + k.substring(1)}`);
|
|
640
|
+
if (importDefinition) {
|
|
641
|
+
imports.unshift(importDefinition.import.name);
|
|
642
|
+
const args = (typeof c !== "object" ? {} : c) || {};
|
|
643
|
+
if (c === "mock")
|
|
644
|
+
args.scriptOptions = { trigger: "manual", skipValidation: true };
|
|
645
|
+
inits.push(`const ${k} = ${importDefinition.import.name}(${JSON.stringify(args)})`);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
for (const [k, c] of Object.entries(config.globals || {})) {
|
|
649
|
+
if (typeof c === "string") {
|
|
650
|
+
inits.push(`const ${k} = useScript(${JSON.stringify({ src: c, key: k })}, { use: () => ({ ${k}: window.${k} }) })`);
|
|
651
|
+
} else if (Array.isArray(c) && c.length === 2) {
|
|
652
|
+
inits.push(`const ${k} = useScript(${JSON.stringify({ key: k, ...typeof c[0] === "string" ? { src: c[0] } : c[0] })}, { ...${JSON.stringify(c[1])}, use: () => ({ ${k}: window.${k} } }) )`);
|
|
653
|
+
} else {
|
|
654
|
+
inits.push(`const ${k} = useScript(${JSON.stringify({ key: k, ...c })}, { use: () => ({ ${k}: window.${k} }) })`);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
return [
|
|
658
|
+
`import { ${imports.join(", ")} } from '#imports'`,
|
|
659
|
+
"",
|
|
660
|
+
`export default defineNuxtPlugin({`,
|
|
661
|
+
` name: "scripts:init",`,
|
|
662
|
+
` env: { islands: false },`,
|
|
663
|
+
` parallel: true,`,
|
|
664
|
+
` setup() {`,
|
|
665
|
+
...inits.map((i) => ` ${i}`),
|
|
666
|
+
` return { provide: { $scripts: { ${[...Object.keys(config.globals || {}), ...Object.keys(config.registry || {})].join(", ")} } } }`,
|
|
667
|
+
` }`,
|
|
668
|
+
`})`
|
|
669
|
+
].join("\n");
|
|
670
|
+
}
|
|
671
|
+
|
|
527
672
|
const module = defineNuxtModule({
|
|
528
673
|
meta: {
|
|
529
674
|
name: "@nuxt/scripts",
|
|
@@ -543,6 +688,10 @@ const module = defineNuxtModule({
|
|
|
543
688
|
async setup(config, nuxt) {
|
|
544
689
|
const { resolve } = createResolver(import.meta.url);
|
|
545
690
|
const { version, name } = await readPackageJSON(resolve("../package.json"));
|
|
691
|
+
if (!config.enabled) {
|
|
692
|
+
logger.debug("The module is disabled, skipping setup.");
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
546
695
|
const unheadPath = await resolvePath("@unhead/vue").catch(() => void 0);
|
|
547
696
|
if (unheadPath) {
|
|
548
697
|
const { version: unheadVersion } = await readPackageJSON(join(unheadPath, "package.json"));
|
|
@@ -551,15 +700,16 @@ const module = defineNuxtModule({
|
|
|
551
700
|
return;
|
|
552
701
|
}
|
|
553
702
|
}
|
|
554
|
-
|
|
555
|
-
logger.debug("The module is disabled, skipping setup.");
|
|
556
|
-
return;
|
|
557
|
-
}
|
|
703
|
+
addBuildPlugin(checkScripts());
|
|
558
704
|
nuxt.options.alias["#nuxt-scripts-validator"] = resolve(`./runtime/validation/${nuxt.options.dev || nuxt.options._prepare ? "valibot" : "mock"}`);
|
|
559
705
|
nuxt.options.alias["#nuxt-scripts"] = resolve("./runtime/types");
|
|
560
706
|
nuxt.options.alias["#nuxt-scripts-utils"] = resolve("./runtime/utils");
|
|
561
707
|
nuxt.options.runtimeConfig["nuxt-scripts"] = { version };
|
|
562
|
-
nuxt.options.runtimeConfig.public["nuxt-scripts"] = {
|
|
708
|
+
nuxt.options.runtimeConfig.public["nuxt-scripts"] = {
|
|
709
|
+
// expose for devtools
|
|
710
|
+
version: nuxt.options.dev ? version : void 0,
|
|
711
|
+
defaultScriptOptions: config.defaultScriptOptions
|
|
712
|
+
};
|
|
563
713
|
addImportsDir([
|
|
564
714
|
resolve("./runtime/composables"),
|
|
565
715
|
// auto-imports aren't working without this for some reason
|
|
@@ -575,18 +725,19 @@ const module = defineNuxtModule({
|
|
|
575
725
|
nuxt.hooks.hook("modules:done", async () => {
|
|
576
726
|
const registryScripts = [...scripts];
|
|
577
727
|
await nuxt.hooks.callHook("scripts:registry", registryScripts);
|
|
578
|
-
const
|
|
579
|
-
addImports(
|
|
728
|
+
const registryScriptsWithImport = registryScripts.filter((i) => !!i.import?.name);
|
|
729
|
+
addImports(registryScriptsWithImport.map((i) => {
|
|
580
730
|
return {
|
|
581
731
|
priority: -1,
|
|
582
732
|
...i.import
|
|
583
733
|
};
|
|
584
734
|
}));
|
|
585
|
-
const newScripts =
|
|
735
|
+
const newScripts = registryScriptsWithImport.filter((i) => !scripts.some((r) => r.import?.name === i.import.name));
|
|
586
736
|
extendTypes(name, async ({ typesPath }) => {
|
|
587
737
|
let types = `
|
|
588
738
|
declare module '#app' {
|
|
589
739
|
interface NuxtApp {
|
|
740
|
+
$scripts: Record<${[...Object.keys(config.globals || {}), ...Object.keys(config.registry || {})].map((k) => `'${k}'`).concat(["string"]).join(" | ")}, Pick<(import('#nuxt-scripts').NuxtAppScript), '$script'> & Record<string, any>>
|
|
590
741
|
_scripts: Record<string, (import('#nuxt-scripts').NuxtAppScript)>
|
|
591
742
|
}
|
|
592
743
|
interface RuntimeNuxtHooks {
|
|
@@ -610,30 +761,11 @@ ${newScripts.map((i) => {
|
|
|
610
761
|
}
|
|
611
762
|
return types;
|
|
612
763
|
});
|
|
613
|
-
if (config.globals
|
|
764
|
+
if (Object.keys(config.globals || {}).length || Object.keys(config.registry || {}).length) {
|
|
614
765
|
addPluginTemplate({
|
|
615
766
|
filename: `modules/${name.replace("/", "-")}.mjs`,
|
|
616
767
|
getContents() {
|
|
617
|
-
|
|
618
|
-
const inits = [];
|
|
619
|
-
for (const [k, c] of Object.entries(config.registry || {})) {
|
|
620
|
-
const importDefinition = withComposables.find((i) => i.import.name === `useScript${k.substring(0, 1).toUpperCase() + k.substring(1)}`);
|
|
621
|
-
if (importDefinition) {
|
|
622
|
-
imports.unshift(importDefinition.import.name);
|
|
623
|
-
const args = (typeof c !== "object" ? {} : c) || {};
|
|
624
|
-
if (c === "mock")
|
|
625
|
-
args.scriptOptions = { trigger: "manual", skipValidation: true };
|
|
626
|
-
inits.push(`${importDefinition.import.name}(${JSON.stringify(args)});`);
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
return `import { ${imports.join(", ")} } from '#imports'
|
|
630
|
-
export default defineNuxtPlugin({
|
|
631
|
-
name: "${name}:init",
|
|
632
|
-
setup() {
|
|
633
|
-
${(config.globals || []).map((g) => !Array.isArray(g) ? ` useScript("${g.toString()}")` : g.length === 2 ? ` useScript(${JSON.stringify(g[0])}, ${JSON.stringify(g[1])} })` : ` useScript(${JSON.stringify(g[0])})`).join("\n")}
|
|
634
|
-
${inits.join("\n ")}
|
|
635
|
-
}
|
|
636
|
-
})`;
|
|
768
|
+
return templatePlugin(config, registryScriptsWithImport);
|
|
637
769
|
}
|
|
638
770
|
});
|
|
639
771
|
}
|
|
@@ -641,7 +773,7 @@ ${(config.globals || []).map((g) => !Array.isArray(g) ? ` useScript("${g.toSt
|
|
|
641
773
|
const { normalizeScriptData } = setupPublicAssetStrategy(config.assets);
|
|
642
774
|
const moduleInstallPromises = /* @__PURE__ */ new Map();
|
|
643
775
|
addBuildPlugin(NuxtScriptBundleTransformer({
|
|
644
|
-
scripts:
|
|
776
|
+
scripts: registryScriptsWithImport,
|
|
645
777
|
defaultBundle: config.defaultScriptOptions?.bundle,
|
|
646
778
|
moduleDetected(module) {
|
|
647
779
|
if (nuxt.options.dev && module !== "@nuxt/scripts" && !moduleInstallPromises.has(module) && !hasNuxtModule(module))
|
package/dist/registry.mjs
CHANGED
|
@@ -110,8 +110,8 @@ const registry = (resolve) => {
|
|
|
110
110
|
scriptBundling(options) {
|
|
111
111
|
return joinURL(`https://widget.intercom.io/widget`, options?.app_id || "");
|
|
112
112
|
},
|
|
113
|
-
logo: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8.968 8.972"
|
|
114
|
-
category: "
|
|
113
|
+
logo: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8.968 8.972"><path d="M7.853 0h-6.73C.496 0-.002.498-.002 1.117v6.73a1.12 1.12 0 0 0 1.126 1.126h6.73c.618 0 1.117-.498 1.117-1.117v-6.73A1.119 1.119 0 0 0 7.853 0zM5.68 1.645c0-.17.13-.3.3-.3s.3.13.3.3v3.998c0 .17-.13.3-.3.3s-.3-.13-.3-.3zm-1.495-.15c0-.17.13-.3.3-.3s.3.13.3.3v4.336c0 .17-.13.3-.3.3s-.3-.13-.3-.3zm-1.495.15c0-.17.13-.3.3-.3s.3.13.3.3v3.998c0 .17-.13.3-.3.3s-.3-.13-.3-.3zm-1.495.598c0-.17.13-.3.3-.3s.3.13.3.3v2.692c0 .17-.13.3-.3.3s-.3-.13-.3-.3zm6.48 4.566c-.05.04-1.156.967-3.2.967s-3.14-.927-3.2-.967a.29.29 0 0 1-.03-.419.29.29 0 0 1 .419-.03c.02 0 1.007.817 2.8.817 1.814 0 2.79-.817 2.79-.827.13-.1.32-.1.42.03a.3.3 0 0 1-.02.429zm.1-1.874c0 .17-.13.3-.3.3s-.3-.13-.3-.3V2.243c0-.17.13-.3.3-.3s.3.13.3.3z" fill="#1f8ded"/></svg>`,
|
|
114
|
+
category: "support",
|
|
115
115
|
import: {
|
|
116
116
|
name: "useScriptIntercom",
|
|
117
117
|
from: resolve("./runtime/registry/intercom")
|
|
@@ -193,6 +193,19 @@ const registry = (resolve) => {
|
|
|
193
193
|
from: resolve("./runtime/registry/google-maps")
|
|
194
194
|
}
|
|
195
195
|
},
|
|
196
|
+
// chat
|
|
197
|
+
{
|
|
198
|
+
label: "Crisp",
|
|
199
|
+
category: "support",
|
|
200
|
+
logo: {
|
|
201
|
+
light: `<svg height="30" width="35" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><filter id="a" height="138.7%" width="131.4%" x="-15.7%" y="-15.1%"><feMorphology in="SourceAlpha" operator="dilate" radius="1" result="shadowSpreadOuter1"/><feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1"/><feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1"/><feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/><feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.07 0"/></filter><path id="b" d="M14.23 20.46l-9.65 1.1L3 5.12 30.07 2l1.58 16.46-9.37 1.07-3.5 5.72-4.55-4.8z"/></defs><g fill="none" fill-rule="evenodd"><use fill="#000" filter="url(#a)" xlink:href="#b"/><use fill="#1972f5" stroke="#1972f5" stroke-width="2" xlink:href="#b"/></g></svg>`,
|
|
202
|
+
dark: `<svg height="30" width="35" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><filter id="a" height="138.7%" width="131.4%" x="-15.7%" y="-15.1%"><feMorphology in="SourceAlpha" operator="dilate" radius="1" result="shadowSpreadOuter1"/><feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1"/><feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1"/><feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/><feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.07 0"/></filter><path id="b" d="M14.23 20.46l-9.65 1.1L3 5.12 30.07 2l1.58 16.46-9.37 1.07-3.5 5.72-4.55-4.8z"/></defs><g fill="none" fill-rule="evenodd"><use fill="#000" filter="url(#a)" xlink:href="#b"/><use fill="#fff" stroke="#fff" stroke-width="2" xlink:href="#b"/></g></svg>`
|
|
203
|
+
},
|
|
204
|
+
import: {
|
|
205
|
+
name: "useScriptCrisp",
|
|
206
|
+
from: resolve("./runtime/registry/crisp")
|
|
207
|
+
}
|
|
208
|
+
},
|
|
196
209
|
// other
|
|
197
210
|
{
|
|
198
211
|
label: "NPM",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { withQuery } from 'ufo'
|
|
3
|
-
import {
|
|
3
|
+
import { useScriptTriggerElement } from '../composables/useScriptTriggerElement'
|
|
4
|
+
import { onBeforeUnmount, onMounted, ref } from '#imports'
|
|
4
5
|
import type { ElementScriptTrigger } from '#nuxt-scripts'
|
|
5
6
|
|
|
6
7
|
const props = defineProps<{
|
|
@@ -14,7 +15,7 @@ const props = defineProps<{
|
|
|
14
15
|
|
|
15
16
|
const emit = defineEmits<{
|
|
16
17
|
error: [error: string | Event]
|
|
17
|
-
|
|
18
|
+
ready: [HTMLScriptElement]
|
|
18
19
|
}>()
|
|
19
20
|
|
|
20
21
|
const attrId = `_carbonads_js`
|
|
@@ -40,7 +41,7 @@ function loadCarbon() {
|
|
|
40
41
|
}
|
|
41
42
|
script.onload = () => {
|
|
42
43
|
status.value = 'loaded'
|
|
43
|
-
emit('
|
|
44
|
+
emit('ready', script)
|
|
44
45
|
}
|
|
45
46
|
carbonadsEl.value.appendChild(script)
|
|
46
47
|
}
|
|
@@ -50,7 +51,7 @@ onMounted(() => {
|
|
|
50
51
|
loadCarbon()
|
|
51
52
|
}
|
|
52
53
|
else {
|
|
53
|
-
|
|
54
|
+
useScriptTriggerElement({ trigger: props.trigger, el: carbonadsEl })
|
|
54
55
|
}
|
|
55
56
|
})
|
|
56
57
|
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useScriptTriggerElement } from '../composables/useScriptTriggerElement'
|
|
3
|
+
import { useScriptCrisp } from '../registry/crisp'
|
|
4
|
+
import { ref, onMounted, onBeforeUnmount, watch } from '#imports'
|
|
5
|
+
import type { ElementScriptTrigger } from '#nuxt-scripts'
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(defineProps<{
|
|
8
|
+
/**
|
|
9
|
+
* Defines the trigger event to load the script.
|
|
10
|
+
*/
|
|
11
|
+
trigger?: ElementScriptTrigger
|
|
12
|
+
id: string
|
|
13
|
+
runtimeConfig?: {
|
|
14
|
+
locale: string
|
|
15
|
+
}
|
|
16
|
+
tokenId?: string
|
|
17
|
+
cookieDomain?: string
|
|
18
|
+
cookieExpiry?: number
|
|
19
|
+
}>(), {
|
|
20
|
+
trigger: 'click',
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const emits = defineEmits<{
|
|
24
|
+
// our emit
|
|
25
|
+
ready: [e: ReturnType<typeof useScriptCrisp>]
|
|
26
|
+
error: []
|
|
27
|
+
}>()
|
|
28
|
+
|
|
29
|
+
const rootEl = ref(null)
|
|
30
|
+
const trigger = useScriptTriggerElement({ trigger: props.trigger, el: rootEl })
|
|
31
|
+
|
|
32
|
+
const isReady = ref(false)
|
|
33
|
+
const crisp = useScriptCrisp({
|
|
34
|
+
id: props.id,
|
|
35
|
+
runtimeConfig: props.runtimeConfig,
|
|
36
|
+
tokenId: props.tokenId,
|
|
37
|
+
cookieDomain: props.cookieDomain,
|
|
38
|
+
cookieExpiry: props.cookieExpiry,
|
|
39
|
+
scriptOptions: {
|
|
40
|
+
trigger,
|
|
41
|
+
},
|
|
42
|
+
})
|
|
43
|
+
if (props.trigger === 'click')
|
|
44
|
+
crisp.do('chat:open')
|
|
45
|
+
const { $script } = crisp
|
|
46
|
+
|
|
47
|
+
defineExpose({
|
|
48
|
+
crisp,
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
let observer: MutationObserver
|
|
52
|
+
onMounted(() => {
|
|
53
|
+
watch($script.status, (status) => {
|
|
54
|
+
if (status === 'loaded') {
|
|
55
|
+
observer = new MutationObserver(() => {
|
|
56
|
+
if (document.getElementById('crisp-chatbox')) {
|
|
57
|
+
isReady.value = true
|
|
58
|
+
emits('ready', crisp)
|
|
59
|
+
observer.disconnect()
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
observer.observe(document.body, { childList: true, subtree: true })
|
|
63
|
+
}
|
|
64
|
+
else if (status === 'error') {
|
|
65
|
+
emits('error')
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
onBeforeUnmount(() => {
|
|
70
|
+
observer?.disconnect()
|
|
71
|
+
})
|
|
72
|
+
</script>
|
|
73
|
+
|
|
74
|
+
<template>
|
|
75
|
+
<div
|
|
76
|
+
ref="rootEl"
|
|
77
|
+
:style="{ display: isReady ? 'none' : 'block' }"
|
|
78
|
+
>
|
|
79
|
+
<slot :ready="isReady" />
|
|
80
|
+
<slot v-if="$script.status.value === 'awaitingLoad'" name="awaitingLoad" />
|
|
81
|
+
<slot v-else-if="$script.status.value === 'loading' || !isReady" name="loading" />
|
|
82
|
+
<slot v-else-if="$script.status.value === 'error'" name="error" />
|
|
83
|
+
</div>
|
|
84
|
+
</template>
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { useScriptTriggerElement } from '../composables/useScriptTriggerElement'
|
|
3
|
+
import { useScriptGoogleAdsense } from '../registry/google-adsense'
|
|
4
|
+
import { callOnce, onMounted, ref, watch } from '#imports'
|
|
3
5
|
import type { ElementScriptTrigger } from '#nuxt-scripts'
|
|
4
6
|
|
|
5
7
|
const props = withDefaults(defineProps<{
|
|
@@ -16,20 +18,36 @@ const props = withDefaults(defineProps<{
|
|
|
16
18
|
dataFullWidthResponsive: true,
|
|
17
19
|
})
|
|
18
20
|
|
|
21
|
+
const emits = defineEmits<{
|
|
22
|
+
// our emit
|
|
23
|
+
ready: [e: ReturnType<typeof useScriptGoogleAdsense>]
|
|
24
|
+
error: []
|
|
25
|
+
}>()
|
|
26
|
+
|
|
19
27
|
const rootEl = ref(null)
|
|
20
|
-
const trigger =
|
|
28
|
+
const trigger = useScriptTriggerElement({ trigger: props.trigger, el: rootEl })
|
|
21
29
|
|
|
22
|
-
const
|
|
30
|
+
const instance = useScriptGoogleAdsense({
|
|
23
31
|
client: props.dataAdClient,
|
|
24
32
|
scriptOptions: {
|
|
25
33
|
trigger,
|
|
26
34
|
},
|
|
27
35
|
})
|
|
28
36
|
|
|
37
|
+
const { $script } = instance
|
|
38
|
+
|
|
29
39
|
onMounted(() => {
|
|
30
40
|
callOnce(() => {
|
|
31
41
|
(window.adsbygoogle = window.adsbygoogle || []).push({})
|
|
32
42
|
})
|
|
43
|
+
watch(instance.$script.status, () => {
|
|
44
|
+
if (instance.$script.status.value === 'loaded') {
|
|
45
|
+
emits('ready', instance)
|
|
46
|
+
}
|
|
47
|
+
else if (instance.$script.status.value === 'error') {
|
|
48
|
+
emits('error')
|
|
49
|
+
}
|
|
50
|
+
})
|
|
33
51
|
})
|
|
34
52
|
</script>
|
|
35
53
|
|
|
@@ -45,6 +63,7 @@ onMounted(() => {
|
|
|
45
63
|
v-bind="{ ...$attrs }"
|
|
46
64
|
>
|
|
47
65
|
<slot v-if="$script.status.value === 'awaitingLoad'" name="awaitingLoad" />
|
|
48
|
-
<slot v-if="$script.status.value === 'loading'" name="loading" />
|
|
66
|
+
<slot v-else-if="$script.status.value === 'loading'" name="loading" />
|
|
67
|
+
<slot v-else-if="$script.status.value === 'error'" name="error" />
|
|
49
68
|
</ins>
|
|
50
69
|
</template>
|
|
@@ -1,21 +1,15 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
/// <reference types="google.maps" />
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
type ReservedProps,
|
|
8
|
-
computed,
|
|
9
|
-
onBeforeUnmount,
|
|
10
|
-
onMounted,
|
|
11
|
-
ref,
|
|
12
|
-
watch,
|
|
13
|
-
} from 'vue'
|
|
14
|
-
import { type QueryObject, withQuery } from 'ufo'
|
|
3
|
+
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
|
4
|
+
import type { HTMLAttributes, ImgHTMLAttributes, Ref, ReservedProps } from 'vue'
|
|
5
|
+
import { withQuery } from 'ufo'
|
|
6
|
+
import type { QueryObject } from 'ufo'
|
|
15
7
|
import { defu } from 'defu'
|
|
16
8
|
import type { ElementScriptTrigger } from '../types'
|
|
17
9
|
import { scriptRuntimeConfig } from '../utils'
|
|
18
|
-
import {
|
|
10
|
+
import { useScriptTriggerElement } from '../composables/useScriptTriggerElement'
|
|
11
|
+
import { useScriptGoogleMaps } from '../registry/google-maps'
|
|
12
|
+
import { resolveComponent, useHead } from '#imports'
|
|
19
13
|
|
|
20
14
|
interface PlaceholderOptions {
|
|
21
15
|
width?: string | number
|
|
@@ -91,6 +85,7 @@ const props = withDefaults(defineProps<{
|
|
|
91
85
|
const emits = defineEmits<{
|
|
92
86
|
// our emit
|
|
93
87
|
ready: [e: Ref<google.maps.Map | undefined>]
|
|
88
|
+
error: []
|
|
94
89
|
}>()
|
|
95
90
|
|
|
96
91
|
const apiKey = props.apiKey || scriptRuntimeConfig('googleMaps')?.apiKey
|
|
@@ -106,7 +101,7 @@ const mapEl = ref<HTMLElement>()
|
|
|
106
101
|
const { $script } = useScriptGoogleMaps({
|
|
107
102
|
apiKey: props.apiKey,
|
|
108
103
|
scriptOptions: {
|
|
109
|
-
trigger:
|
|
104
|
+
trigger: useScriptTriggerElement({ trigger: props.trigger, el: rootEl }),
|
|
110
105
|
},
|
|
111
106
|
})
|
|
112
107
|
|
|
@@ -142,6 +137,11 @@ onMounted(() => {
|
|
|
142
137
|
watch(ready, (v) => {
|
|
143
138
|
v && emits('ready', map)
|
|
144
139
|
})
|
|
140
|
+
watch($script.status, () => {
|
|
141
|
+
if ($script.status.value === 'error') {
|
|
142
|
+
emits('error')
|
|
143
|
+
}
|
|
144
|
+
})
|
|
145
145
|
// create the map
|
|
146
146
|
$script.then(async (instance) => {
|
|
147
147
|
const maps = await instance.maps as any as typeof google.maps // some weird type issue here
|
|
@@ -259,6 +259,7 @@ onBeforeUnmount(() => {
|
|
|
259
259
|
<ScriptLoadingIndicator color="black" />
|
|
260
260
|
</slot>
|
|
261
261
|
<slot v-if="$script.status.value === 'awaitingLoad'" name="awaitingLoad" />
|
|
262
|
+
<slot v-else-if="$script.status.value === 'error'" name="error" />
|
|
262
263
|
<slot />
|
|
263
264
|
</div>
|
|
264
265
|
</template>
|