nativescript-web-adapter 0.1.2 → 0.1.3

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.
Files changed (97) hide show
  1. package/README.md +218 -246
  2. package/core/components/AbsoluteLayout.vue +11 -0
  3. package/core/components/ActionBar.vue +11 -0
  4. package/core/components/ActionItem.vue +11 -0
  5. package/core/components/ActivityIndicator.vue +15 -0
  6. package/core/components/Button.vue +41 -0
  7. package/core/components/DatePicker.vue +27 -0
  8. package/core/components/DockLayout.vue +23 -0
  9. package/core/components/FlexboxLayout.vue +11 -0
  10. package/core/components/Frame.vue +11 -0
  11. package/core/components/GridLayout.vue +85 -0
  12. package/core/components/HtmlView.vue +13 -0
  13. package/core/components/Image.vue +12 -0
  14. package/core/components/ImageCacheIt.vue +12 -0
  15. package/core/components/Label.vue +15 -0
  16. package/core/components/ListPicker.vue +21 -0
  17. package/core/components/ListView.vue +12 -0
  18. package/core/components/NavigationButton.vue +28 -0
  19. package/core/components/Page.vue +18 -0
  20. package/core/components/Placeholder.vue +11 -0
  21. package/core/components/Progress.vue +12 -0
  22. package/core/components/RootLayout.vue +11 -0
  23. package/core/components/ScrollView.vue +11 -0
  24. package/core/components/SearchBar.vue +22 -0
  25. package/core/components/SegmentedBar.vue +50 -0
  26. package/core/components/SegmentedBarItem.vue +21 -0
  27. package/core/components/Slider.vue +18 -0
  28. package/core/components/StackLayout.vue +11 -0
  29. package/core/components/Switch.vue +26 -0
  30. package/core/components/TabView.vue +48 -0
  31. package/core/components/TabViewItem.vue +27 -0
  32. package/core/components/TextField.vue +15 -0
  33. package/core/components/TextView.vue +18 -0
  34. package/core/components/TimePicker.vue +21 -0
  35. package/core/components/WebView.vue +13 -0
  36. package/core/components/WrapLayout.vue +11 -0
  37. package/core/components/index.js +3 -0
  38. package/core/components/index.ts +35 -0
  39. package/core/composables/dialogs.ts +31 -0
  40. package/core/composables/index.js +3 -0
  41. package/core/composables/index.ts +4 -0
  42. package/core/composables/useActionBar.js +7 -0
  43. package/core/composables/useActionBar.ts +19 -0
  44. package/core/composables/useFrame.js +8 -0
  45. package/core/composables/useFrame.ts +25 -0
  46. package/core/composables/usePage.js +8 -0
  47. package/core/composables/usePage.ts +25 -0
  48. package/core/env.d.ts +7 -0
  49. package/core/index.js +4 -0
  50. package/core/index.ts +85 -0
  51. package/core/types.ts +12 -0
  52. package/dist/nativescript-web-adapter.es.js +83 -0
  53. package/dist/nativescript-web-adapter.umd.js +1 -0
  54. package/dist/style.css +1 -0
  55. package/package.json +35 -49
  56. package/tools/cli.cjs +45 -0
  57. package/tools/create-web-platform.cjs +76 -0
  58. package/tools/create-web-platform.js +196 -0
  59. package/tools/modules/appPatch.cjs +27 -0
  60. package/tools/modules/copy.cjs +84 -0
  61. package/tools/modules/router.cjs +46 -0
  62. package/tools/modules/templates.cjs +130 -0
  63. package/tools/modules/transform.cjs +93 -0
  64. package/dist/core.cjs +0 -3
  65. package/dist/core.cjs.map +0 -1
  66. package/dist/core.js +0 -2
  67. package/dist/core.js.map +0 -1
  68. package/dist/index.cjs +0 -377
  69. package/dist/index.cjs.map +0 -1
  70. package/dist/index.css +0 -172
  71. package/dist/index.js +0 -361
  72. package/dist/index.js.map +0 -1
  73. package/dist/types/core/index.d.ts +0 -8
  74. package/dist/types/index.d.ts +0 -1
  75. package/dist/types/index.types.d.ts +0 -1
  76. package/dist/types/vue/components/ActionBar.d.ts +0 -5
  77. package/dist/types/vue/components/ActionItem.d.ts +0 -15
  78. package/dist/types/vue/components/Button.d.ts +0 -26
  79. package/dist/types/vue/components/ContentView.d.ts +0 -3
  80. package/dist/types/vue/components/FlexboxLayout.d.ts +0 -35
  81. package/dist/types/vue/components/Frame.d.ts +0 -3
  82. package/dist/types/vue/components/GridLayout.d.ts +0 -26
  83. package/dist/types/vue/components/ImageCacheIt.d.ts +0 -23
  84. package/dist/types/vue/components/Label.d.ts +0 -26
  85. package/dist/types/vue/components/ListView.d.ts +0 -24
  86. package/dist/types/vue/components/Page.d.ts +0 -5
  87. package/dist/types/vue/components/StackLayout.d.ts +0 -5
  88. package/dist/types/vue/components/TabView.d.ts +0 -26
  89. package/dist/types/vue/components/TabViewItem.d.ts +0 -24
  90. package/dist/types/vue/index.d.ts +0 -18
  91. package/dist/types/vue/index.types.d.ts +0 -17
  92. package/dist/types/vue.d.ts +0 -266
  93. package/dist/vue.cjs +0 -377
  94. package/dist/vue.cjs.map +0 -1
  95. package/dist/vue.css +0 -172
  96. package/dist/vue.js +0 -361
  97. package/dist/vue.js.map +0 -1
