@jctrans-materials/nuxt 1.0.37-beta.1 → 1.0.37-beta.11

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 CHANGED
@@ -1,75 +1,128 @@
1
- # Nuxt Minimal Starter
1
+ # @jctrans-materials/nuxt
2
2
 
3
- Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
3
+ Nuxt 3 模块,自动注册 `@jctrans-materials/comps-vue3` 组件,并内置埋点初始化插件与事件上报指令。
4
4
 
5
- ## Setup
6
-
7
- Make sure to install dependencies:
5
+ ## 安装
8
6
 
9
7
  ```bash
10
- # npm
11
- npm install
12
-
13
- # pnpm
14
- pnpm install
15
-
16
- # yarn
17
- yarn install
18
-
19
- # bun
20
- bun install
8
+ pnpm add @jctrans-materials/nuxt @jctrans-materials/comps-vue3 @jctrans-materials/shared gio-webjs-sdk
21
9
  ```
22
10
 
23
- ## Development Server
11
+ ## Nuxt 配置
12
+
13
+ ```ts
14
+ export default defineNuxtConfig({
15
+ modules: ["@jctrans-materials/nuxt"],
16
+ jctrans: {
17
+ sharedConfig: {
18
+ appId: "ERA",
19
+ prefixPath: "https://api.example.com",
20
+ },
21
+ tracking: {
22
+ enabled: true,
23
+ autoInit: true,
24
+ directiveName: "gio-track",
25
+ globalVarName: "__JCTRANS_GIO_CONFIG__",
26
+ accountId: "your-account-id",
27
+ dataSourceId: "your-data-source-id",
28
+ appId: "your-gio-app-id",
29
+ initOptions: {
30
+ debug: false,
31
+ trackPage: false,
32
+ autoTrackPage: true,
33
+ },
34
+ },
35
+ },
36
+ });
37
+ ```
24
38
 
25
- Start the development server on `http://localhost:3000`:
39
+ ## 环境变量与全局变量
40
+
41
+ 模块会在 client 插件内自动按优先级读取配置:
42
+
43
+ 1. `window[globalVarName]`(默认 `window.__JCTRANS_GIO_CONFIG__`)
44
+ 2. `window.__GIO_CONFIG__`
45
+ 3. `runtimeConfig.public.jctrans.tracking`
46
+ 4. `runtimeConfig.public.GIO_ACCOUNT_ID` / `runtimeConfig.public.GIO_DATA_SOURCE_ID` / `runtimeConfig.public.GIO_APP_ID`
47
+ 5. `import.meta.env.VITE_GIO_ACCOUNT_ID` / `import.meta.env.VITE_GIO_DATA_SOURCE_ID` / `import.meta.env.VITE_GIO_APP_ID`
48
+
49
+ 例如在 HTML 模板注入:
50
+
51
+ ```html
52
+ <script>
53
+ window.__JCTRANS_GIO_CONFIG__ = {
54
+ accountId: "your-account-id",
55
+ dataSourceId: "your-data-source-id",
56
+ appId: "your-gio-app-id",
57
+ directiveName: "gio-track",
58
+ initOptions: {
59
+ debug: false,
60
+ trackPage: false,
61
+ autoTrackPage: true,
62
+ },
63
+ };
64
+ </script>
65
+ ```
26
66
 
27
- ```bash
28
- # npm
29
- npm run dev
67
+ ## 事件上报指令
30
68
 
31
- # pnpm
32
- pnpm dev
69
+ 默认注册全局指令 `v-gio-track`(可通过 `tracking.directiveName` 修改)。
33
70
 
34
- # yarn
35
- yarn dev
71
+ 字符串写法:
36
72
 
37
- # bun
38
- bun run dev
73
+ ```vue
74
+ <button v-gio-track="'login_click'">登录</button>
39
75
  ```
40
76
 
41
- ## Production
77
+ 对象写法:
78
+
79
+ ```vue
80
+ <button
81
+ v-gio-track="{
82
+ event: 'order_submit',
83
+ trigger: 'click',
84
+ attrs: { source: 'home', type: 'sea' },
85
+ once: true,
86
+ stop: true,
87
+ prevent: false,
88
+ onTracked: ({ eventName }) => {
89
+ console.log('tracked:', eventName);
90
+ },
91
+ }"
92
+ >
93
+ 提交
94
+ </button>
95
+ ```
42
96
 
43
- Build the application for production:
97
+ 支持回调字段:`onTracked`(推荐)和 `callback`(兼容)。回调会在 `gio.track` 完成回调后触发。
44
98
 
45
- ```bash
46
- # npm
47
- npm run build
99
+ ## 注入能力
48
100
 
