transone-cli 0.3.1 → 0.5.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.
@@ -1,4 +1,7 @@
1
1
  // @bun
2
+ import {
3
+ loadTypescript
4
+ } from "./index-k1qfvp0y.js";
2
5
  import {
3
6
  __require
4
7
  } from "./index-yb2wsc7f.js";
@@ -9,6 +12,7 @@ var TARGET_TYPES = [
9
12
  "mp-weixin",
10
13
  "mp-alipay",
11
14
  "mp-bytedance",
15
+ "mp-xiaohongshu",
12
16
  "app-ios",
13
17
  "app-android",
14
18
  "app-harmony"
@@ -19,8 +23,17 @@ function isTargetType(value) {
19
23
  var MP_TARGET_TYPES = [
20
24
  "mp-weixin",
21
25
  "mp-alipay",
22
- "mp-bytedance"
26
+ "mp-bytedance",
27
+ "mp-xiaohongshu"
28
+ ];
29
+ var APP_TARGET_TYPES = [
30
+ "app-ios",
31
+ "app-android",
32
+ "app-harmony"
23
33
  ];
34
+ function isAppTargetType(value) {
35
+ return typeof value === "string" && APP_TARGET_TYPES.includes(value);
36
+ }
24
37
  function isMpTargetType(value) {
25
38
  return typeof value === "string" && MP_TARGET_TYPES.includes(value);
26
39
  }
@@ -72,7 +85,8 @@ async function resolveConfig(options = {}) {
72
85
  includeEntry: false,
73
86
  allowRoot: true
74
87
  }) : pages;
75
- const mpEnabled = config.mp !== undefined || target === "mp-weixin";
88
+ const mpEnabled = config.mp !== undefined || isMpTargetType(target);
89
+ const appConfig = pickAppConfig(config.app, target);
76
90
  return {
77
91
  root,
78
92
  ...loadedConfig.exists ? { configFile } : {},
@@ -92,25 +106,64 @@ async function resolveConfig(options = {}) {
92
106
  ...config.library ? { library: resolveLibrary(root, config.library) } : {},
93
107
  ...mpEnabled ? {
94
108
  mp: resolveMiniProgram(root, options.mpOutDir, mpConfig ?? {}, mpPages, target)
95
- } : {}
109
+ } : {},
110
+ ...isAppTargetType(target) ? { app: await resolveApp(root, options.outDir, appConfig ?? {}, target, pages) } : {}
111
+ };
112
+ }
113
+ function isAppConfigMap(value) {
114
+ return isRecord(value) && APP_TARGET_TYPES.some((platform) => (platform in value));
115
+ }
116
+ function pickAppConfig(app, target) {
117
+ if (app === undefined) {
118
+ return;
119
+ }
120
+ if (isAppConfigMap(app)) {
121
+ return isAppTargetType(target) ? app[target] : undefined;
122
+ }
123
+ return app;
124
+ }
125
+ async function resolveApp(root, outDirOverride, app, target, fallbackPages) {
126
+ return {
127
+ appName: app.appName ?? "TransOne",
128
+ bundleId: app.bundleId ?? "com.transone.app",
129
+ outDir: resolve(root, outDirOverride ?? app.outDir ?? `dist/build/${target}`),
130
+ minPlatformVersion: app.minPlatformVersion ?? "16.0",
131
+ publicDir: resolve(root, app.publicDir ?? "public"),
132
+ pages: app.pages ? await resolvePages(root, resolve(root, app.pages["/"] ?? "src/main.ts"), app.pages, {
133
+ includeEntry: false,
134
+ allowRoot: true
135
+ }) : fallbackPages
96
136
  };
97
137
  }
98
138
  var MP_DEFAULT_OUT_DIRS = {
99
139
  "mp-weixin": "dist/build/mp-weixin",
100
140
  "mp-alipay": "dist/build/mp-alipay",
101
- "mp-bytedance": "dist/build/mp-bytedance"
141
+ "mp-bytedance": "dist/build/mp-bytedance",
142
+ "mp-xiaohongshu": "dist/build/mp-xiaohongshu"
102
143
  };
103
- function isMpConfigMap(value) {
104
- return isRecord(value) && MP_TARGET_TYPES.some((platform) => (platform in value));
105
- }
106
144
  function pickMpConfig(mp, target) {
107
145
  if (mp === undefined) {
108
146
  return;
109
147
  }
110
- if (isMpConfigMap(mp)) {
111
- return isMpTargetType(target) ? mp[target] : undefined;
148
+ const common = Object.fromEntries(Object.entries(mp).filter(([key]) => !MP_TARGET_TYPES.includes(key)));
149
+ const platform = isMpTargetType(target) ? mp[target] : undefined;
150
+ return mergeMpRecords(common, { ...platform });
151
+ }
152
+ function mergeMpRecords(common, overrides) {
153
+ const merged = { ...common };
154
+ for (const [key, value] of Object.entries(overrides)) {
155
+ if (value === undefined)
156
+ continue;
157
+ const previous = Object.prototype.hasOwnProperty.call(common, key) ? common[key] : undefined;
158
+ const next = isRecord(previous) && isRecord(value) ? mergeMpRecords(previous, value) : value;
159
+ Object.defineProperty(merged, key, {
160
+ value: next,
161
+ enumerable: true,
162
+ configurable: true,
163
+ writable: true
164
+ });
112
165
  }
113
- return mp;
166
+ return merged;
114
167
  }
115
168
  function resolveMiniProgram(root, outDirOverride, mp, pages, target) {
116
169
  return {
@@ -154,7 +207,7 @@ function resolveTarget(target) {
154
207
  if (isTargetType(target)) {
155
208
  return target;
156
209
  }
157
- throw new Error(`Unknown build target "${String(target)}". ` + "Available targets: web, mp-weixin, mp-alipay, mp-bytedance, " + "app-ios, app-android, app-harmony.");
210
+ throw new Error(`Unknown build target "${String(target)}". ` + "Available targets: web, mp-weixin, mp-alipay, mp-bytedance, mp-xiaohongshu, " + "app-ios, app-android, app-harmony.");
158
211
  }
159
212
  async function resolvePages(root, entry, pages, options = {}) {
160
213
  const resolved = options.includeEntry === false ? {} : { "/": entry };
@@ -231,7 +284,8 @@ function mergeConfig(...configs) {
231
284
  directoryPages: build?.directoryPages ?? merged.build.directoryPages
232
285
  },
233
286
  library: config.library ?? merged.library,
234
- mp: config.mp ?? merged.mp
287
+ mp: config.mp ?? merged.mp,
288
+ app: config.app ?? merged.app
235
289
  };
236
290
  }, DEFAULT_CONFIG);
237
291
  }