@@ -0,0 +1,31 @@
1
+ export async function alert(message: string, title?: string, okButtonText?: string) {
2
+ window.alert(title ? `${title}\n\n${message}` : message);
3
+ }
4
+
5
+ export async function confirm(message: string, title?: string, okButtonText?: string, cancelButtonText?: string): Promise<boolean> {
6
+ return window.confirm(title ? `${title}\n\n${message}` : message);
7
+ }
8
+
9
+ export async function prompt(message: string, defaultText = '', title?: string, okButtonText?: string, cancelButtonText?: string): Promise<{ result: boolean; text: string }> {
10
+ const res = window.prompt(title ? `${title}\n\n${message}` : message, defaultText);
11
+ return { result: res !== null, text: res ?? '' };
12
+ }
13
+
14
+ export async function login(message = '登录', userName = '', password = '', title?: string, okButtonText?: string, cancelButtonText?: string): Promise<{ result: boolean; userName: string; password: string }> {
15
+ const u = window.prompt(title ? `${title}\n\n${message} - 用户名` : `${message} - 用户名`, userName);
16
+ if (u === null) return { result: false, userName: '', password: '' };
17
+ const p = window.prompt(title ? `${title}\n\n${message} - 密码` : `${message} - 密码`, password);
18
+ if (p === null) return { result: false, userName: '', password: '' };
19
+ return { result: true, userName: u, password: p };
20
+ }
21
+
22
+ export async function action(options: string | { message?: string; cancelButtonText?: string; actions?: string[] }, title?: string): Promise<string | undefined> {
23
+ let message = typeof options === 'string' ? options : (options.message || '选择一个操作');
24
+ const actions = typeof options === 'string' ? [] : (options.actions || []);
25
+ const promptText = title ? `${title}\n\n${message}${actions.length ? `\n选项: ${actions.join(', ')}` : ''}` : `${message}${actions.length ? `\n选项: ${actions.join(', ')}` : ''}`;
26
+ const res = window.prompt(promptText);
27
+ if (!res) return undefined;
28
+ if (!actions.length) return res;
29
+ const match = actions.find(a => a.toLowerCase() === res.toLowerCase());
30
+ return match ?? undefined;
31
+ }
@@ -0,0 +1,3 @@
1
+ export { useActionBar } from './useActionBar.js';
2
+ export { usePage } from './usePage.js';
3
+ export { useFrame } from './useFrame.js';
@@ -0,0 +1,4 @@
1
+ export * from './useActionBar';
2
+ export * from './usePage';
3
+ export * from './useFrame';
4
+ export * from './dialogs';
@@ -0,0 +1,7 @@
1
+ import { ref } from 'vue';
2
+
3
+ export function useActionBar() {
4
+ const title = ref('');
5
+ function setTitle(t) { title.value = t; }
6
+ return { title, setTitle };
7
+ }
@@ -0,0 +1,19 @@
1
+ import { Ref, ref } from 'vue';
2
+
3
+ export interface ActionBarState {
4
+ title: Ref<string>;
5
+ setTitle: (value: string) => void;
6
+ }
7
+
8
+ export function useActionBar(): ActionBarState {
9
+ const title = ref('');
10
+
11
+ function setTitle(value: string) {
12
+ title.value = value;
13
+ }
14
+
15
+ return {
16
+ title,
17
+ setTitle
18
+ };
19
+ }
@@ -0,0 +1,8 @@
1
+ import { ref } from 'vue';
2
+
3
+ export function useFrame() {
4
+ const stack = ref([]);
5
+ function push(page) { stack.value.push(page); }
6
+ function pop() { return stack.value.pop(); }
7
+ return { stack, push, pop };
8
+ }
@@ -0,0 +1,25 @@
1
+ import { Ref, ref } from 'vue';
2
+
3
+ export interface FrameState {
4
+ stack: Ref<any[]>;
5
+ push: (page: any) => void;
6
+ pop: () => any;
7
+ }
8
+
9
+ export function useFrame(): FrameState {
10
+ const stack = ref<any[]>([]);
11
+
12
+ function push(page: any) {
13
+ stack.value.push(page);
14
+ }
15
+
16
+ function pop() {
17
+ return stack.value.pop();
18
+ }
19
+
20
+ return {
21
+ stack,
22
+ push,
23
+ pop
24
+ };
25
+ }
@@ -0,0 +1,8 @@
1
+ import { ref } from 'vue';
2
+
3
+ export function usePage() {
4
+ const isVisible = ref(true);
5
+ function show() { isVisible.value = true; }
6
+ function hide() { isVisible.value = false; }
7
+ return { isVisible, show, hide };
8
+ }
@@ -0,0 +1,25 @@
1
+ import { Ref, ref } from 'vue';
2
+
3
+ export interface PageState {
4
+ isVisible: Ref<boolean>;
5
+ show: () => void;
6
+ hide: () => void;
7
+ }
8
+
9
+ export function usePage(): PageState {
10
+ const isVisible = ref(true);
11
+
12
+ function show() {
13
+ isVisible.value = true;
14
+ }
15
+
16
+ function hide() {
17
+ isVisible.value = false;
18
+ }
19
+
20
+ return {
21
+ isVisible,
22
+ show,
23
+ hide
24
+ };
25
+ }
package/core/env.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ declare module '*.vue' {
4
+ import type { DefineComponent } from 'vue';
5
+ const component: DefineComponent<{}, {}, any>;
6
+ export default component;
7
+ }
package/core/index.js ADDED
@@ -0,0 +1,4 @@
1
+ import * as components from './components/index.js';
2
+ import * as composables from './composables/index.js';
3
+
4
+ export { components, composables };
package/core/index.ts ADDED
@@ -0,0 +1,85 @@
1
+ // Explicitly collect components and composables into objects so consumers
2
+ // can reference `core.components` and `core.composables` at runtime.
3
+ import ActionBar from './components/ActionBar.vue';
4
+ import Page from './components/Page.vue';
5
+ import Frame from './components/Frame.vue';
6
+ import StackLayout from './components/StackLayout.vue';
7
+ import GridLayout from './components/GridLayout.vue';
8
+ import FlexboxLayout from './components/FlexboxLayout.vue';
9
+ import WrapLayout from './components/WrapLayout.vue';
10
+ import ScrollView from './components/ScrollView.vue';
11
+ import Label from './components/Label.vue';
12
+ import Button from './components/Button.vue';
13
+ import Image from './components/Image.vue';
14
+ import HtmlView from './components/HtmlView.vue';
15
+ import ImageCacheIt from './components/ImageCacheIt.vue';
16
+ import TabView from './components/TabView.vue';
17
+ import TabViewItem from './components/TabViewItem.vue';
18
+ import RootLayout from './components/RootLayout.vue';
19
+ import DockLayout from './components/DockLayout.vue';
20
+ import AbsoluteLayout from './components/AbsoluteLayout.vue';
21
+ import ActionItem from './components/ActionItem.vue';
22
+ import NavigationButton from './components/NavigationButton.vue';
23
+ import ActivityIndicator from './components/ActivityIndicator.vue';
24
+ import DatePicker from './components/DatePicker.vue';
25
+ import TimePicker from './components/TimePicker.vue';
26
+ import ListPicker from './components/ListPicker.vue';
27
+ import ListView from './components/ListView.vue';
28
+ import Placeholder from './components/Placeholder.vue';
29
+ import Progress from './components/Progress.vue';
30
+ import SearchBar from './components/SearchBar.vue';
31
+ import SegmentedBar from './components/SegmentedBar.vue';
32
+ import SegmentedBarItem from './components/SegmentedBarItem.vue';
33
+ import Slider from './components/Slider.vue';
34
+ import SwitchComp from './components/Switch.vue';
35
+ import TextField from './components/TextField.vue';
36
+ import TextView from './components/TextView.vue';
37
+ import WebView from './components/WebView.vue';
38
+
39
+ export const components = {
40
+ ActionBar,
41
+ Page,
42
+ Frame,
43
+ StackLayout,
44
+ GridLayout,
45
+ FlexboxLayout,
46
+ WrapLayout,
47
+ ScrollView,
48
+ Label,
49
+ Button,
50
+ Image,
51
+ HtmlView,
52
+ ImageCacheIt,
53
+ TabView,
54
+ TabViewItem,
55
+ RootLayout,
56
+ DockLayout,
57
+ AbsoluteLayout,
58
+ ActionItem,
59
+ NavigationButton,
60
+ ActivityIndicator,
61
+ DatePicker,
62
+ TimePicker,
63
+ ListPicker,
64
+ ListView,
65
+ Placeholder,
66
+ Progress,
67
+ SearchBar,
68
+ SegmentedBar,
69
+ SegmentedBarItem,
70
+ Slider,
71
+ Switch: SwitchComp,
72
+ TextField,
73
+ TextView,
74
+ WebView,
75
+ };
76
+
77
+ import * as composablesNS from './composables';
78
+ export const composables = composablesNS;
79
+
80
+ // Re-export types for convenience
81
+ export * from './types';
82
+
83
+ // Also provide the original named exports for compatibility
84
+ export { ActionBar, Page, Frame, StackLayout, GridLayout, FlexboxLayout, WrapLayout, ScrollView, Label, Button, Image, HtmlView, ImageCacheIt, TabView, TabViewItem };
85
+ export { RootLayout, DockLayout, AbsoluteLayout, ActionItem, NavigationButton, ActivityIndicator, DatePicker, TimePicker, ListPicker, ListView, Placeholder, Progress, SearchBar, SegmentedBar, SegmentedBarItem, Slider, SwitchComp as Switch, TextField, TextView, WebView };
package/core/types.ts ADDED
@@ -0,0 +1,12 @@
1
+ import type { DefineComponent } from 'vue';
2
+ import type { FrameState } from './composables/useFrame';
3
+ import type { PageState } from './composables/usePage';
4
+ import type { ActionBarState } from './composables/useActionBar';
5
+
6
+ // 重新导出Vue组件类型
7
+ export type ActionBarComponent = DefineComponent;
8
+ export type PageComponent = DefineComponent;
9
+ export type FrameComponent = DefineComponent;
10
+
11
+ // 重新导出composables类型
12
+ export type { FrameState, PageState, ActionBarState };
@@ -0,0 +1,83 @@
1
+ import { defineComponent as r, createElementBlock as s, openBlock as c, renderSlot as a, ref as u } from "vue";
2
+ const f = { class: "ns-actionbar" }, p = /* @__PURE__ */ r({
3
+ name: "ActionBar",
4
+ __name: "ActionBar",
5
+ setup(e) {
6
+ return (t, o) => (c(), s("header", f, [
7
+ a(t.$slots, "default", {}, void 0, !0)
8
+ ]));
9
+ }
10
+ }), _ = (e, t) => {
11
+ const o = e.__vccOpts || e;
12
+ for (const [n, d] of t)
13
+ o[n] = d;
14
+ return o;
15
+ }, m = /* @__PURE__ */ _(p, [["__scopeId", "data-v-f29dfd84"]]), v = { class: "ns-page" }, b = /* @__PURE__ */ r({
16
+ name: "Page",
17
+ __name: "Page",
18
+ setup(e) {
19
+ return (t, o) => (c(), s("div", v, [
20
+ a(t.$slots, "default", {}, void 0, !0)
21
+ ]));
22
+ }
23
+ }), g = /* @__PURE__ */ _(b, [["__scopeId", "data-v-87719fa5"]]), h = { class: "ns-frame" }, $ = /* @__PURE__ */ r({
24
+ name: "Frame",
25
+ __name: "Frame",
26
+ setup(e) {
27
+ return (t, o) => (c(), s("div", h, [
28
+ a(t.$slots, "default", {}, void 0, !0)
29
+ ]));
30
+ }
31
+ }), O = /* @__PURE__ */ _($, [["__scopeId", "data-v-a66356e7"]]), i = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
32
+ __proto__: null,
33
+ ActionBar: m,
34
+ Frame: O,
35
+ Page: g
36
+ }, Symbol.toStringTag, { value: "Module" }));
37
+ function P() {
38
+ const e = u("");
39
+ function t(o) {
40
+ e.value = o;
41
+ }
42
+ return { title: e, setTitle: t };
43
+ }
44
+ function j() {
45
+ const e = u(!0);
46
+ function t() {
47
+ e.value = !0;
48
+ }
49
+ function o() {
50
+ e.value = !1;
51
+ }
52
+ return { isVisible: e, show: t, hide: o };
53
+ }
54
+ function y() {
55
+ const e = u([]);
56
+ function t(n) {
57
+ e.value.push(n);
58
+ }
59
+ function o() {
60
+ return e.value.pop();
61
+ }
62
+ return { stack: e, push: t, pop: o };
63
+ }
64
+ const l = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
65
+ __proto__: null,
66
+ useActionBar: P,
67
+ useFrame: y,
68
+ usePage: j
69
+ }, Symbol.toStringTag, { value: "Module" })), x = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
70
+ __proto__: null,
71
+ components: i,
72
+ composables: l
73
+ }, Symbol.toStringTag, { value: "Module" })), B = {
74
+ install(e) {
75
+ Object.entries(i || {}).forEach(([t, o]) => {
76
+ e.component(t, o);
77
+ }), e.config.globalProperties.$ns = l || {};
78
+ }
79
+ };
80
+ export {
81
+ x as core,
82
+ B as default
83
+ };
@@ -0,0 +1 @@
1
+ (function(r,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(r=typeof globalThis<"u"?globalThis:r||self,e(r.NativeScriptWebAdapter={},r.Vue))})(this,function(r,e){"use strict";const l={class:"ns-actionbar"},_=e.defineComponent({name:"ActionBar",__name:"ActionBar",setup(t){return(n,o)=>(e.openBlock(),e.createElementBlock("header",l,[e.renderSlot(n.$slots,"default",{},void 0,!0)]))}}),c=(t,n)=>{const o=t.__vccOpts||t;for(const[s,$]of n)o[s]=$;return o},u=c(_,[["__scopeId","data-v-f29dfd84"]]),d={class:"ns-page"},f=c(e.defineComponent({name:"Page",__name:"Page",setup(t){return(n,o)=>(e.openBlock(),e.createElementBlock("div",d,[e.renderSlot(n.$slots,"default",{},void 0,!0)]))}}),[["__scopeId","data-v-87719fa5"]]),p={class:"ns-frame"},a=Object.freeze(Object.defineProperty({__proto__:null,ActionBar:u,Frame:c(e.defineComponent({name:"Frame",__name:"Frame",setup(t){return(n,o)=>(e.openBlock(),e.createElementBlock("div",p,[e.renderSlot(n.$slots,"default",{},void 0,!0)]))}}),[["__scopeId","data-v-a66356e7"]]),Page:f},Symbol.toStringTag,{value:"Module"}));function m(){const t=e.ref("");function n(o){t.value=o}return{title:t,setTitle:n}}function b(){const t=e.ref(!0);function n(){t.value=!0}function o(){t.value=!1}return{isVisible:t,show:n,hide:o}}function g(){const t=e.ref([]);function n(s){t.value.push(s)}function o(){return t.value.pop()}return{stack:t,push:n,pop:o}}const i=Object.freeze(Object.defineProperty({__proto__:null,useActionBar:m,useFrame:g,usePage:b},Symbol.toStringTag,{value:"Module"})),h=Object.freeze(Object.defineProperty({__proto__:null,components:a,composables:i},Symbol.toStringTag,{value:"Module"})),S={install(t){Object.entries(a||{}).forEach(([n,o])=>{t.component(n,o)}),t.config.globalProperties.$ns=i||{}}};r.core=h,r.default=S,Object.defineProperties(r,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ .ns-actionbar[data-v-f29dfd84]{background:#1f1140;color:#fff;padding:12px}.ns-page[data-v-87719fa5]{top:0;left:0;position:absolute;width:100%;min-height:100%;padding:0}
package/package.json CHANGED
@@ -1,61 +1,47 @@
1
1
  {
2
2
  "name": "nativescript-web-adapter",
3
- "version": "0.1.2",
4
- "repository": {
5
- "type": "git",
6
- "url": "https://github.com/ponzS/NativeScript-for-web.git"
7
- },
8
- "bugs": {
9
- "url": "https://github.com/ponzS/NativeScript-for-web/issues"
10
- },
11
- "homepage": "https://github.com/ponzS/NativeScript-for-web#readme",
12
- "files": [
13
- "dist",
14
- "README.md"
15
- ],
16
- "description": "Web adapter for NativeScript UI components (Vue 3)",
17
- "license": "MIT",
3
+ "version": "0.1.3",
4
+ "description": "Web adapter for NativeScript applications",
18
5
  "type": "module",
19
- "main": "dist/index.cjs",
20
- "module": "dist/index.js",
21
- "types": "dist/types/index.d.ts",
6
+ "main": "./dist/nativescript-web-adapter.umd.js",
7
+ "module": "./dist/nativescript-web-adapter.es.js",
8
+ "types": "./dist/index.d.ts",
22
9
  "exports": {
23
10
  ".": {
24
- "import": "./dist/index.js",
25
- "require": "./dist/index.cjs",
26
- "types": "./dist/types/index.d.ts"
27
- },
28
- "./vue": {
29
- "import": "./dist/vue.js",
30
- "require": "./dist/vue.cjs",
31
- "types": "./dist/types/vue.d.ts"
32
- },
33
- "./core": {
34
- "import": "./dist/core.js",
35
- "require": "./dist/core.cjs",
36
- "types": "./dist/types/core/index.d.ts"
37
- },
38
- "./vue.css": "./dist/vue.css",
39
- "./index.css": "./dist/index.css"
11
+ "import": "./dist/nativescript-web-adapter.es.js",
12
+ "require": "./dist/nativescript-web-adapter.umd.js",
13
+ "types": "./dist/index.d.ts"
14
+ }
40
15
  },
41
16
  "scripts": {
42
- "build": "rimraf dist && rollup -c",
43
- "types": "tsc -p tsconfig.json",
44
- "test": "vitest run",
45
- "dev": "vitest",
46
- "bt": "npm run build && npm run types"
17
+ "create:web": "node tools/create-web-platform.cjs",
18
+ "dev": "vite",
19
+ "build": "vite build",
20
+ "preview": "vite preview",
21
+ "type-check": "vue-tsc --noEmit",
22
+ "prepublishOnly": "npm run build"
47
23
  },
48
- "peerDependencies": {
49
- "vue": "^3.4.0"
24
+ "bin": {
25
+ "ns-web": "./tools/cli.cjs"
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "tools",
30
+ "templates",
31
+ "core"
32
+ ],
33
+ "dependencies": {
34
+ "vue": "^3.4.0",
35
+ "commander": "^11.0.0"
50
36
  },
51
37
  "devDependencies": {
52
- "@rollup/plugin-typescript": "^11.1.6",
53
- "rimraf": "^6.0.1",
54
- "rollup": "^4.22.0",
55
- "rollup-plugin-dts": "^6.0.2",
56
- "rollup-plugin-postcss": "^4.0.2",
57
- "tslib": "^2.6.3",
58
- "typescript": "~5.9.0",
59
- "vitest": "^2.0.5"
38
+ "@types/node": "^20.0.0",
39
+ "typescript": "^5.0.0",
40
+ "@vitejs/plugin-vue": "^5.0.0",
41
+ "vite": "^5.0.0",
42
+ "vue-tsc": "^1.8.0"
43
+ },
44
+ "peerDependencies": {
45
+ "vue": "^3.0.0"
60
46
  }
61
47
  }
package/tools/cli.cjs ADDED
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ const { program } = require('commander');
3
+ const { createWebPlatform } = require('./create-web-platform.cjs');
4
+ const path = require('path');
5
+ const { execSync } = require('child_process');
6
+
7
+ program
8
+ .name('ns-web')
9
+ .description('CLI工具用于创建和管理NativeScript应用的web平台')
10
+ .version('1.0.0');
11
+
12
+ program
13
+ .command('init')
14
+ .description('为NativeScript项目初始化web平台支持')
15
+ .action(async () => {
16
+ await createWebPlatform();
17
+ });
18
+
19
+ program
20
+ .command('build')
21
+ .description('生成web平台并在 platforms/web 内构建')
22
+ .option('--skip-install', '跳过依赖安装')
23
+ .action(async (opts) => {
24
+ await createWebPlatform();
25
+ const webDir = path.join(process.cwd(), 'platforms', 'web');
26
+ if (!opts.skipInstall) {
27
+ execSync('npm install', { stdio: 'inherit', cwd: webDir });
28
+ }
29
+ execSync('npm run build', { stdio: 'inherit', cwd: webDir });
30
+ });
31
+
32
+ program
33
+ .command('dev')
34
+ .description('生成web平台并在 platforms/web 内启动开发服务器')
35
+ .option('--skip-install', '跳过依赖安装')
36
+ .action(async (opts) => {
37
+ await createWebPlatform();
38
+ const webDir = path.join(process.cwd(), 'platforms', 'web');
39
+ if (!opts.skipInstall) {
40
+ execSync('npm install', { stdio: 'inherit', cwd: webDir });
41
+ }
42
+ execSync('npm run dev', { stdio: 'inherit', cwd: webDir });
43
+ });
44
+
45
+ program.parse();
@@ -0,0 +1,76 @@
1
+ console.log('[web-adapter] create-web-platform.cjs 脚本已启动');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ // 模块入口(全部实现下沉到 modules/*)
6
+ const copy = require('./modules/copy.cjs');
7
+ const transform = require('./modules/transform.cjs');
8
+ const routerGen = require('./modules/router.cjs');
9
+ const appPatch = require('./modules/appPatch.cjs');
10
+ const templates = require('./modules/templates.cjs');
11
+
12
+ function createWebPlatform(options = {}) {
13
+ const adapterDir = path.resolve(__dirname, '..');
14
+ // 当作为 node_modules 使用时,项目根应为当前工作目录
15
+ const projectRoot = options.projectRoot ? path.resolve(options.projectRoot) : process.cwd();
16
+ const platformsDir = path.join(projectRoot, 'platforms');
17
+ const webDir = path.join(platformsDir, 'web');
18
+ const srcDir = path.join(projectRoot, 'src');
19
+
20
+ console.log('[web-adapter] 项目根目录:', projectRoot);
21
+ console.log('[web-adapter] platforms 目录:', platformsDir);
22
+ console.log('[web-adapter] web 目录:', webDir);
23
+ console.log('[web-adapter] src 目录:', srcDir);
24
+
25
+ try {
26
+ if (!fs.existsSync(webDir)) {
27
+ fs.mkdirSync(webDir, { recursive: true });
28
+ console.log('[web-adapter] 已创建 web 目录');
29
+ } else {
30
+ console.log('[web-adapter] web 目录已存在');
31
+ }
32
+
33
+ // 1) 复制源码(仅脚本层转换,保留模板标签)
34
+ copy.copySourceFiles(srcDir, path.join(webDir, 'src'), transform.transformContent);
35
+ console.log('[web-adapter] 已复制 src 源代码');
36
+
37
+ // 2) 复制适配器 web 组件与 composables
38
+ const adapterComponentsDir = path.join(adapterDir, 'core', 'components');
39
+ const targetComponentsDir = path.join(webDir, 'src', 'components', 'websfc');
40
+ copy.copyAdapterComponents(adapterComponentsDir, targetComponentsDir);
41
+ console.log('[web-adapter] 已复制适配器组件到 websfc');
42
+
43
+ const adapterComposablesDir = path.join(adapterDir, 'core', 'composables');
44
+ const targetComposablesDir = path.join(webDir, 'src', 'composables', 'websfc');
45
+ copy.copyAdapterComposables(adapterComposablesDir, targetComposablesDir);
46
+ console.log('[web-adapter] 已复制适配器 composables 到 websfc');
47
+
48
+ // 3) 写入 web 项目模板(index.html、package.json、vite.config、postcss、tailwind、App.vue)
49
+ templates.createWebPlatformFiles(webDir);
50
+ console.log('[web-adapter] 已生成 web 平台模板与配置');
51
+
52
+ // 4) 生成路由(根据 pages 目录)
53
+ const routerDirPath = path.join(webDir, 'src', 'router');
54
+ if (!fs.existsSync(routerDirPath)) {
55
+ fs.mkdirSync(routerDirPath, { recursive: true });
56
+ }
57
+ const routerContent = routerGen.buildRouterFromPages(webDir);
58
+ fs.writeFileSync(path.join(routerDirPath, 'index.ts'), routerContent, 'utf8');
59
+ console.log('[web-adapter] 已创建路由配置');
60
+
61
+ // 5) 修补 app.ts:注册所有 Web 适配组件并挂载应用
62
+ appPatch.patchAppForWeb(webDir);
63
+ console.log('[web-adapter] 正在安装依赖项...');
64
+
65
+ // 如需安装依赖,可在此调用(默认跳过以加快生成速度)
66
+ // installDependencies(webDir);
67
+ } catch (err) {
68
+ console.error('[web-adapter] 生成 web 平台时出错:', err);
69
+ }
70
+ }
71
+
72
+ module.exports = { createWebPlatform };
73
+
74
+ if (require.main === module) {
75
+ createWebPlatform();
76
+ }