@serveryyswys/node.operit 0.0.0-stage → 0.1.2

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 (123) hide show
  1. package/BUILTINS.json +233 -0
  2. package/DESIGN.md +513 -0
  3. package/LICENSE +674 -0
  4. package/README.md +301 -2
  5. package/dist/assert/strict.d.ts +2 -0
  6. package/dist/assert/strict.js +7 -0
  7. package/dist/assert.d.ts +3 -0
  8. package/dist/assert.js +483 -0
  9. package/dist/buffer.d.ts +60 -0
  10. package/dist/buffer.js +524 -0
  11. package/dist/child_process.d.ts +56 -0
  12. package/dist/child_process.js +371 -0
  13. package/dist/constants.d.ts +2 -0
  14. package/dist/constants.js +19 -0
  15. package/dist/crypto.d.ts +76 -0
  16. package/dist/crypto.js +312 -0
  17. package/dist/dns/promises.d.ts +34 -0
  18. package/dist/dns/promises.js +190 -0
  19. package/dist/dns.d.ts +88 -0
  20. package/dist/dns.js +259 -0
  21. package/dist/events.d.ts +40 -0
  22. package/dist/events.js +237 -0
  23. package/dist/fs/promises.d.ts +159 -0
  24. package/dist/fs/promises.js +129 -0
  25. package/dist/fs.d.ts +221 -0
  26. package/dist/fs.js +944 -0
  27. package/dist/http.d.ts +92 -0
  28. package/dist/http.js +319 -0
  29. package/dist/https.d.ts +296 -0
  30. package/dist/https.js +50 -0
  31. package/dist/index.d.ts +2422 -0
  32. package/dist/index.js +57 -0
  33. package/dist/lib/bridge.d.ts +60 -0
  34. package/dist/lib/bridge.js +205 -0
  35. package/dist/lib/bytes.d.ts +20 -0
  36. package/dist/lib/bytes.js +239 -0
  37. package/dist/lib/child-process-types.d.ts +45 -0
  38. package/dist/lib/child-process-types.js +2 -0
  39. package/dist/lib/cwd.d.ts +2 -0
  40. package/dist/lib/cwd.js +32 -0
  41. package/dist/lib/deep-equal.d.ts +3 -0
  42. package/dist/lib/deep-equal.js +223 -0
  43. package/dist/lib/deflate.d.ts +2 -0
  44. package/dist/lib/deflate.js +234 -0
  45. package/dist/lib/dns-driver.d.ts +14 -0
  46. package/dist/lib/dns-driver.js +85 -0
  47. package/dist/lib/dns-types.d.ts +22 -0
  48. package/dist/lib/dns-types.js +2 -0
  49. package/dist/lib/errors.d.ts +48 -0
  50. package/dist/lib/errors.js +424 -0
  51. package/dist/lib/fs-driver.d.ts +70 -0
  52. package/dist/lib/fs-driver.js +364 -0
  53. package/dist/lib/fs-env.d.ts +30 -0
  54. package/dist/lib/fs-env.js +157 -0
  55. package/dist/lib/fs-types.d.ts +19 -0
  56. package/dist/lib/fs-types.js +2 -0
  57. package/dist/lib/hashes.d.ts +27 -0
  58. package/dist/lib/hashes.js +432 -0
  59. package/dist/lib/http-driver.d.ts +30 -0
  60. package/dist/lib/http-driver.js +72 -0
  61. package/dist/lib/http-types.d.ts +18 -0
  62. package/dist/lib/http-types.js +2 -0
  63. package/dist/lib/inflate.d.ts +6 -0
  64. package/dist/lib/inflate.js +284 -0
  65. package/dist/lib/path-types.d.ts +37 -0
  66. package/dist/lib/path-types.js +2 -0
  67. package/dist/lib/paths.d.ts +8 -0
  68. package/dist/lib/paths.js +106 -0
  69. package/dist/lib/perf-hooks-types.d.ts +18 -0
  70. package/dist/lib/perf-hooks-types.js +2 -0
  71. package/dist/lib/process-driver.d.ts +31 -0
  72. package/dist/lib/process-driver.js +102 -0
  73. package/dist/lib/punycode.d.ts +8 -0
  74. package/dist/lib/punycode.js +179 -0
  75. package/dist/lib/stream-types.d.ts +29 -0
  76. package/dist/lib/stream-types.js +2 -0
  77. package/dist/lib/timers-types.d.ts +18 -0
  78. package/dist/lib/timers-types.js +2 -0
  79. package/dist/lib/url-search-params.d.ts +26 -0
  80. package/dist/lib/url-search-params.js +281 -0
  81. package/dist/lib/url-types.d.ts +44 -0
  82. package/dist/lib/url-types.js +2 -0
  83. package/dist/lib/url-whatwg.d.ts +78 -0
  84. package/dist/lib/url-whatwg.js +857 -0
  85. package/dist/lib/zlib-types.d.ts +12 -0
  86. package/dist/lib/zlib-types.js +2 -0
  87. package/dist/module.d.ts +8 -0
  88. package/dist/module.js +72 -0
  89. package/dist/os.d.ts +80 -0
  90. package/dist/os.js +247 -0
  91. package/dist/path/posix.d.ts +2 -0
  92. package/dist/path/posix.js +7 -0
  93. package/dist/path/win32.d.ts +2 -0
  94. package/dist/path/win32.js +10 -0
  95. package/dist/path.d.ts +3 -0
  96. package/dist/path.js +1222 -0
  97. package/dist/perf_hooks.d.ts +36 -0
  98. package/dist/perf_hooks.js +144 -0
  99. package/dist/process.d.ts +69 -0
  100. package/dist/process.js +230 -0
  101. package/dist/querystring.d.ts +15 -0
  102. package/dist/querystring.js +209 -0
  103. package/dist/stream/promises.d.ts +5 -0
  104. package/dist/stream/promises.js +10 -0
  105. package/dist/stream.d.ts +84 -0
  106. package/dist/stream.js +875 -0
  107. package/dist/string_decoder.d.ts +15 -0
  108. package/dist/string_decoder.js +237 -0
  109. package/dist/timers/promises.d.ts +19 -0
  110. package/dist/timers/promises.js +74 -0
  111. package/dist/timers.d.ts +21 -0
  112. package/dist/timers.js +41 -0
  113. package/dist/tty.d.ts +9 -0
  114. package/dist/tty.js +25 -0
  115. package/dist/unsupported.d.ts +12 -0
  116. package/dist/unsupported.js +17 -0
  117. package/dist/url.d.ts +28 -0
  118. package/dist/url.js +486 -0
  119. package/dist/util.d.ts +74 -0
  120. package/dist/util.js +515 -0
  121. package/dist/zlib.d.ts +88 -0
  122. package/dist/zlib.js +371 -0
  123. package/package.json +29 -4