@@ -255,19 +309,45 @@ function validateUserConfig(config) {
255
309
  if (config.mp !== undefined) {
256
310
  validateMpConfig(config.mp);
257
311
  }
312
+ if (config.app !== undefined) {
313
+ validateAppConfig(config.app);
314
+ }
258
315
  }
259
- function validateMpConfig(mp) {
260
- assertRecord(mp, "Config mp");
261
- if (isMpConfigMap(mp)) {
262
- for (const platform of MP_TARGET_TYPES) {
263
- const platformConfig = mp[platform];
264
- if (platformConfig !== undefined) {
265
- validateMiniProgramConfig(platformConfig, `Config mp.${platform}`);
316
+ function validateAppConfig(app) {
317
+ assertRecord(app, "Config app");
318
+ if (isAppConfigMap(app)) {
319
+ const flatKeys = ["appName", "bundleId", "outDir", "minPlatformVersion", "publicDir", "pages"];
320
+ if (flatKeys.some((key) => (key in app))) {
321
+ throw new Error("Config app cannot mix flat fields with platform keys");
322
+ }
323
+ for (const platform of APP_TARGET_TYPES) {
324
+ if (app[platform] !== undefined) {
325
+ validateSingleAppConfig(app[platform], `Config app.${platform}`);
266
326
  }
267
327
  }
268
328
  return;
269
329
  }
330
+ validateSingleAppConfig(app, "Config app");
331
+ }
332
+ function validateSingleAppConfig(app, label) {
333
+ assertRecord(app, label);
334
+ for (const key of ["appName", "bundleId", "outDir", "minPlatformVersion", "publicDir"]) {
335
+ if (app[key] !== undefined && typeof app[key] !== "string") {
336
+ throw new Error(`${label}.${key} must be a string`);
337
+ }
338
+ }
339
+ if (app.pages !== undefined) {
340
+ validatePagesConfig(app.pages, `${label}.pages`);
341
+ }
342
+ }
343
+ function validateMpConfig(mp) {
344
+ assertRecord(mp, "Config mp");
270
345
  validateMiniProgramConfig(mp, "Config mp");
346
+ for (const platform of MP_TARGET_TYPES) {
347
+ if (mp[platform] !== undefined) {
348
+ validateMiniProgramConfig(mp[platform], `Config mp.${platform}`);
349
+ }
350
+ }
271
351
  }
272
352
  function validateMiniProgramConfig(mp, label) {
273
353
  assertRecord(mp, label);
@@ -707,6 +787,35 @@ var MP_BYTEDANCE_DIALECT = {
707
787
  usingComponents
708
788
  })
709
789
  };
790
+ var MP_XIAOHONGSHU_DIALECT = {
791
+ id: "mp-xiaohongshu",
792
+ label: "\u5C0F\u7EA2\u4E66\u5C0F\u7A0B\u5E8F\u539F\u751F\u5DE5\u7A0B\uFF08XHSML / CSS / JS \u9759\u6001\u8F6C\u6362\uFF09",
793
+ templateExt: "xhsml",
794
+ styleExt: "css",
795
+ appStyleFile: "app.css",
796
+ directivePrefix: "xhs:",
797
+ bindEvent: (event) => `bind${event}`,
798
+ catchEvent: (event) => `catch${event}`,
799
+ projectConfigFile: "project.config.json",
800
+ buildProjectConfig: (mp, projectName) => ({
801
+ appid: mp.appId,
802
+ projectname: projectName,
803
+ compileType: "miniprogram"
804
+ }),
805
+ windowDefaults: (title) => ({
806
+ navigationBarTitleText: title,
807
+ navigationBarBackgroundColor: "#ffffff",
808
+ navigationBarTextStyle: "black",
809
+ backgroundTextStyle: "light"
810
+ }),
811
+ appJsonExtras: () => ({}),
812
+ sitemap: false,
813
+ componentJson: (usingComponents) => ({
814
+ component: true,
815
+ multipleSlots: true,
816
+ usingComponents
817
+ })
818
+ };
710
819
 
711
820
  // src/target/mp-target.ts
712
821
  class MpTarget {
@@ -724,29 +833,427 @@ class MpTarget {
724
833
  if (!config.mp) {
725
834
  throw new Error("Mini program build requires config.mp\uFF08\u8BF7\u5728 transone.config.ts \u914D\u7F6E mp \u5B57\u6BB5\uFF0C" + "\u5982 appId / pages / outDir\uFF09");
726
835
  }
727
- const { buildMiniProgram } = await import("./build-mp-k1dgvwwx.js");
836
+ const { buildMiniProgram } = await import("./build-mp-6j38wf4r.js");
728
837
  return buildMiniProgram(config, this.dialect);
729
838
  }
730
839
  }
731
840
  var mpWeixinTarget = new MpTarget(MP_WEIXIN_DIALECT);
732
841
  var mpAlipayTarget = new MpTarget(MP_ALIPAY_DIALECT);
733
842
  var mpBytedanceTarget = new MpTarget(MP_BYTEDANCE_DIALECT);
843
+ var mpXiaohongshuTarget = new MpTarget(MP_XIAOHONGSHU_DIALECT);
844
+
845
+ // src/app/build-app.ts
846
+ import { cp, mkdir as mkdir2, rm as rm2, writeFile as writeFile2 } from "fs/promises";
847
+ import { existsSync as existsSync3 } from "fs";
848
+ import { dirname as dirname3, join, resolve as resolve4 } from "path";
734
849
 
735
- // src/target/placeholder-target.ts
736
- class PlaceholderTarget {
737
- type;
738
- label;
739
- plannedMilestone;
740
- constructor(type, label, plannedMilestone) {
741
- this.type = type;
742
- this.label = label;
743
- this.plannedMilestone = plannedMilestone;
850
+ // src/app/errors.ts
851
+ import { basename } from "path";
852
+ function nativeError(filePath, message) {
853
+ return new Error(`[transone app] ${basename(filePath)}: ${message}`);
854
+ }
855
+
856
+ // src/app/analyze.ts
857
+ import { existsSync as existsSync2, readFileSync } from "fs";
858
+ var CONTAINERS = new Set(["view", "main", "div"]);
859
+ var TEXT = new Set(["text", "span", "p", "h1"]);
860
+ var STYLE_KEYS = new Set(["color", "backgroundColor", "fontSize", "fontWeight", "padding", "margin", "width", "height", "borderRadius", "textAlign"]);
861
+ async function analyzeNativeScreen(entry) {
862
+ if (!existsSync2(entry))
863
+ throw nativeError(entry, "\u6E90\u6587\u4EF6\u4E0D\u5B58\u5728");
864
+ const ts = await loadTypescript();
865
+ const source = ts.createSourceFile(entry, readFileSync(entry, "utf8"), ts.ScriptTarget.Latest, true);
866
+ const component = source.statements.find((s) => ts.isClassDeclaration(s));
867
+ if (!component)
868
+ throw nativeError(entry, "\u672A\u627E\u5230 Component \u7C7B");
869
+ const state = readState(ts, component, entry);
870
+ const actions = new Map;
871
+ for (const member of component.members)
872
+ if (ts.isMethodDeclaration(member) && ts.isIdentifier(member.name)) {
873
+ const action = readAction(ts, member, entry);
874
+ if (action)
875
+ actions.set(member.name.text, action);
876
+ }
877
+ const render = component.members.find((m) => ts.isMethodDeclaration(m) && m.name.getText(source) === "render");
878
+ const value = render?.body?.statements.find(ts.isReturnStatement)?.expression;
879
+ if (!value || !ts.isObjectLiteralExpression(value))
880
+ throw nativeError(entry, "render() \u5FC5\u987B\u8FD4\u56DE\u9759\u6001 VNode \u5BF9\u8C61");
881
+ const root = readNode(ts, value, entry, new Set(state.map((item) => item.key)), actions);
882
+ if (root.kind !== "container")
883
+ throw nativeError(entry, "\u6839\u8282\u70B9\u5FC5\u987B\u662F\u5BB9\u5668\u8282\u70B9");
884
+ return { name: component.name?.text ?? "App", state, root };
885
+ }
886
+ function readState(ts, component, file) {
887
+ const method = component.members.find((m) => ts.isMethodDeclaration(m) && m.name.getText() === "initState");
888
+ const value = method?.body?.statements.find(ts.isReturnStatement)?.expression;
889
+ if (!value)
890
+ return [];
891
+ if (!ts.isObjectLiteralExpression(value))
892
+ throw nativeError(file, "initState() \u5FC5\u987B\u8FD4\u56DE\u5BF9\u8C61\u5B57\u9762\u91CF");
893
+ return value.properties.map((item) => {
894
+ if (!ts.isPropertyAssignment(item) || !ts.isIdentifier(item.name))
895
+ throw nativeError(file, "state \u5FC5\u987B\u4F7F\u7528\u6807\u8BC6\u7B26\u5C5E\u6027");
896
+ const literal = literalValue(ts, item.initializer);
897
+ if (literal === undefined)
898
+ throw nativeError(file, `state.${item.name.text} \u5FC5\u987B\u662F\u5B57\u9762\u91CF`);
899
+ return { key: item.name.text, value: literal };
900
+ });
901
+ }
902
+ function readAction(ts, method, file) {
903
+ const expression = method.body?.statements[0];
904
+ if (!expression || !ts.isExpressionStatement(expression) || !ts.isBinaryExpression(expression.expression))
905
+ return;
906
+ const binary = expression.expression;
907
+ if (!ts.isPropertyAccessExpression(binary.left) || !ts.isPropertyAccessExpression(binary.left.expression) || binary.left.expression.expression.kind !== ts.SyntaxKind.ThisKeyword || binary.left.expression.name.text !== "state")
908
+ return;
909
+ const value = literalValue(ts, binary.right);
910
+ const key = binary.left.name.text;
911
+ if ((binary.operatorToken.kind === ts.SyntaxKind.PlusEqualsToken || binary.operatorToken.kind === ts.SyntaxKind.MinusEqualsToken) && typeof value === "number")
912
+ return { kind: "increment", key, by: binary.operatorToken.kind === ts.SyntaxKind.MinusEqualsToken ? -value : value };
913
+ if (binary.operatorToken.kind === ts.SyntaxKind.EqualsToken && value !== undefined)
914
+ return { kind: "set-literal", key, value };
915
+ throw nativeError(file, `\u65B9\u6CD5 ${method.name.getText()} \u4E0D\u652F\u6301\u539F\u751F\u7F16\u8BD1`);
916
+ }
917
+ function readNode(ts, node, file, state, actions) {
918
+ const tag = stringValue(ts, get(ts, node, "tag"), file, "VNode tag");
919
+ const style = readStyle(ts, get(ts, node, "props"), file);
920
+ const children = get(ts, node, "children");
921
+ const childNodes = children && ts.isArrayLiteralExpression(children) ? [...children.elements].filter(ts.isExpression) : [];
922
+ if (CONTAINERS.has(tag))
923
+ return { kind: "container", children: childNodes.map((child) => {
924
+ if (!ts.isObjectLiteralExpression(child))
925
+ throw nativeError(file, "\u5BB9\u5668 children \u53EA\u652F\u6301\u9759\u6001 VNode");
926
+ return readNode(ts, child, file, state, actions);
927
+ }), ...style ? { style } : {} };
928
+ const parts = childNodes.flatMap((child) => readText(ts, child, file, state));
929
+ if (TEXT.has(tag))
930
+ return { kind: "text", parts, ...style ? { style } : {} };
931
+ if (tag === "button")
932
+ return { kind: "button", parts, action: readClick(ts, get(ts, node, "listeners"), file, actions), ...style ? { style } : {} };
933
+ throw nativeError(file, `\u4E0D\u652F\u6301\u7684\u539F\u751F\u8282\u70B9: ${tag}`);
934
+ }
935
+ function readText(ts, expression, file, state) {
936
+ const value = literalValue(ts, expression);
937
+ if (typeof value !== "string")
938
+ throw nativeError(file, "\u6587\u672C children \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u5B57\u9762\u91CF");
939
+ const result = [];
940
+ const matcher = /{{([^}]+)}}/g;
941
+ let cursor = 0;
942
+ let match;
943
+ while (match = matcher.exec(value)) {
944
+ if (match.index > cursor)
945
+ result.push({ kind: "literal", value: value.slice(cursor, match.index) });
946
+ const key = match[1];
947
+ if (!/^[A-Za-z_$][\w$]*$/.test(key) || !state.has(key))
948
+ throw nativeError(file, "\u53EA\u652F\u6301\u5DF2\u58F0\u660E state \u7684 {{key}} \u7ED1\u5B9A");
949
+ result.push({ kind: "state", key });
950
+ cursor = matcher.lastIndex;
951
+ }
952
+ if (cursor < value.length || result.length === 0)
953
+ result.push({ kind: "literal", value: value.slice(cursor) });
954
+ return result;
955
+ }
956
+ function readClick(ts, listeners, file, actions) {
957
+ if (!listeners || !ts.isObjectLiteralExpression(listeners))
958
+ throw nativeError(file, "button \u5FC5\u987B\u58F0\u660E listeners.click");
959
+ const handler = get(ts, listeners, "click");
960
+ const body = handler && ts.isArrowFunction(handler) ? handler.body : undefined;
961
+ const expression = body && ts.isCallExpression(body) ? body : body && ts.isBlock(body) && ts.isExpressionStatement(body.statements[0]) ? body.statements[0].expression : undefined;
962
+ if (!expression || !ts.isCallExpression(expression) || !ts.isPropertyAccessExpression(expression.expression) || expression.expression.expression.kind !== ts.SyntaxKind.ThisKeyword)
963
+ throw nativeError(file, "click \u53EA\u652F\u6301\u8C03\u7528 this.method()");
964
+ const action = actions.get(expression.expression.name.text);
965
+ if (!action)
966
+ throw nativeError(file, `click \u65B9\u6CD5 ${expression.expression.name.text} \u4E0D\u652F\u6301\u539F\u751F\u7F16\u8BD1`);
967
+ return action;
968
+ }
969
+ function readStyle(ts, props, file) {
970
+ if (!props || !ts.isObjectLiteralExpression(props))
971
+ return;
972
+ const style = get(ts, props, "style");
973
+ if (!style || !ts.isObjectLiteralExpression(style))
974
+ return;
975
+ const out = {};
976
+ for (const item of style.properties) {
977
+ if (!ts.isPropertyAssignment(item) || !ts.isIdentifier(item.name) || !STYLE_KEYS.has(item.name.text))
978
+ throw nativeError(file, "\u4E0D\u652F\u6301\u7684\u539F\u751F\u6837\u5F0F\u5C5E\u6027");
979
+ const value = literalValue(ts, item.initializer);
980
+ const keyword = item.name.text === "color" || item.name.text === "backgroundColor" || item.name.text === "fontWeight" || item.name.text === "textAlign";
981
+ if (keyword && (typeof value === "string" || typeof value === "number")) {
982
+ out[item.name.text] = value;
983
+ continue;
984
+ }
985
+ if (typeof value !== "number" && !(typeof value === "string" && /^\d+(\.\d+)?px$/.test(value)))
986
+ throw nativeError(file, `\u6837\u5F0F ${item.name.text} \u53EA\u652F\u6301\u6570\u5B57\u6216 px`);
987
+ out[item.name.text] = typeof value === "string" ? Number.parseFloat(value) : value;
988
+ }
989
+ return out;
990
+ }
991
+ function get(ts, node, name) {
992
+ const item = node.properties.find((p) => ts.isPropertyAssignment(p) && p.name.getText().replace(/['"]/g, "") === name);
993
+ return item && ts.isPropertyAssignment(item) ? item.initializer : undefined;
994
+ }
995
+ function stringValue(ts, expression, file, label) {
996
+ const value = expression && literalValue(ts, expression);
997
+ if (typeof value !== "string")
998
+ throw nativeError(file, `${label} \u5FC5\u987B\u662F\u5B57\u7B26\u4E32`);
999
+ return value;
1000
+ }
1001
+ function literalValue(ts, value) {
1002
+ if (ts.isStringLiteral(value) || ts.isNoSubstitutionTemplateLiteral(value))
1003
+ return value.text;
1004
+ if (ts.isNumericLiteral(value))
1005
+ return Number(value.text);
1006
+ if (value.kind === ts.SyntaxKind.TrueKeyword)
1007
+ return true;
1008
+ if (value.kind === ts.SyntaxKind.FalseKeyword)
1009
+ return false;
1010
+ return;
1011
+ }
1012
+
1013
+ // src/app/build-app.ts
1014
+ async function buildNativeApp(config, dialect) {
1015
+ if (!config.app)
1016
+ throw new Error("Native app build requires config.app");
1017
+ const entries = Object.values(config.app.pages);
1018
+ if (entries.length !== 1)
1019
+ throw nativeError(config.entry, "\u9996\u671F\u539F\u751F App \u53EA\u652F\u6301\u4E00\u4E2A\u9875\u9762");
1020
+ const screen = await analyzeNativeScreen(entries[0]);
1021
+ const files = dialect.generateProject(screen, config.app);
1022
+ await rm2(config.app.outDir, { recursive: true, force: true });
1023
+ const assetsBuilt = [];
1024
+ for (const [relative3, content] of Object.entries(files).sort(([a], [b]) => a.localeCompare(b))) {
1025
+ const target = join(config.app.outDir, relative3);
1026
+ await mkdir2(dirname3(target), { recursive: true });
1027
+ await writeFile2(target, content, "utf8");
1028
+ assetsBuilt.push(target);
1029
+ }
1030
+ if (existsSync3(config.app.publicDir))
1031
+ await cp(config.app.publicDir, join(config.app.outDir, dialect.resourceDirectory), { recursive: true });
1032
+ return { root: config.root, outDir: resolve4(config.app.outDir), assetsBuilt };
1033
+ }
1034
+
1035
+ // src/target/app-target.ts
1036
+ class AppTarget {
1037
+ dialect;
1038
+ constructor(dialect) {
1039
+ this.dialect = dialect;
1040
+ }
1041
+ get type() {
1042
+ return this.dialect.id;
1043
+ }
1044
+ get label() {
1045
+ return this.dialect.label;
1046
+ }
1047
+ build(config, _options) {
1048
+ return buildNativeApp(config, this.dialect);
1049
+ }
1050
+ }
1051
+
1052
+ // src/app/dialects.ts
1053
+ function text(parts, language) {
1054
+ if (language === "swift") {
1055
+ const value = parts.map((part) => part.kind === "literal" ? part.value : `\\(${part.key})`).join("");
1056
+ return `"${value.replace(/"/g, "\\\"")}"`;
1057
+ }
1058
+ if (language === "kotlin") {
1059
+ return JSON.stringify(parts.map((part) => part.kind === "literal" ? part.value : `$${part.key}`).join(""));
1060
+ }
1061
+ return parts.map((part) => part.kind === "literal" ? JSON.stringify(part.value) : `this.${part.key}`).join(" + ") || '""';
1062
+ }
1063
+ function action(node, language) {
1064
+ const { action: action2 } = node;
1065
+ const target = language === "ark" ? `this.${action2.key}` : action2.key;
1066
+ return action2.kind === "increment" ? `${target} ${action2.by >= 0 ? "+=" : "-="} ${Math.abs(action2.by)}` : `${target} = ${typeof action2.value === "string" ? JSON.stringify(action2.value) : action2.value}`;
1067
+ }
1068
+ function swiftNode(node, indent = " ") {
1069
+ if (node.kind === "container")
1070
+ return `${indent}VStack {
1071
+ ${node.children.map((child) => swiftNode(child, `${indent} `)).join(`
1072
+ `)}
1073
+ ${indent}}`;
1074
+ if (node.kind === "text")
1075
+ return `${indent}Text(${text(node.parts, "swift")})`;
1076
+ return `${indent}Button(${text(node.parts, "swift")}) { ${action(node, "swift")} }`;
1077
+ }
1078
+ function kotlinNode(node, indent = " ") {
1079
+ if (node.kind === "container")
1080
+ return `${indent}Column {
1081
+ ${node.children.map((child) => kotlinNode(child, `${indent} `)).join(`
1082
+ `)}
1083
+ ${indent}}`;
1084
+ if (node.kind === "text")
1085
+ return `${indent}Text(${text(node.parts, "kotlin")})`;
1086
+ return `${indent}Button(onClick = { ${action(node, "kotlin")} }) { Text(${text(node.parts, "kotlin")}) }`;
1087
+ }
1088
+ function arkNode(node, indent = " ") {
1089
+ if (node.kind === "container")
1090
+ return `${indent}Column() {
1091
+ ${node.children.map((child) => arkNode(child, `${indent} `)).join(`
1092
+ `)}
1093
+ ${indent}}`;
1094
+ if (node.kind === "text")
1095
+ return `${indent}Text(${text(node.parts, "ark")})`;
1096
+ return `${indent}Button(${text(node.parts, "ark")}).onClick(() => { ${action(node, "ark")} })`;
1097
+ }
1098
+ function swiftState(screen) {
1099
+ return screen.state.map((item) => ` @State private var ${item.key}: ${typeof item.value === "number" ? "Int" : typeof item.value === "boolean" ? "Bool" : "String"} = ${JSON.stringify(item.value)}`).join(`
1100
+ `);
1101
+ }
1102
+ function kotlinState(screen) {
1103
+ return screen.state.map((item) => ` var ${item.key} by remember { mutableStateOf(${JSON.stringify(item.value)}) }`).join(`
1104
+ `);
1105
+ }
1106
+ function arkState(screen) {
1107
+ return screen.state.map((item) => ` @State ${item.key}: ${typeof item.value === "number" ? "number" : typeof item.value === "boolean" ? "boolean" : "string"} = ${JSON.stringify(item.value)}`).join(`
1108
+ `);
1109
+ }
1110
+ var IOS_DIALECT = {
1111
+ id: "app-ios",
1112
+ label: "iOS \u539F\u751F App\uFF08SwiftUI\uFF09",
1113
+ resourceDirectory: "TransOneApp/Assets",
1114
+ generateProject(screen, config) {
1115
+ return {
1116
+ "TransOneApp/TransOneApp.swift": `import SwiftUI
1117
+
1118
+ @main struct TransOneApp: App { var body: some Scene { WindowGroup { ContentView() } } }
1119
+ `,
1120
+ "TransOneApp/ContentView.swift": `import SwiftUI
1121
+
1122
+ struct ContentView: View {
1123
+ ${swiftState(screen)}
1124
+ var body: some View {
1125
+ ${swiftNode(screen.root)}
744
1126
  }
745
- async build(_config, _options) {
746
- const available = ["web"].map((target) => `'${target}'`).join(", ");
747
- throw new Error(`Target "${this.type}" (${this.label}) \u5C1A\u672A\u5B9E\u73B0\uFF0C\u9884\u8BA1\u5728 ${this.plannedMilestone} \u843D\u5730\u3002` + `\u5F53\u524D\u53EF\u7528\u76EE\u6807\u7AEF\uFF1A${available}\u3002`);
1127
+ }
1128
+ `,
1129
+ "TransOneApp.xcodeproj/project.pbxproj": xcodeProject(config),
1130
+ "TransOneApp/Assets.xcassets/Contents.json": `{"info":{"author":"xcode","version":1}}
1131
+ `
1132
+ };
748
1133
  }
1134
+ };
1135
+ function xcodeProject(config) {
1136
+ const escapedName = config.appName.replace(/"/g, "\\\"");
1137
+ return `// !$*UTF8*$!
1138
+ {
1139
+ archiveVersion = 1;
1140
+ classes = {};
1141
+ objectVersion = 56;
1142
+ objects = {
1143
+
1144
+ /* Begin PBXBuildFile section */
1145
+ A00100000000000000000001 /* TransOneApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A00100000000000000000011 /* TransOneApp.swift */; };
1146
+ A00100000000000000000002 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A00100000000000000000012 /* ContentView.swift */; };
1147
+ /* End PBXBuildFile section */
1148
+
1149
+ /* Begin PBXFileReference section */
1150
+ A00100000000000000000011 /* TransOneApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransOneApp.swift; sourceTree = "<group>"; };
1151
+ A00100000000000000000012 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
1152
+ A00100000000000000000013 /* TransOneApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TransOneApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
1153
+ /* End PBXFileReference section */
1154
+
1155
+ /* Begin PBXGroup section */
1156
+ A00100000000000000000021 = {isa = PBXGroup; children = (A00100000000000000000022 /* TransOneApp */, A00100000000000000000023 /* Products */, ); sourceTree = "<group>"; };
1157
+ A00100000000000000000022 /* TransOneApp */ = {isa = PBXGroup; children = (A00100000000000000000011 /* TransOneApp.swift */, A00100000000000000000012 /* ContentView.swift */, ); path = TransOneApp; sourceTree = "<group>"; };
1158
+ A00100000000000000000023 /* Products */ = {isa = PBXGroup; children = (A00100000000000000000013 /* TransOneApp.app */, ); name = Products; sourceTree = "<group>"; };
1159
+ /* End PBXGroup section */
1160
+
1161
+ /* Begin PBXNativeTarget section */
1162
+ A00100000000000000000031 /* TransOneApp */ = {isa = PBXNativeTarget; buildConfigurationList = A00100000000000000000041 /* Build configuration list for PBXNativeTarget "TransOneApp" */; buildPhases = (A00100000000000000000032 /* Sources */, A00100000000000000000033 /* Frameworks */, A00100000000000000000034 /* Resources */, ); buildRules = (); dependencies = (); name = TransOneApp; productName = TransOneApp; productReference = A00100000000000000000013 /* TransOneApp.app */; productType = "com.apple.product-type.application"; };
1163
+ /* End PBXNativeTarget section */
1164
+
1165
+ /* Begin PBXProject section */
1166
+ A00100000000000000000051 /* Project object */ = {isa = PBXProject; attributes = { LastUpgradeCheck = 2700; TargetAttributes = { A00100000000000000000031 = { CreatedOnToolsVersion = 27.0; }; }; }; buildConfigurationList = A00100000000000000000052 /* Build configuration list for PBXProject "TransOneApp" */; compatibilityVersion = "Xcode 14.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = (en, Base, ); mainGroup = A00100000000000000000021; productRefGroup = A00100000000000000000023; projectDirPath = ""; projectRoot = ""; targets = (A00100000000000000000031 /* TransOneApp */, ); };
1167
+ /* End PBXProject section */
1168
+
1169
+ /* Begin PBXResourcesBuildPhase section */
1170
+ A00100000000000000000034 /* Resources */ = {isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = (); runOnlyForDeploymentPostprocessing = 0; };
1171
+ /* End PBXResourcesBuildPhase section */
1172
+
1173
+ /* Begin PBXSourcesBuildPhase section */
1174
+ A00100000000000000000032 /* Sources */ = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = (A00100000000000000000001 /* TransOneApp.swift in Sources */, A00100000000000000000002 /* ContentView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };
1175
+ /* End PBXSourcesBuildPhase section */
1176
+
1177
+ /* Begin PBXFrameworksBuildPhase section */
1178
+ A00100000000000000000033 /* Frameworks */ = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = (); runOnlyForDeploymentPostprocessing = 0; };
1179
+ /* End PBXFrameworksBuildPhase section */
1180
+
1181
+ /* Begin XCBuildConfiguration section */
1182
+ A00100000000000000000061 /* Debug */ = {isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_MODULES = YES; SWIFT_VERSION = 5.0; }; name = Debug; };
1183
+ A00100000000000000000062 /* Release */ = {isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_MODULES = YES; SWIFT_VERSION = 5.0; }; name = Release; };
1184
+ A00100000000000000000063 /* Debug */ = {isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CODE_SIGNING_ALLOWED = NO; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = ${config.minPlatformVersion}; PRODUCT_BUNDLE_IDENTIFIER = ${config.bundleId}; PRODUCT_NAME = "${escapedName}"; SDKROOT = iphoneos; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; };
1185
+ A00100000000000000000064 /* Release */ = {isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CODE_SIGNING_ALLOWED = NO; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = ${config.minPlatformVersion}; PRODUCT_BUNDLE_IDENTIFIER = ${config.bundleId}; PRODUCT_NAME = "${escapedName}"; SDKROOT = iphoneos; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; };
1186
+ /* End XCBuildConfiguration section */
1187
+
1188
+ /* Begin XCConfigurationList section */
1189
+ A00100000000000000000041 /* Build configuration list for PBXNativeTarget "TransOneApp" */ = {isa = XCConfigurationList; buildConfigurations = (A00100000000000000000063 /* Debug */, A00100000000000000000064 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; };
1190
+ A00100000000000000000052 /* Build configuration list for PBXProject "TransOneApp" */ = {isa = XCConfigurationList; buildConfigurations = (A00100000000000000000061 /* Debug */, A00100000000000000000062 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; };
1191
+ /* End XCConfigurationList section */
1192
+ };
1193
+ rootObject = A00100000000000000000051 /* Project object */;
749
1194
  }
1195
+ `;
1196
+ }
1197
+ var ANDROID_DIALECT = {
1198
+ id: "app-android",
1199
+ label: "Android \u539F\u751F App\uFF08Jetpack Compose\uFF09",
1200
+ resourceDirectory: "app/src/main/assets",
1201
+ generateProject(screen, config) {
1202
+ const pkg = config.bundleId.replace(/[^A-Za-z0-9_.]/g, "_");
1203
+ const path = pkg.replace(/\./g, "/");
1204
+ return {
1205
+ "settings.gradle.kts": `rootProject.name = "${config.appName}"
1206
+ include(":app")
1207
+ `,
1208
+ "build.gradle.kts": `plugins { }
1209
+ `,
1210
+ "app/build.gradle.kts": `plugins { id("com.android.application") version "8.5.0" apply false }
1211
+ `,
1212
+ "app/src/main/AndroidManifest.xml": `<manifest package="${pkg}" xmlns:android="http://schemas.android.com/apk/res/android"><application android:label="${config.appName}"><activity android:name=".MainActivity" android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter></activity></application></manifest>
1213
+ `,
1214
+ [`app/src/main/java/${path}/MainActivity.kt`]: `package ${pkg}
1215
+
1216
+ import androidx.activity.ComponentActivity
1217
+ import androidx.activity.compose.setContent
1218
+ import androidx.compose.runtime.*
1219
+ import androidx.compose.foundation.layout.Column
1220
+ import androidx.compose.material3.*
1221
+
1222
+ class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: android.os.Bundle?) { super.onCreate(savedInstanceState); setContent {
1223
+ ${kotlinState(screen)}
1224
+ ${kotlinNode(screen.root)}
1225
+ } } }
1226
+ `
1227
+ };
1228
+ }
1229
+ };
1230
+ var HARMONY_DIALECT = {
1231
+ id: "app-harmony",
1232
+ label: "HarmonyOS \u539F\u751F App\uFF08ArkUI\uFF09",
1233
+ resourceDirectory: "entry/src/main/resources/rawfile",
1234
+ generateProject(screen, config) {
1235
+ return {
1236
+ "AppScope/app.json5": `{ "app": { "bundleName": "${config.bundleId}", "vendor": "TransOne", "versionCode": 1, "versionName": "1.0.0" } }
1237
+ `,
1238
+ "AppScope/resources/base/element/string.json": `{ "string": [{ "name": "app_name", "value": "${config.appName}" }] }
1239
+ `,
1240
+ "entry/src/main/module.json5": `{ "module": { "name": "entry", "type": "entry", "mainElement": "EntryAbility" } }
1241
+ `,
1242
+ "entry/src/main/ets/entryability/EntryAbility.ets": `import UIAbility from '@ohos.app.ability.UIAbility';
1243
+ export default class EntryAbility extends UIAbility {}
1244
+ `,
1245
+ "entry/src/main/ets/pages/Index.ets": `@Entry
1246
+ @Component
1247
+ struct Index {
1248
+ ${arkState(screen)}
1249
+ build() {
1250
+ ${arkNode(screen.root)}
1251
+ }
1252
+ }
1253
+ `
1254
+ };
1255
+ }
1256
+ };
750
1257
 
751
1258
  // src/target/registry.ts
752
1259
  class TargetRegistry {
@@ -756,9 +1263,10 @@ class TargetRegistry {
756
1263
  this.register(mpWeixinTarget);
757
1264
  this.register(mpAlipayTarget);
758
1265
  this.register(mpBytedanceTarget);
759
- this.register(new PlaceholderTarget("app-ios", "iOS \u539F\u751F App", "\u8FDC\u671F"));
760
- this.register(new PlaceholderTarget("app-android", "Android \u539F\u751F App", "\u8FDC\u671F"));
761
- this.register(new PlaceholderTarget("app-harmony", "\u9E3F\u8499\u539F\u751F App\uFF08ArkUI\uFF09", "\u8FDC\u671F"));
1266
+ this.register(mpXiaohongshuTarget);
1267
+ this.register(new AppTarget(IOS_DIALECT));
1268
+ this.register(new AppTarget(ANDROID_DIALECT));
1269
+ this.register(new AppTarget(HARMONY_DIALECT));
762
1270
  }
763
1271
  register(target) {
764
1272
  this.targets.set(target.type, target);
@@ -777,8 +1285,8 @@ class TargetRegistry {
777
1285
  var targetRegistry = new TargetRegistry;
778
1286
 
779
1287
  // src/build.ts
780
- import { mkdir as mkdir2, rm as rm2 } from "fs/promises";
781
- import { dirname as dirname3, resolve as resolve4 } from "path";
1288
+ import { mkdir as mkdir3, rm as rm3 } from "fs/promises";
1289
+ import { dirname as dirname4, resolve as resolve5 } from "path";
782
1290
  async function build(options = {}) {
783
1291
  const config = await resolveConfig(options);
784
1292
  if (options.library) {
@@ -792,8 +1300,8 @@ async function buildLibrary(config) {
792
1300
  if (!library) {
793
1301
  throw new Error("TransOne library build requires config.library");
794
1302
  }
795
- await rm2(library.outDir, { recursive: true, force: true });
796
- await mkdir2(library.outDir, { recursive: true });
1303
+ await rm3(library.outDir, { recursive: true, force: true });
1304
+ await mkdir3(library.outDir, { recursive: true });
797
1305
  if (library.dts) {
798
1306
  for (const tsconfig of library.tsconfigs) {
799
1307
  await runTsc(config.root, tsconfig);
@@ -803,7 +1311,7 @@ async function buildLibrary(config) {
803
1311
  const result = await Bun.build({
804
1312
  entrypoints: [library.entry],
805
1313
  outdir: library.outDir,
806
- root: dirname3(library.entry),
1314
+ root: dirname4(library.entry),
807
1315
  target: "browser",
808
1316
  format: "esm",
809
1317
  sourcemap: library.sourcemap ? "linked" : undefined,
@@ -817,7 +1325,7 @@ async function buildLibrary(config) {
817
1325
  ${result.logs.map((log) => log.message).join(`
818
1326
  `)}`);
819
1327
  }
820
- const assetsBuilt = result.outputs.map((output) => resolve4(output.path));
1328
+ const assetsBuilt = result.outputs.map((output) => resolve5(output.path));
821
1329
  return { root: config.root, outDir: library.outDir, assetsBuilt };
822
1330
  }
823
1331
  async function runTsc(root, tsconfig) {
@@ -833,23 +1341,23 @@ async function runTsc(root, tsconfig) {
833
1341
  }
834
1342
 
835
1343
  // src/create.ts
836
- import { existsSync as existsSync2, mkdirSync, writeFileSync } from "fs";
837
- import { basename, join } from "path";
1344
+ import { existsSync as existsSync4, mkdirSync, writeFileSync } from "fs";
1345
+ import { basename as basename2, join as join2 } from "path";
838
1346
  var TRANSONE_FRAMEWORK_VERSION = "0.4.0";
839
- var TRANSONE_CLI_VERSION = "0.3.1";
1347
+ var TRANSONE_CLI_VERSION = "0.5.0";
840
1348
  var GITHUB_URL = "https://github.com/geektech-team/transone";
841
1349
  function createProject(options = {}) {
842
1350
  const root = options.root ?? process.cwd();
843
- const name = options.name ?? basename(root);
1351
+ const name = options.name ?? basename2(root);
844
1352
  const files = scaffoldFiles(name);
845
- const existing = files.filter((file) => existsSync2(join(root, file.path)));
1353
+ const existing = files.filter((file) => existsSync4(join2(root, file.path)));
846
1354
  if (existing.length > 0) {
847
1355
  throw new Error(`Refusing to overwrite existing TransOne project files: ${existing.map((file) => file.path).join(", ")}`);
848
1356
  }
849
- mkdirSync(join(root, "src"), { recursive: true });
1357
+ mkdirSync(join2(root, "src"), { recursive: true });
850
1358
  const created = [];
851
1359
  for (const file of files) {
852
- writeFileSync(join(root, file.path), file.content, "utf8");
1360
+ writeFileSync(join2(root, file.path), file.content, "utf8");
853
1361
  created.push(file.path);
854
1362
  }
855
1363
  return { root, files: created };
@@ -991,11 +1499,11 @@ app.mount();
991
1499
  // src/server.ts
992
1500
  import { randomUUID } from "crypto";
993
1501
  import {
994
- basename as basename2,
1502
+ basename as basename3,
995
1503
  extname,
996
1504
  isAbsolute as isAbsolute4,
997
1505
  relative as relative4,
998
- resolve as resolve5,
1506
+ resolve as resolve6,
999
1507
  sep as sep3
1000
1508
  } from "path";
1001
1509
 
@@ -1084,7 +1592,7 @@ function filterHeaders(source) {
1084
1592
  // src/watch.ts
1085
1593
  import { watch } from "fs";
1086
1594
  import { readdir, stat } from "fs/promises";
1087
- import { isAbsolute as isAbsolute3, join as join2, relative as relative3 } from "path";
1595
+ import { isAbsolute as isAbsolute3, join as join3, relative as relative3 } from "path";
1088
1596
  var RECURSIVE_WATCH_UNSUPPORTED_ERROR = "ERR_FEATURE_UNAVAILABLE_ON_PLATFORM";
1089
1597
  var DEFAULT_DEBOUNCE_MS = 100;
1090
1598
  var DEFAULT_POLL_INTERVAL_MS = 300;
@@ -1195,7 +1703,7 @@ async function collectRelevantFiles(root, isRelevant, output) {
1195
1703
  if (relativeDirectory === undefined) {
1196
1704
  break;
1197
1705
  }
1198
- const absoluteDirectory = join2(root, relativeDirectory);
1706
+ const absoluteDirectory = join3(root, relativeDirectory);
1199
1707
  let entries;
1200
1708
  try {
1201
1709
  entries = await readdir(absoluteDirectory, { withFileTypes: true });
@@ -1212,7 +1720,7 @@ async function collectRelevantFiles(root, isRelevant, output) {
1212
1720
  continue;
1213
1721
  }
1214
1722
  try {
1215
- const info = await stat(join2(root, relativePath));
1723
+ const info = await stat(join3(root, relativePath));
1216
1724
  output.set(relativePath, { mtimeMs: info.mtimeMs, size: info.size });
1217
1725
  } catch {}
1218
1726
  }
@@ -1311,11 +1819,11 @@ async function createServerInstance(options, watch2) {
1311
1819
  for (const [route, entry] of Object.entries(config.pages)) {
1312
1820
  await renderProjectHtml(config, {}, entry, route);
1313
1821
  }
1314
- const developmentOutDir = resolve5(config.root, "dist", "dev", "h5");
1822
+ const developmentOutDir = resolve6(config.root, "dist", "dev", "h5");
1315
1823
  await assertSafeSubdirectory(config.root, developmentOutDir, INVALID_DEVELOPMENT_DIRECTORY_MESSAGE);
1316
1824
  const proxy = createProxyHandler(config.server.proxy);
1317
1825
  const sessionId = createGenerationId();
1318
- const sessionOutDir = resolve5(developmentOutDir, sessionId);
1826
+ const sessionOutDir = resolve6(developmentOutDir, sessionId);
1319
1827
  const artifacts = new Map;
1320
1828
  const buildProject = createDevelopmentBuilder(sessionId, sessionOutDir);
1321
1829
  const liveReload = watch2 ? createLiveReloadHub() : undefined;
@@ -1550,11 +2058,11 @@ function isWatchedFile(instance, relativePath) {
1550
2058
  if (segments.some((segment) => IGNORED_WATCH_SEGMENTS.has(segment))) {
1551
2059
  return false;
1552
2060
  }
1553
- const absolutePath = resolve5(instance.config.root, relativePath);
2061
+ const absolutePath = resolve6(instance.config.root, relativePath);
1554
2062
  if (isWithinOrEqual(instance.config.build.outDir, absolutePath)) {
1555
2063
  return false;
1556
2064
  }
1557
- const base = basename2(absolutePath);
2065
+ const base = basename3(absolutePath);
1558
2066
  if (base.startsWith(".") && absolutePath !== instance.config.configFile) {
1559
2067
  return false;
1560
2068
  }
@@ -1581,7 +2089,7 @@ function createDevelopmentBuilder(sessionId, sessionOutDir) {
1581
2089
  }
1582
2090
  async function buildProjectBundle(entry, sessionId, sessionOutDir) {
1583
2091
  const generationId = createGenerationId();
1584
- const generationOutDir = resolve5(sessionOutDir, generationId);
2092
+ const generationOutDir = resolve6(sessionOutDir, generationId);
1585
2093
  const generationUrl = `${DEVELOPMENT_URL_PREFIX}/${sessionId}/${generationId}`;
1586
2094
  const buildOptions = {
1587
2095
  entrypoints: [entry],
@@ -1645,7 +2153,7 @@ function publishDevelopmentBundle(bundle, artifacts) {
1645
2153
  }
1646
2154
  }
1647
2155
  function createDevelopmentOutput(generationOutDir, generationUrl, output) {
1648
- const filePath = resolve5(output.path);
2156
+ const filePath = resolve6(output.path);
1649
2157
  const pathFromGeneration = relative4(generationOutDir, filePath);
1650
2158
  if (pathFromGeneration === "" || pathFromGeneration === ".." || pathFromGeneration.startsWith(`..${sep3}`) || isAbsolute4(pathFromGeneration)) {
1651
2159
  throw new Error(`Development output must not escape outside its generation directory: ${output.path}`);
@@ -1667,7 +2175,7 @@ function buildFailureResponse() {
1667
2175
  });
1668
2176
  }
1669
2177
 
1670
- export { TARGET_TYPES, isTargetType, MP_TARGET_TYPES, isMpTargetType, defineConfig, resolveConfig, WebTarget, MpTarget, mpWeixinTarget, mpAlipayTarget, mpBytedanceTarget, PlaceholderTarget, TargetRegistry, targetRegistry, build, createProject, startDevServer };
2178
+ export { TARGET_TYPES, isTargetType, MP_TARGET_TYPES, isMpTargetType, defineConfig, resolveConfig, WebTarget, MpTarget, mpWeixinTarget, mpAlipayTarget, mpBytedanceTarget, mpXiaohongshuTarget, TargetRegistry, targetRegistry, build, createProject, startDevServer };
1671
2179
 
1672
- //# debugId=64B59B0DA2718AD164756E2164756E21
1673
- //# sourceMappingURL=index-rjvspt2q.js.map
2180
+ //# debugId=53ACD0D6DD0AC45964756E2164756E21
2181
+ //# sourceMappingURL=index-nag8rsrg.js.map