49
- # pnpm
50
- pnpm build
101
+ 模块会自动注入:
51
102
 
52
- # yarn
53
- yarn build
103
+ - `$gio`:`tracker` 实例
104
+ - `$trackEvent(eventName, attrs?)`:手动上报方法
54
105
 
55
- # bun
56
- bun run build
57
- ```
106
+ `script setup` 使用示例:
58
107
 
59
- Locally preview production build:
108
+ ```ts
109
+ const { $trackEvent, $gio } = useNuxtApp();
60
110
 
61
- ```bash
62
- # npm
63
- npm run preview
111
+ const handleClick = () => {
112
+ $trackEvent("search_click", { tab: "air" });
113
+ $gio.setGeneralProps({ app: "nuxt3" });
114
+ };
115
+ ```
64
116
 
65
- # pnpm
66
- pnpm preview
117
+ ## 说明
67
118
 
68
- # yarn
69
- yarn preview
119
+ - 埋点初始化与指令注册都在 `client` 插件执行,不影响 SSR。
120
+ - 当 `tracking.enabled = false` 时,指令与上报函数会退化为空实现。
121
+ - 当缺少 `accountId` 或 `dataSourceId` 时,会跳过自动初始化,但指令和 `$trackEvent` 仍可用。
70
122
 
71
- # bun
72
- bun run preview
73
- ```
123
+ ## 类型注意事项(重要)
74
124
 
75
- Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
125
+ - `plugin.client.ts` 内保持从 `@jctrans-materials/shared` 直接引入 `tracker`。
126
+ - 但在 Nuxt `provide` 和 `types.d.ts` 中,不要直接使用 `typeof tracker` 作为 `$gio` 类型。
127
+ - 原因:`tracker` 基于 class,直接暴露具体实例类型在声明生成阶段可能触发 `TS4094`(私有成员泄漏)。
128
+ - 规范做法:使用 `GioPublicApi` 这类公共接口作为对外类型契约。
package/dist/module.cjs CHANGED
@@ -14,7 +14,18 @@ const module$1 = kit.defineNuxtModule({
14
14
  },
15
15
  defaults: {
16
16
  addStyle: true,
17
- sharedConfig: {}
17
+ sharedConfig: {},
18
+ tracking: {
19
+ enabled: true,
20
+ autoInit: true,
21
+ directiveName: "gio-track",
22
+ globalVarName: "__JCTRANS_GIO_CONFIG__",
23
+ initOptions: {
24
+ debug: false,
25
+ trackPage: false,
26
+ autoTrackPage: false
27
+ }
28
+ }
18
29
  },
19
30
  async setup(options, nuxt) {
20
31
  const { resolve } = kit.createResolver((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('module.cjs', document.baseURI).href)));
@@ -22,7 +33,8 @@ const module$1 = kit.defineNuxtModule({
22
33
  nuxt.options.runtimeConfig.public.jctrans = defu.defu(
23
34
  nuxt.options.runtimeConfig.public.jctrans,
24
35
  {
25
- sharedConfig: options.sharedConfig
36
+ sharedConfig: options.sharedConfig,
37
+ tracking: options.tracking
26
38
  }
27
39
  );
28
40
  if (options.addStyle) {
@@ -56,6 +68,18 @@ const module$1 = kit.defineNuxtModule({
56
68
  src: resolve("./runtime/plugin"),
57
69
  mode: "all"
58
70
  });
71
+ kit.addPlugin({
72
+ src: resolve("./runtime/gio.client"),
73
+ mode: "client"
74
+ });
75
+ kit.addPlugin({
76
+ src: resolve("./runtime/gio.server"),
77
+ mode: "server"
78
+ });
79
+ kit.addPlugin({
80
+ src: resolve("./runtime/plugin.client"),
81
+ mode: "client"
82
+ });
59
83
  kit.addTypeTemplate({
60
84
  filename: "types/jctrans-materials-nuxt.d.ts",
61
85
  // 生成在宿主 .nuxt/types 下的文件名,不重名即可
package/dist/module.d.cts CHANGED
@@ -1,9 +1,29 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
2
  import { SharedConfig } from '@jctrans-materials/comps-vue3';
3
3
 
4
+ interface TrackingInitOptions {
5
+ debug?: boolean;
6
+ serverUrl?: string;
7
+ trackPage?: boolean;
8
+ forceLogin?: boolean;
9
+ idMapping?: boolean;
10
+ hashtag?: boolean;
11
+ autoTrackPage?: boolean;
12
+ }
13
+ interface TrackingOptions {
14
+ enabled?: boolean;
15
+ autoInit?: boolean;
16
+ directiveName?: string;
17
+ globalVarName?: string;
18
+ accountId?: string;
19
+ dataSourceId?: string;
20
+ appId?: string;
21
+ initOptions?: TrackingInitOptions;
22
+ }
4
23
  interface ModuleOptions {
5
24
  addStyle?: boolean;
6
25
  sharedConfig?: Partial<SharedConfig>;
26
+ tracking?: TrackingOptions;
7
27
  }
8
28
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
9
29
 
@@ -11,10 +31,11 @@ declare module "@nuxt/schema" {
11
31
  interface PublicRuntimeConfig {
12
32
  jctrans?: {
13
33
  sharedConfig?: Partial<SharedConfig>;
14
- appId: string;
34
+ appId?: string;
35
+ tracking?: TrackingOptions;
15
36
  };
16
37
  }
17
38
  }
18
39
 
19
40
  export = _default;
20
- export type { ModuleOptions };
41
+ export type { ModuleOptions, TrackingInitOptions, TrackingOptions };
package/dist/module.d.mts CHANGED
@@ -1,9 +1,29 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
2
  import { SharedConfig } from '@jctrans-materials/comps-vue3';
3
3
 
4
+ interface TrackingInitOptions {
5
+ debug?: boolean;
6
+ serverUrl?: string;
7
+ trackPage?: boolean;
8
+ forceLogin?: boolean;
9
+ idMapping?: boolean;
10
+ hashtag?: boolean;
11
+ autoTrackPage?: boolean;
12
+ }
13
+ interface TrackingOptions {
14
+ enabled?: boolean;
15
+ autoInit?: boolean;
16
+ directiveName?: string;
17
+ globalVarName?: string;
18
+ accountId?: string;
19
+ dataSourceId?: string;
20
+ appId?: string;
21
+ initOptions?: TrackingInitOptions;
22
+ }
4
23
  interface ModuleOptions {
5
24
  addStyle?: boolean;
6
25
  sharedConfig?: Partial<SharedConfig>;
26
+ tracking?: TrackingOptions;
7
27
  }
8
28
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
9
29
 
@@ -11,10 +31,11 @@ declare module "@nuxt/schema" {
11
31
  interface PublicRuntimeConfig {
12
32
  jctrans?: {
13
33
  sharedConfig?: Partial<SharedConfig>;
14
- appId: string;
34
+ appId?: string;
35
+ tracking?: TrackingOptions;
15
36
  };
16
37
  }
17
38
  }
18
39
 
19
40
  export { _default as default };
20
- export type { ModuleOptions };
41
+ export type { ModuleOptions, TrackingInitOptions, TrackingOptions };
package/dist/module.d.ts CHANGED
@@ -1,9 +1,29 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
2
  import { SharedConfig } from '@jctrans-materials/comps-vue3';
3
3
 
4
+ interface TrackingInitOptions {
5
+ debug?: boolean;
6
+ serverUrl?: string;
7
+ trackPage?: boolean;
8
+ forceLogin?: boolean;
9
+ idMapping?: boolean;
10
+ hashtag?: boolean;
11
+ autoTrackPage?: boolean;
12
+ }
13
+ interface TrackingOptions {
14
+ enabled?: boolean;
15
+ autoInit?: boolean;
16
+ directiveName?: string;
17
+ globalVarName?: string;
18
+ accountId?: string;
19
+ dataSourceId?: string;
20
+ appId?: string;
21
+ initOptions?: TrackingInitOptions;
22
+ }
4
23
  interface ModuleOptions {
5
24
  addStyle?: boolean;
6
25
  sharedConfig?: Partial<SharedConfig>;
26
+ tracking?: TrackingOptions;
7
27
  }
8
28
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
9
29
 
@@ -11,10 +31,11 @@ declare module "@nuxt/schema" {
11
31
  interface PublicRuntimeConfig {
12
32
  jctrans?: {
13
33
  sharedConfig?: Partial<SharedConfig>;
14
- appId: string;
34
+ appId?: string;
35
+ tracking?: TrackingOptions;
15
36
  };
16
37
  }
17
38
  }
18
39
 
19
40
  export = _default;
20
- export type { ModuleOptions };
41
+ export type { ModuleOptions, TrackingInitOptions, TrackingOptions };
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^3.0.0"
6
6
  },
7
- "version": "1.0.37-beta.1",
7
+ "version": "1.0.37-beta.11",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -11,7 +11,18 @@ const module$1 = defineNuxtModule({
11
11
  },
12
12
  defaults: {
13
13
  addStyle: true,
14
- sharedConfig: {}
14
+ sharedConfig: {},
15
+ tracking: {
16
+ enabled: true,
17
+ autoInit: true,
18
+ directiveName: "gio-track",
19
+ globalVarName: "__JCTRANS_GIO_CONFIG__",
20
+ initOptions: {
21
+ debug: false,
22
+ trackPage: false,
23
+ autoTrackPage: false
24
+ }
25
+ }
15
26
  },
16
27
  async setup(options, nuxt) {
17
28
  const { resolve } = createResolver(import.meta.url);
@@ -19,7 +30,8 @@ const module$1 = defineNuxtModule({
19
30
  nuxt.options.runtimeConfig.public.jctrans = defu(
20
31
  nuxt.options.runtimeConfig.public.jctrans,
21
32
  {
22
- sharedConfig: options.sharedConfig
33
+ sharedConfig: options.sharedConfig,
34
+ tracking: options.tracking
23
35
  }
24
36
  );
25
37
  if (options.addStyle) {
@@ -53,6 +65,18 @@ const module$1 = defineNuxtModule({
53
65
  src: resolve("./runtime/plugin"),
54
66
  mode: "all"
55
67
  });
68
+ addPlugin({
69
+ src: resolve("./runtime/gio.client"),
70
+ mode: "client"
71
+ });
72
+ addPlugin({
73
+ src: resolve("./runtime/gio.server"),
74
+ mode: "server"
75
+ });
76
+ addPlugin({
77
+ src: resolve("./runtime/plugin.client"),
78
+ mode: "client"
79
+ });
56
80
  addTypeTemplate({
57
81
  filename: "types/jctrans-materials-nuxt.d.ts",
58
82
  // 生成在宿主 .nuxt/types 下的文件名,不重名即可
@@ -0,0 +1,3 @@
1
+ import "gio-webjs-sdk";
2
+ declare const _default: import("#app").Plugin<Record<string, unknown>> & import("#app").ObjectPlugin<Record<string, unknown>>;
3
+ export default _default;
@@ -0,0 +1,15 @@
1
+ import { defineNuxtPlugin } from "#app";
2
+ import "gio-webjs-sdk";
3
+ export default defineNuxtPlugin({
4
+ name: "jctrans-gio-sdk-loader",
5
+ enforce: "pre",
6
+ setup() {
7
+ if (process.dev && typeof window !== "undefined") {
8
+ if (typeof window.gdp !== "function") {
9
+ console.warn(
10
+ "[GIO] SDK \u5DF2\u5F15\u5165\uFF0C\u4F46 window.gdp \u4ECD\u4E0D\u53EF\u7528\uFF0C\u8BF7\u68C0\u67E5\u6253\u5305/\u8FD0\u884C\u73AF\u5883"
11
+ );
12
+ }
13
+ }
14
+ }
15
+ });
@@ -0,0 +1,28 @@
1
+ declare const _default: import("#app").Plugin<{
2
+ gio: {
3
+ init: () => void;
4
+ track: () => void;
5
+ isInitialized: () => boolean;
6
+ isBrowser: () => boolean;
7
+ setUserId: () => void;
8
+ clearUserId: () => void;
9
+ setGeneralProps: () => void;
10
+ setPageAttributes: () => void;
11
+ sendPage: () => void;
12
+ };
13
+ trackEvent: () => void;
14
+ }> & import("#app").ObjectPlugin<{
15
+ gio: {
16
+ init: () => void;
17
+ track: () => void;
18
+ isInitialized: () => boolean;
19
+ isBrowser: () => boolean;
20
+ setUserId: () => void;
21
+ clearUserId: () => void;
22
+ setGeneralProps: () => void;
23
+ setPageAttributes: () => void;
24
+ sendPage: () => void;
25
+ };
26
+ trackEvent: () => void;
27
+ }>;
28
+ export default _default;
@@ -0,0 +1,42 @@
1
+ import { defineNuxtPlugin, useRuntimeConfig } from "#app";
2
+ const normalizeDirectiveName = (value) => {
3
+ if (typeof value !== "string") return "gio-track";
4
+ const trimmed = value.trim();
5
+ if (!trimmed) return "gio-track";
6
+ return trimmed.replace(/^v-/, "");
7
+ };
8
+ export default defineNuxtPlugin((nuxtApp) => {
9
+ const runtimeConfig = useRuntimeConfig();
10
+ const directiveName = normalizeDirectiveName(
11
+ runtimeConfig.public?.jctrans?.tracking?.directiveName
12
+ );
13
+ nuxtApp.vueApp.directive("gio-track", {});
14
+ if (directiveName !== "gio-track") {
15
+ nuxtApp.vueApp.directive(directiveName, {});
16
+ }
17
+ const mockGio = {
18
+ init: () => {
19
+ },
20
+ track: () => {
21
+ },
22
+ isInitialized: () => false,
23
+ isBrowser: () => false,
24
+ setUserId: () => {
25
+ },
26
+ clearUserId: () => {
27
+ },
28
+ setGeneralProps: () => {
29
+ },
30
+ setPageAttributes: () => {
31
+ },
32
+ sendPage: () => {
33
+ }
34
+ };
35
+ return {
36
+ provide: {
37
+ gio: mockGio,
38
+ trackEvent: () => {
39
+ }
40
+ }
41
+ };
42
+ });
@@ -1,4 +1,3 @@
1
1
  import { defineNuxtRouteMiddleware } from "#app";
2
2
  export default defineNuxtRouteMiddleware((to, from) => {
3
- console.log("\u5168\u5C40\u4E2D\u95F4\u4EF6\u8FD0\u884C\u4E2D...");
4
3
  });
@@ -0,0 +1,18 @@
1
+ type TrackAttrs = Record<string, string | number | Array<string | number>>;
2
+ type GioPublicApi = {
3
+ isInitialized: () => boolean;
4
+ isBrowser: () => boolean;
5
+ init: (...args: any[]) => void;
6
+ track: (eventName: string, attrs?: TrackAttrs, callback?: () => void) => void;
7
+ setGeneralProps: (props: Record<string, any>) => void;
8
+ setPageAttributes: (props: Record<string, any>) => void;
9
+ sendPage: () => void;
10
+ };
11
+ declare const _default: import("#app").Plugin<{
12
+ gio: GioPublicApi;
13
+ trackEvent: (eventName: string, attrs?: TrackAttrs) => void;
14
+ }> & import("#app").ObjectPlugin<{
15
+ gio: GioPublicApi;
16
+ trackEvent: (eventName: string, attrs?: TrackAttrs) => void;
17
+ }>;
18
+ export default _default;
@@ -0,0 +1,223 @@
1
+ import { defineNuxtPlugin, useRuntimeConfig, useRouter } from "#app";
2
+ import { tracker } from "@jctrans-materials/shared";
3
+ import { nextTick } from "vue";
4
+ const pickString = (...values) => {
5
+ for (const value of values) {
6
+ if (typeof value === "string") {
7
+ const trimmed = value.trim();
8
+ if (trimmed) return trimmed;
9
+ }
10
+ }
11
+ return "";
12
+ };
13
+ const pickBoolean = (...values) => {
14
+ for (const value of values) {
15
+ if (typeof value === "boolean") return value;
16
+ if (typeof value === "string") {
17
+ const normalized = value.trim().toLowerCase();
18
+ if (normalized === "true") return true;
19
+ if (normalized === "false") return false;
20
+ }
21
+ }
22
+ return void 0;
23
+ };
24
+ const getGlobalTrackingConfig = (globalVarName) => {
25
+ if (typeof window === "undefined") return {};
26
+ const currentWindow = window;
27
+ const fromCustom = currentWindow?.[globalVarName];
28
+ const fromJctrans = currentWindow?.__JCTRANS_GIO_CONFIG__;
29
+ const fromDefault = currentWindow?.__GIO_CONFIG__;
30
+ const finalConfig = fromCustom || fromJctrans || fromDefault;
31
+ if (finalConfig && typeof finalConfig === "object") {
32
+ return finalConfig;
33
+ }
34
+ return {};
35
+ };
36
+ const normalizeDirectiveName = (value) => {
37
+ const raw = pickString(value);
38
+ const name = raw || "gio-track";
39
+ return name.replace(/^v-/, "");
40
+ };
41
+ const normalizeBinding = (binding) => {
42
+ const value = binding.value;
43
+ if (typeof value === "string") {
44
+ const eventName2 = value.trim();
45
+ return {
46
+ eventName: eventName2,
47
+ trigger: "click",
48
+ attrs: {},
49
+ once: false,
50
+ stop: false,
51
+ prevent: false
52
+ };
53
+ }
54
+ if (!value || typeof value !== "object") {
55
+ return {
56
+ eventName: "",
57
+ trigger: "click",
58
+ attrs: {},
59
+ once: false,
60
+ stop: false,
61
+ prevent: false
62
+ };
63
+ }
64
+ const eventName = pickString(value.event, value.name, binding.arg);
65
+ const trigger = pickString(value.trigger) || "click";
66
+ const attrs = value.attributes || value.attrs || {};
67
+ return {
68
+ eventName,
69
+ trigger,
70
+ attrs,
71
+ once: Boolean(value.once),
72
+ stop: Boolean(value.stop),
73
+ prevent: Boolean(value.prevent),
74
+ callback: typeof value.onTracked === "function" ? value.onTracked : typeof value.callback === "function" ? value.callback : void 0
75
+ };
76
+ };
77
+ const removeElementHandler = (element) => {
78
+ const bound = element.__jctransTrackHandler__;
79
+ if (!bound) return;
80
+ element.removeEventListener(bound.trigger, bound.handler);
81
+ delete element.__jctransTrackHandler__;
82
+ };
83
+ const bindTrackHandler = (element, binding, gio) => {
84
+ removeElementHandler(element);
85
+ const normalized = normalizeBinding(binding);
86
+ if (!normalized.eventName) return;
87
+ const handler = (event) => {
88
+ if (normalized.prevent && "preventDefault" in event) {
89
+ event.preventDefault();
90
+ }
91
+ if (normalized.stop && "stopPropagation" in event) {
92
+ event.stopPropagation();
93
+ }
94
+ gio.track(normalized.eventName, normalized.attrs, () => {
95
+ normalized.callback?.({
96
+ event,
97
+ eventName: normalized.eventName,
98
+ attrs: normalized.attrs,
99
+ trigger: normalized.trigger
100
+ });
101
+ });
102
+ if (normalized.once) {
103
+ removeElementHandler(element);
104
+ }
105
+ };
106
+ element.addEventListener(normalized.trigger, handler);
107
+ element.__jctransTrackHandler__ = {
108
+ eventName: normalized.eventName,
109
+ trigger: normalized.trigger,
110
+ handler
111
+ };
112
+ };
113
+ export default defineNuxtPlugin((nuxtApp) => {
114
+ const runtimeConfig = useRuntimeConfig();
115
+ const router = useRouter();
116
+ const gio = tracker;
117
+ const runtimeTracking = runtimeConfig.public?.jctrans?.tracking || {};
118
+ const globalVarName = pickString(
119
+ runtimeTracking.globalVarName,
120
+ "__JCTRANS_GIO_CONFIG__"
121
+ );
122
+ const globalTracking = getGlobalTrackingConfig(globalVarName);
123
+ const metaEnv = import.meta.env || {};
124
+ const enabled = pickBoolean(runtimeTracking.enabled, globalTracking.enabled);
125
+ if (enabled === false) {
126
+ return {
127
+ provide: {
128
+ gio,
129
+ trackEvent: () => {
130
+ }
131
+ }
132
+ };
133
+ }
134
+ const initOptions = {
135
+ ...runtimeTracking.initOptions || {},
136
+ ...globalTracking.initOptions || {}
137
+ };
138
+ if (!initOptions.serverUrl) {
139
+ const serverUrl = pickString(
140
+ runtimeConfig.public?.GIO_SERVER_URL,
141
+ runtimeConfig.public?.gioServerUrl,
142
+ globalTracking?.serverUrl,
143
+ runtimeTracking?.serverUrl
144
+ );
145
+ if (serverUrl) {
146
+ initOptions.serverUrl = serverUrl;
147
+ }
148
+ }
149
+ const accountId = pickString(
150
+ globalTracking.accountId,
151
+ runtimeTracking.accountId,
152
+ runtimeConfig.public?.gioAccountId,
153
+ runtimeConfig.public?.GIO_ACCOUNT_ID,
154
+ metaEnv.VITE_GIO_ACCOUNT_ID
155
+ );
156
+ const dataSourceId = pickString(
157
+ globalTracking.dataSourceId,
158
+ runtimeTracking.dataSourceId,
159
+ runtimeConfig.public?.gioDataSourceId,
160
+ runtimeConfig.public?.GIO_DATA_SOURCE_ID,
161
+ metaEnv.VITE_GIO_DATA_SOURCE_ID
162
+ );
163
+ const appId = pickString(
164
+ globalTracking.appId,
165
+ runtimeTracking.appId,
166
+ runtimeConfig.public?.gioAppId,
167
+ runtimeConfig.public?.GIO_APP_ID,
168
+ metaEnv.VITE_GIO_APP_ID
169
+ );
170
+ const autoInit = pickBoolean(
171
+ runtimeTracking.autoInit,
172
+ globalTracking.autoInit
173
+ );
174
+ if ((autoInit ?? true) && accountId && dataSourceId && !gio.isInitialized()) {
175
+ if (appId) {
176
+ gio.init(accountId, dataSourceId, appId, initOptions);
177
+ } else {
178
+ gio.init(accountId, dataSourceId, initOptions);
179
+ }
180
+ }
181
+ const trackEvent = (eventName, attrs) => {
182
+ const normalizedEvent = pickString(eventName);
183
+ if (!normalizedEvent) return;
184
+ gio.track(normalizedEvent, attrs || {});
185
+ };
186
+ const directiveName = normalizeDirectiveName(
187
+ globalTracking.directiveName || runtimeTracking.directiveName
188
+ );
189
+ const trackDirective = {
190
+ mounted(element, binding) {
191
+ bindTrackHandler(element, binding, gio);
192
+ },
193
+ updated(element, binding) {
194
+ if (JSON.stringify(binding.value) !== JSON.stringify(binding.oldValue)) {
195
+ bindTrackHandler(element, binding, gio);
196
+ }
197
+ },
198
+ beforeUnmount(element) {
199
+ removeElementHandler(element);
200
+ }
201
+ };
202
+ nuxtApp.vueApp.directive(directiveName, trackDirective);
203
+ if (initOptions.trackPage === false && initOptions.autoTrackPage) {
204
+ if (import.meta.client) {
205
+ router.afterEach((to) => {
206
+ setTimeout(async () => {
207
+ await nextTick();
208
+ gio.setPageAttributes({
209
+ route_name: String(to.name || ""),
210
+ route_path: to.path
211
+ });
212
+ gio.sendPage();
213
+ }, 50);
214
+ });
215
+ }
216
+ }
217
+ return {
218
+ provide: {
219
+ gio,
220
+ trackEvent
221
+ }
222
+ };
223
+ });
@@ -1,15 +1,41 @@
1
1
  // src/runtime/types.d.ts
2
2
  import { initSharedConfig } from "@jctrans-materials/comps-vue3";
3
3
 
4
+ type TrackAttrs = Record<string, string | number | Array<string | number>>;
5
+
6
+ // ⚠️ 不要使用 `typeof tracker` 作为 `$gio` 类型。
7
+ // `tracker` 是 class 实例,直接导出具体类型会在声明生成时触发 TS4094。
8
+ // 这里定义公共接口类型,既能保留调用提示,也能避免私有字段泄漏。
9
+ type GioPublicApi = {
10
+ isInitialized: () => boolean;
11
+ isBrowser: () => boolean;
12
+ init: (...args: any[]) => void;
13
+ track: (eventName: string, attrs?: TrackAttrs, callback?: () => void) => void;
14
+ setGeneralProps: (props: Record<string, any>) => void;
15
+ setPageAttributes: (props: Record<string, any>) => void;
16
+ sendPage: () => void;
17
+ };
18
+
4
19
  declare module "#app" {
5
20
  interface NuxtApp {
6
21
  $initAuthSharedConfig: typeof initSharedConfig;
22
+ $gio: GioPublicApi;
23
+ $trackEvent: (eventName: string, attrs?: TrackAttrs) => void;
7
24
  }
8
25
  }
9
26
 
10
27
  declare module "vue" {
11
28
  interface ComponentCustomProperties {
12
29
  $initAuthSharedConfig: typeof initSharedConfig;
30
+ $gio: GioPublicApi;
31
+ $trackEvent: (eventName: string, attrs?: TrackAttrs) => void;
32
+ }
33
+ }
34
+
35
+ declare global {
36
+ interface Window {
37
+ __JCTRANS_GIO_CONFIG__?: Record<string, unknown>;
38
+ __GIO_CONFIG__?: Record<string, unknown>;
13
39
  }
14
40
  }
15
41
 
package/dist/types.d.mts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { default } from './module.mjs'
2
2
 
3
- export { type ModuleOptions } from './module.mjs'
3
+ export { type ModuleOptions, type TrackingInitOptions, type TrackingOptions } from './module.mjs'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jctrans-materials/nuxt",
3
3
  "type": "module",
4
- "version": "1.0.37-beta.1",
4
+ "version": "1.0.37-beta.11",
5
5
  "description": "Nuxt module for JCtrans UI components",
6
6
  "exports": {
7
7
  ".": {
@@ -22,11 +22,14 @@
22
22
  "nuxt": "^3.0.0",
23
23
  "vue": "^3.5.26",
24
24
  "vue-router": "^4.6.4",
25
- "@jctrans-materials/comps-vue3": "1.0.37-beta.1"
25
+ "@jctrans-materials/comps-vue3": "1.0.37-beta.11",
26
+ "@jctrans-materials/shared": "1.0.37-beta.11"
26
27
  },
27
28
  "peerDependencies": {
29
+ "gio-webjs-sdk": "^4.0.0",
28
30
  "nuxt": "^3.0.0",
29
- "@jctrans-materials/comps-vue3": "1.0.37-beta.1"
31
+ "@jctrans-materials/shared": "1.0.37-beta.11",
32
+ "@jctrans-materials/comps-vue3": "1.0.37-beta.11"
30
33
  },
31
34
  "devDependencies": {
32
35
  "@nuxt/module-builder": "latest",