package/dist/index.js ADDED
@@ -0,0 +1,57 @@
1
+ 'use strict';
2
+ /**
3
+ * 聚合入口(糖)。
4
+ *
5
+ * 正式契约是"一个 Node 内置名 = 一个子路径",见 BUILTINS.json;
6
+ * 本文件只把已实现的模块聚合成一个对象,方便手写代码时少写几行 require。
7
+ *
8
+ * 用法:
9
+ * const onj = require('<项目>/node_modules/@serveryyswys/node.operit/index.js');
10
+ * onj.path.join('a', 'b');
11
+ *
12
+ * 注意:stream 不在聚合里,因为它以类形式 `export =` 导出(`require('.../stream')` 返回
13
+ * Stream 类本身),无法在 .d.ts 里被"命名",加进来会让本文件的声明生成失败。
14
+ * 需要它请直接引子路径。
15
+ */
16
+ const pathModule = require("./path");
17
+ const fsModule = require("./fs");
18
+ const bufferModule = require("./buffer");
19
+ const osModule = require("./os");
20
+ const processModule = require("./process");
21
+ const cryptoModule = require("./crypto");
22
+ const zlibModule = require("./zlib");
23
+ const childProcessModule = require("./child_process");
24
+ const urlModule = require("./url");
25
+ const timersModule = require("./timers");
26
+ const timersPromisesModule = require("./timers/promises");
27
+ const perfHooksModule = require("./perf_hooks");
28
+ const constantsModule = require("./constants");
29
+ const moduleModule = require("./module");
30
+ const ttyModule = require("./tty");
31
+ const httpModule = require("./http");
32
+ const httpsModule = require("./https");
33
+ const dnsModule = require("./dns");
34
+ const dnsPromisesModule = require("./dns/promises");
35
+ const api = {
36
+ version: '0.1.0',
37
+ path: pathModule,
38
+ fs: fsModule,
39
+ buffer: bufferModule,
40
+ os: osModule,
41
+ process: processModule,
42
+ crypto: cryptoModule,
43
+ zlib: zlibModule,
44
+ child_process: childProcessModule,
45
+ url: urlModule,
46
+ timers: timersModule,
47
+ 'timers/promises': timersPromisesModule,
48
+ perf_hooks: perfHooksModule,
49
+ constants: constantsModule,
50
+ module: moduleModule,
51
+ tty: ttyModule,
52
+ http: httpModule,
53
+ https: httpsModule,
54
+ dns: dnsModule,
55
+ 'dns/promises': dnsPromisesModule
56
+ };
57
+ module.exports = api;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * 唯一接触 Operit Java bridge 的地方。
3
+ *
4
+ * 运行时契约(types/core.d.ts):
5
+ * javaCallStatic(className, methodName, argsJson) -> "{\"success\":bool,\"data\":any,\"error\":string}"
6
+ * javaNewInstance / javaCallInstance / javaGet|SetStatic|InstanceField 同形状
7
+ * javaGetApplicationContext / javaGetCurrentActivity
8
+ *
9
+ * 返回值经 toJsonCompatibleValue 转换:基本类型直通,数组 / Map / Iterable 递归展开,
10
+ * 其余对象变成 { __javaHandle, __javaClass } 句柄。参数方向只接受 JSON 值。
11
+ *
12
+ * 本模块只做三件事:调用、解包、把 Java 异常翻成带 code 的中间态错误。
13
+ * 它不知道 fs,也不知道路径语义 —— 那些属于上层。
14
+ */
15
+ import { type NodeStyleError } from './errors';
16
+ /** Java 侧对象在 JS 侧的表现形式。 */
17
+ export interface JavaHandle {
18
+ __javaHandle: string;
19
+ __javaClass: string;
20
+ }
21
+ /** 宿主后端接口:Operit 上的实现走 NativeInterface,桌面测试注入 mock。 */
22
+ export interface JavaBridgeBackend {
23
+ classExists(className: string): boolean;
24
+ callStatic(className: string, methodName: string, args: readonly unknown[]): unknown;
25
+ callInstance(instance: unknown, methodName: string, args: readonly unknown[]): unknown;
26
+ newInstance(className: string, args: readonly unknown[]): unknown;
27
+ getStaticField(className: string, fieldName: string): unknown;
28
+ setStaticField(className: string, fieldName: string, value: unknown): unknown;
29
+ getInstanceField(instance: unknown, fieldName: string): unknown;
30
+ setInstanceField(instance: unknown, fieldName: string, value: unknown): unknown;
31
+ getApplicationContext(): unknown;
32
+ getCurrentActivity(): unknown;
33
+ setEnv(key: string, value: string | null): void;
34
+ }
35
+ /** 宿主注入点:桌面测试与 mock 使用。传 null 恢复为自动解析 Operit 宿主。 */
36
+ export declare function setBackend(next: JavaBridgeBackend | null): void;
37
+ /** 把 { __javaHandle, __javaClass } 或裸 handle 字符串统一成 handle 字符串。 */
38
+ export declare function handleOf(instance: unknown): string;
39
+ export declare function normalizeBoolean(value: unknown): boolean;
40
+ /**
41
+ * 解包 bridge 返回值。约定形状 `{ success, data?, error?, message? }`;
42
+ * success 为 false 时抛中间态 Java 错误(带 code,但还没有 syscall / path)。
43
+ */
44
+ export declare function unwrap(raw: unknown, context: string): unknown;
45
+ export declare function classExists(className: string): boolean;
46
+ export declare function callStatic(className: string, methodName: string, args?: readonly unknown[]): unknown;
47
+ export declare function callInstance(instance: unknown, methodName: string, args?: readonly unknown[]): unknown;
48
+ export declare function newInstance(className: string, args?: readonly unknown[]): unknown;
49
+ export declare function getStaticField(className: string, fieldName: string): unknown;
50
+ export declare function setStaticField(className: string, fieldName: string, value: unknown): unknown;
51
+ export declare function getInstanceField(instance: unknown, fieldName: string): unknown;
52
+ export declare function setInstanceField(instance: unknown, fieldName: string, value: unknown): unknown;
53
+ export declare function getApplicationContext(): unknown;
54
+ export declare function getCurrentActivity(): unknown;
55
+ /** 写环境变量。setEnv 是 P2 能力:不存在时抛 ONJ_MISSING_HOST,不静默丢弃。 */
56
+ export declare function setEnv(key: string, value: string | null): void;
57
+ /** 便于上层判断某个值是不是 Java 句柄。 */
58
+ export declare function isJavaHandle(value: unknown): value is JavaHandle;
59
+ /** 类型收窄辅助:把 unknown 断言成带 code 的错误对象。 */
60
+ export declare function asNodeError(value: unknown): NodeStyleError | null;
@@ -0,0 +1,205 @@
1
+ 'use strict';
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setBackend = setBackend;
4
+ exports.handleOf = handleOf;
5
+ exports.normalizeBoolean = normalizeBoolean;
6
+ exports.unwrap = unwrap;
7
+ exports.classExists = classExists;
8
+ exports.callStatic = callStatic;
9
+ exports.callInstance = callInstance;
10
+ exports.newInstance = newInstance;
11
+ exports.getStaticField = getStaticField;
12
+ exports.setStaticField = setStaticField;
13
+ exports.getInstanceField = getInstanceField;
14
+ exports.setInstanceField = setInstanceField;
15
+ exports.getApplicationContext = getApplicationContext;
16
+ exports.getCurrentActivity = getCurrentActivity;
17
+ exports.setEnv = setEnv;
18
+ exports.isJavaHandle = isJavaHandle;
19
+ exports.asNodeError = asNodeError;
20
+ /**
21
+ * 唯一接触 Operit Java bridge 的地方。
22
+ *
23
+ * 运行时契约(types/core.d.ts):
24
+ * javaCallStatic(className, methodName, argsJson) -> "{\"success\":bool,\"data\":any,\"error\":string}"
25
+ * javaNewInstance / javaCallInstance / javaGet|SetStatic|InstanceField 同形状
26
+ * javaGetApplicationContext / javaGetCurrentActivity
27
+ *
28
+ * 返回值经 toJsonCompatibleValue 转换:基本类型直通,数组 / Map / Iterable 递归展开,
29
+ * 其余对象变成 { __javaHandle, __javaClass } 句柄。参数方向只接受 JSON 值。
30
+ *
31
+ * 本模块只做三件事:调用、解包、把 Java 异常翻成带 code 的中间态错误。
32
+ * 它不知道 fs,也不知道路径语义 —— 那些属于上层。
33
+ */
34
+ const errors_1 = require("./errors");
35
+ let backend = null;
36
+ /** 宿主注入点:桌面测试与 mock 使用。传 null 恢复为自动解析 Operit 宿主。 */
37
+ function setBackend(next) {
38
+ backend = next === undefined ? null : next;
39
+ }
40
+ function getBackend() {
41
+ if (backend === null) {
42
+ backend = createOperitBackend();
43
+ }
44
+ return backend;
45
+ }
46
+ function createOperitBackend() {
47
+ const detected = NativeInterface;
48
+ if (detected === undefined) {
49
+ throw (0, errors_1.onjError)('ONJ_MISSING_HOST');
50
+ }
51
+ const native = detected;
52
+ function callNative(method, args) {
53
+ const fn = native[method];
54
+ if (typeof fn !== 'function') {
55
+ throw (0, errors_1.onjError)('ONJ_MISSING_HOST', 'NativeInterface.' + String(method) + ' 不可用。');
56
+ }
57
+ const invoke = fn;
58
+ return invoke.apply(native, args);
59
+ }
60
+ return {
61
+ classExists(className) {
62
+ return normalizeBoolean(callNative('javaClassExists', [String(className)]));
63
+ },
64
+ callStatic(className, methodName, args) {
65
+ return unwrap(callNative('javaCallStatic', [String(className), String(methodName), JSON.stringify(args)]), 'javaCallStatic ' + className + '#' + methodName);
66
+ },
67
+ callInstance(instance, methodName, args) {
68
+ return unwrap(callNative('javaCallInstance', [handleOf(instance), String(methodName), JSON.stringify(args)]), 'javaCallInstance ' + methodName);
69
+ },
70
+ newInstance(className, args) {
71
+ return unwrap(callNative('javaNewInstance', [String(className), JSON.stringify(args)]), 'javaNewInstance ' + className);
72
+ },
73
+ getStaticField(className, fieldName) {
74
+ return unwrap(callNative('javaGetStaticField', [String(className), String(fieldName)]), 'javaGetStaticField ' + className + '#' + fieldName);
75
+ },
76
+ setStaticField(className, fieldName, value) {
77
+ return unwrap(callNative('javaSetStaticField', [String(className), String(fieldName), JSON.stringify(value)]), 'javaSetStaticField ' + className + '#' + fieldName);
78
+ },
79
+ getInstanceField(instance, fieldName) {
80
+ return unwrap(callNative('javaGetInstanceField', [handleOf(instance), String(fieldName)]), 'javaGetInstanceField ' + fieldName);
81
+ },
82
+ setInstanceField(instance, fieldName, value) {
83
+ return unwrap(callNative('javaSetInstanceField', [handleOf(instance), String(fieldName), JSON.stringify(value)]), 'javaSetInstanceField ' + fieldName);
84
+ },
85
+ getApplicationContext() {
86
+ return unwrap(callNative('javaGetApplicationContext', []), 'javaGetApplicationContext');
87
+ },
88
+ getCurrentActivity() {
89
+ return unwrap(callNative('javaGetCurrentActivity', []), 'javaGetCurrentActivity');
90
+ },
91
+ setEnv(key, value) {
92
+ // setEnv 属于 P2(源码里真实存在,官方 d.ts 未声明),因此显式检查可用性
93
+ if (typeof native.setEnv !== 'function') {
94
+ throw (0, errors_1.onjError)('ONJ_MISSING_HOST', 'NativeInterface.setEnv 不可用,无法写环境变量。');
95
+ }
96
+ native.setEnv(String(key), value);
97
+ }
98
+ };
99
+ }
100
+ /** 把 { __javaHandle, __javaClass } 或裸 handle 字符串统一成 handle 字符串。 */
101
+ function handleOf(instance) {
102
+ if (typeof instance === 'string' && instance.length > 0) {
103
+ return instance;
104
+ }
105
+ if (instance !== null && typeof instance === 'object') {
106
+ const candidate = instance.__javaHandle;
107
+ if (typeof candidate === 'string' && candidate.length > 0) {
108
+ return candidate;
109
+ }
110
+ }
111
+ throw (0, errors_1.createError)('EINVAL', 'bridge.handleOf');
112
+ }
113
+ function normalizeBoolean(value) {
114
+ if (value === true || value === false) {
115
+ return value;
116
+ }
117
+ if (typeof value === 'string') {
118
+ return value.trim().toLowerCase() === 'true';
119
+ }
120
+ if (typeof value === 'number') {
121
+ return value !== 0;
122
+ }
123
+ if (value === null || value === undefined) {
124
+ return false;
125
+ }
126
+ return Boolean(value);
127
+ }
128
+ /**
129
+ * 解包 bridge 返回值。约定形状 `{ success, data?, error?, message? }`;
130
+ * success 为 false 时抛中间态 Java 错误(带 code,但还没有 syscall / path)。
131
+ */
132
+ function unwrap(raw, context) {
133
+ if (typeof raw !== 'string') {
134
+ return raw;
135
+ }
136
+ let parsed;
137
+ try {
138
+ parsed = JSON.parse(raw);
139
+ }
140
+ catch (parseFailure) {
141
+ throw (0, errors_1.onjError)('ONJ_BRIDGE_PROTOCOL', context + ' 的返回不是 JSON。');
142
+ }
143
+ if (parsed === null || typeof parsed !== 'object') {
144
+ return parsed;
145
+ }
146
+ const envelope = parsed;
147
+ if (envelope.success === false) {
148
+ const detail = typeof envelope.error === 'string' && envelope.error.length > 0
149
+ ? envelope.error
150
+ : (typeof envelope.message === 'string' && envelope.message.length > 0 ? envelope.message : context);
151
+ throw (0, errors_1.javaError)(detail);
152
+ }
153
+ if (Object.prototype.hasOwnProperty.call(envelope, 'data')) {
154
+ return envelope.data;
155
+ }
156
+ return envelope;
157
+ }
158
+ function classExists(className) {
159
+ return getBackend().classExists(className);
160
+ }
161
+ function callStatic(className, methodName, args = []) {
162
+ return getBackend().callStatic(className, methodName, args);
163
+ }
164
+ function callInstance(instance, methodName, args = []) {
165
+ return getBackend().callInstance(instance, methodName, args);
166
+ }
167
+ function newInstance(className, args = []) {
168
+ return getBackend().newInstance(className, args);
169
+ }
170
+ function getStaticField(className, fieldName) {
171
+ return getBackend().getStaticField(className, fieldName);
172
+ }
173
+ function setStaticField(className, fieldName, value) {
174
+ return getBackend().setStaticField(className, fieldName, value);
175
+ }
176
+ function getInstanceField(instance, fieldName) {
177
+ return getBackend().getInstanceField(instance, fieldName);
178
+ }
179
+ function setInstanceField(instance, fieldName, value) {
180
+ return getBackend().setInstanceField(instance, fieldName, value);
181
+ }
182
+ function getApplicationContext() {
183
+ return getBackend().getApplicationContext();
184
+ }
185
+ function getCurrentActivity() {
186
+ return getBackend().getCurrentActivity();
187
+ }
188
+ /** 写环境变量。setEnv 是 P2 能力:不存在时抛 ONJ_MISSING_HOST,不静默丢弃。 */
189
+ function setEnv(key, value) {
190
+ getBackend().setEnv(key, value);
191
+ }
192
+ /** 便于上层判断某个值是不是 Java 句柄。 */
193
+ function isJavaHandle(value) {
194
+ if (value === null || typeof value !== 'object') {
195
+ return false;
196
+ }
197
+ return typeof value.__javaHandle === 'string';
198
+ }
199
+ /** 类型收窄辅助:把 unknown 断言成带 code 的错误对象。 */
200
+ function asNodeError(value) {
201
+ if (value instanceof Error) {
202
+ return value;
203
+ }
204
+ return null;
205
+ }
@@ -0,0 +1,20 @@
1
+ export type BinaryChannel = 'base64' | 'latin1';
2
+ export declare function encodeBase64(bytes: Uint8Array): string;
3
+ /**
4
+ * 按 Node 的容错规则解码 base64:
5
+ * - 字母表以外的 ASCII 字符(空白、'!' 等)跳过
6
+ * - 遇到 '=' 或任何码点 > 0x7f 的字符立即停止
7
+ * 于是 'aGVsbG8=' 与 'aGVs bG8=!' 同结果,而 'a=b' 与 '🚀 emoji' 都是空。
8
+ * 对规范 base64 输入(本库自己的编码器产物)结果与严格解码完全一致。
9
+ */
10
+ export declare function decodeBase64(text: string): Uint8Array;
11
+ export declare function bytesToLatin1(bytes: Uint8Array): string;
12
+ export declare function latin1ToBytes(text: string): Uint8Array;
13
+ export declare function utf8Encode(text: string): Uint8Array;
14
+ export declare function utf8Decode(bytes: Uint8Array): string;
15
+ export declare function getChannel(): BinaryChannel;
16
+ export declare function setChannel(name: BinaryChannel): void;
17
+ /** 按当前通道把字节编码成可穿过 bridge 的字符串。 */
18
+ export declare function encode(bytes: Uint8Array): string;
19
+ /** 按当前通道把 bridge 返回的字符串还原成字节。 */
20
+ export declare function decode(text: string): Uint8Array;
@@ -0,0 +1,239 @@
1
+ 'use strict';
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.encodeBase64 = encodeBase64;
4
+ exports.decodeBase64 = decodeBase64;
5
+ exports.bytesToLatin1 = bytesToLatin1;
6
+ exports.latin1ToBytes = latin1ToBytes;
7
+ exports.utf8Encode = utf8Encode;
8
+ exports.utf8Decode = utf8Decode;
9
+ exports.getChannel = getChannel;
10
+ exports.setChannel = setChannel;
11
+ exports.encode = encode;
12
+ exports.decode = decode;
13
+ /**
14
+ * 二进制通道的唯一开关,以及 UTF-8 编解码。
15
+ *
16
+ * 背景:Java bridge 的返回值经 toJsonCompatibleValue 转换,byte[] 会被逐元素展开成
17
+ * JSON 数字数组(1MB 文件膨胀到 MB 级文本),因此二进制不走 byte[],改用字符串通道:
18
+ *
19
+ * base64 1.33x 体积,纯 ASCII,任何传输都安全 —— 默认
20
+ * latin1 1.00x 体积,依赖 JSON 字符串保持码点不变
21
+ *
22
+ * 换通道只改这里;fs 与 Buffer 都只调 encode() / decode()。
23
+ * QuickJS 不保证有 TextEncoder / TextDecoder,因此 UTF-8 自行实现,非法序列按 U+FFFD 处理。
24
+ */
25
+ const errors_1 = require("./errors");
26
+ const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
27
+ const LOOKUP = (function buildLookup() {
28
+ const table = new Int16Array(128);
29
+ for (let i = 0; i < table.length; i += 1) {
30
+ table[i] = -1;
31
+ }
32
+ for (let j = 0; j < ALPHABET.length; j += 1) {
33
+ table[ALPHABET.charCodeAt(j)] = j;
34
+ }
35
+ return table;
36
+ })();
37
+ const REPLACEMENT_CODE_POINT = 0xfffd;
38
+ const CHAR_EQUALS = 61;
39
+ function encodeBase64(bytes) {
40
+ let out = '';
41
+ const len = bytes.length;
42
+ let i = 0;
43
+ for (; i + 2 < len; i += 3) {
44
+ const triple = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
45
+ out += ALPHABET[(triple >> 18) & 63] +
46
+ ALPHABET[(triple >> 12) & 63] +
47
+ ALPHABET[(triple >> 6) & 63] +
48
+ ALPHABET[triple & 63];
49
+ }
50
+ const rest = len - i;
51
+ if (rest === 1) {
52
+ const single = bytes[i] << 16;
53
+ out += ALPHABET[(single >> 18) & 63] + ALPHABET[(single >> 12) & 63] + '==';
54
+ }
55
+ else if (rest === 2) {
56
+ const pair = (bytes[i] << 16) | (bytes[i + 1] << 8);
57
+ out += ALPHABET[(pair >> 18) & 63] +
58
+ ALPHABET[(pair >> 12) & 63] +
59
+ ALPHABET[(pair >> 6) & 63] + '=';
60
+ }
61
+ return out;
62
+ }
63
+ /**
64
+ * 按 Node 的容错规则解码 base64:
65
+ * - 字母表以外的 ASCII 字符(空白、'!' 等)跳过
66
+ * - 遇到 '=' 或任何码点 > 0x7f 的字符立即停止
67
+ * 于是 'aGVsbG8=' 与 'aGVs bG8=!' 同结果,而 'a=b' 与 '🚀 emoji' 都是空。
68
+ * 对规范 base64 输入(本库自己的编码器产物)结果与严格解码完全一致。
69
+ */
70
+ function decodeBase64(text) {
71
+ const source = String(text);
72
+ let count = 0;
73
+ for (let i = 0; i < source.length; i += 1) {
74
+ const code = source.charCodeAt(i);
75
+ if (code === CHAR_EQUALS || code > 0x7f) {
76
+ break;
77
+ }
78
+ if (LOOKUP[code] >= 0) {
79
+ count += 1;
80
+ }
81
+ }
82
+ const remainder = count & 3;
83
+ let outLength = (count >> 2) * 3;
84
+ if (remainder === 2) {
85
+ outLength += 1;
86
+ }
87
+ else if (remainder === 3) {
88
+ outLength += 2;
89
+ }
90
+ const out = new Uint8Array(outLength);
91
+ let accumulator = 0;
92
+ let inWindow = 0;
93
+ let produced = 0;
94
+ let o = 0;
95
+ for (let i = 0; i < source.length && produced < count; i += 1) {
96
+ const code = source.charCodeAt(i);
97
+ if (code === CHAR_EQUALS || code > 0x7f) {
98
+ break;
99
+ }
100
+ const value = LOOKUP[code];
101
+ if (value < 0) {
102
+ continue;
103
+ }
104
+ accumulator = (accumulator << 6) | value;
105
+ inWindow += 1;
106
+ produced += 1;
107
+ if (inWindow === 4) {
108
+ out[o] = (accumulator >> 16) & 255;
109
+ out[o + 1] = (accumulator >> 8) & 255;
110
+ out[o + 2] = accumulator & 255;
111
+ o += 3;
112
+ accumulator = 0;
113
+ inWindow = 0;
114
+ }
115
+ }
116
+ if (inWindow === 2) {
117
+ out[o] = (accumulator >> 4) & 255;
118
+ }
119
+ else if (inWindow === 3) {
120
+ out[o] = (accumulator >> 10) & 255;
121
+ out[o + 1] = (accumulator >> 2) & 255;
122
+ }
123
+ return out;
124
+ }
125
+ function bytesToLatin1(bytes) {
126
+ const parts = [];
127
+ const CHUNK = 4096;
128
+ for (let i = 0; i < bytes.length; i += CHUNK) {
129
+ const end = Math.min(i + CHUNK, bytes.length);
130
+ const chunk = new Array(end - i);
131
+ for (let j = i; j < end; j += 1) {
132
+ chunk[j - i] = bytes[j];
133
+ }
134
+ parts.push(String.fromCharCode.apply(null, chunk));
135
+ }
136
+ return parts.join('');
137
+ }
138
+ function latin1ToBytes(text) {
139
+ const source = String(text);
140
+ const out = new Uint8Array(source.length);
141
+ for (let i = 0; i < source.length; i += 1) {
142
+ out[i] = source.charCodeAt(i) & 255;
143
+ }
144
+ return out;
145
+ }
146
+ function utf8Encode(text) {
147
+ const source = String(text);
148
+ const out = [];
149
+ for (let i = 0; i < source.length; i += 1) {
150
+ const code = source.charCodeAt(i);
151
+ if (code < 0x80) {
152
+ out.push(code);
153
+ }
154
+ else if (code < 0x800) {
155
+ out.push(0xc0 | (code >> 6), 0x80 | (code & 63));
156
+ }
157
+ else if (code >= 0xd800 && code <= 0xdbff) {
158
+ const low = i + 1 < source.length ? source.charCodeAt(i + 1) : 0;
159
+ if (low >= 0xdc00 && low <= 0xdfff) {
160
+ i += 1;
161
+ const codePoint = 0x10000 + ((code - 0xd800) << 10) + (low - 0xdc00);
162
+ out.push(0xf0 | (codePoint >> 18), 0x80 | ((codePoint >> 12) & 63), 0x80 | ((codePoint >> 6) & 63), 0x80 | (codePoint & 63));
163
+ }
164
+ else {
165
+ out.push(0xef, 0xbf, 0xbd);
166
+ }
167
+ }
168
+ else if (code >= 0xdc00 && code <= 0xdfff) {
169
+ out.push(0xef, 0xbf, 0xbd);
170
+ }
171
+ else {
172
+ out.push(0xe0 | (code >> 12), 0x80 | ((code >> 6) & 63), 0x80 | (code & 63));
173
+ }
174
+ }
175
+ return new Uint8Array(out);
176
+ }
177
+ function utf8Decode(bytes) {
178
+ let out = '';
179
+ let i = 0;
180
+ const len = bytes.length;
181
+ while (i < len) {
182
+ const b0 = bytes[i];
183
+ if (b0 < 0x80) {
184
+ out += String.fromCharCode(b0);
185
+ i += 1;
186
+ continue;
187
+ }
188
+ if (b0 >= 0xc2 && b0 <= 0xdf && i + 1 < len && (bytes[i + 1] & 0xc0) === 0x80) {
189
+ out += String.fromCharCode(((b0 & 0x1f) << 6) | (bytes[i + 1] & 63));
190
+ i += 2;
191
+ continue;
192
+ }
193
+ if (b0 >= 0xe0 && b0 <= 0xef && i + 2 < len &&
194
+ (bytes[i + 1] & 0xc0) === 0x80 && (bytes[i + 2] & 0xc0) === 0x80) {
195
+ const cp3 = ((b0 & 0x0f) << 12) | ((bytes[i + 1] & 63) << 6) | (bytes[i + 2] & 63);
196
+ if (cp3 >= 0x800 && !(cp3 >= 0xd800 && cp3 <= 0xdfff)) {
197
+ out += String.fromCharCode(cp3);
198
+ i += 3;
199
+ continue;
200
+ }
201
+ }
202
+ if (b0 >= 0xf0 && b0 <= 0xf4 && i + 3 < len &&
203
+ (bytes[i + 1] & 0xc0) === 0x80 &&
204
+ (bytes[i + 2] & 0xc0) === 0x80 &&
205
+ (bytes[i + 3] & 0xc0) === 0x80) {
206
+ const cp4 = ((b0 & 0x07) << 18) |
207
+ ((bytes[i + 1] & 63) << 12) |
208
+ ((bytes[i + 2] & 63) << 6) |
209
+ (bytes[i + 3] & 63);
210
+ if (cp4 >= 0x10000 && cp4 <= 0x10ffff) {
211
+ const offset = cp4 - 0x10000;
212
+ out += String.fromCharCode(0xd800 + (offset >> 10), 0xdc00 + (offset & 0x3ff));
213
+ i += 4;
214
+ continue;
215
+ }
216
+ }
217
+ out += String.fromCharCode(REPLACEMENT_CODE_POINT);
218
+ i += 1;
219
+ }
220
+ return out;
221
+ }
222
+ let channel = 'base64';
223
+ function getChannel() {
224
+ return channel;
225
+ }
226
+ function setChannel(name) {
227
+ if (name !== 'base64' && name !== 'latin1') {
228
+ throw (0, errors_1.onjError)('ONJ_BRIDGE_PROTOCOL', '未知的二进制通道: ' + String(name));
229
+ }
230
+ channel = name;
231
+ }
232
+ /** 按当前通道把字节编码成可穿过 bridge 的字符串。 */
233
+ function encode(bytes) {
234
+ return channel === 'base64' ? encodeBase64(bytes) : bytesToLatin1(bytes);
235
+ }
236
+ /** 按当前通道把 bridge 返回的字符串还原成字节。 */
237
+ function decode(text) {
238
+ return channel === 'base64' ? decodeBase64(text) : latin1ToBytes(text);
239
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * child_process 的公开类型。
3
+ *
4
+ * 与其他 types 文件同样的原因:child_process.ts 用 `export =` 导出模块本体,
5
+ * 无法再导出类型。
6
+ */
7
+ import type { NodeStyleError } from './errors';
8
+ import type { Buffer } from '../buffer';
9
+ /** 驱动层一次执行的完整结果(含启动失败)。 */
10
+ export interface RunOutcome {
11
+ pid: number;
12
+ status: number | null;
13
+ signal: string | null;
14
+ stdout: Buffer;
15
+ stderr: Buffer;
16
+ error?: NodeStyleError;
17
+ }
18
+ export interface ExecOptions {
19
+ cwd?: string;
20
+ env?: Record<string, string>;
21
+ encoding?: string;
22
+ timeout?: number;
23
+ maxBuffer?: number;
24
+ shell?: string | boolean;
25
+ windowsHide?: boolean;
26
+ }
27
+ export interface SpawnSyncResult {
28
+ pid: number;
29
+ output: Array<unknown>;
30
+ stdout: unknown;
31
+ stderr: unknown;
32
+ status: number | null;
33
+ signal: string | null;
34
+ error?: Error;
35
+ }
36
+ export interface ExecException extends Error {
37
+ code?: string;
38
+ status?: number | null;
39
+ signal?: string | null;
40
+ stdout?: unknown;
41
+ stderr?: unknown;
42
+ pid?: number;
43
+ killed?: boolean;
44
+ }
45
+ export type ExecCallback = (error: ExecException | null, stdout?: unknown, stderr?: unknown) => void;
@@ -0,0 +1,2 @@
1
+ 'use strict';
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ export declare function get(): string;
2
+ export declare function set(next: string): void;
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.get = get;
4
+ exports.set = set;
5
+ /**
6
+ * 当前工作目录的唯一持有者。
7
+ *
8
+ * path.resolve 需要 cwd,而 cwd 的语义由 fs 的环境状态机决定(环境 = 根 + cwd + 能力)。
9
+ * 独立成模块是为了打破 path 与 fs 之间的循环依赖:path 只读,fs / process 只写。
10
+ */
11
+ let current = '/';
12
+ function get() {
13
+ return current;
14
+ }
15
+ function set(next) {
16
+ if (typeof next !== 'string' || next.length === 0) {
17
+ throw new TypeError('cwd 必须是非空字符串,收到 ' + describe(next));
18
+ }
19
+ current = next;
20
+ }
21
+ function describe(value) {
22
+ if (typeof value === 'string') {
23
+ return "'" + value + "'";
24
+ }
25
+ if (value === null) {
26
+ return 'null';
27
+ }
28
+ if (value === undefined) {
29
+ return 'undefined';
30
+ }
31
+ return String(value);
32
+ }
@@ -0,0 +1,3 @@
1
+ export declare function isDeepStrictEqual(left: unknown, right: unknown, loose?: boolean): boolean;
2
+ /** Node 的旧版宽松深比较(assert.deepEqual),叶子用 == 且不检查原型。 */
3
+ export declare function isDeepEqual(left: unknown, right: unknown): boolean;