oox 0.3.0-beta1 → 0.3.0-beta11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app.js +15 -14
- package/bin/cli.js +42 -36
- package/bin/configurer.js +24 -9
- package/bin/loader.mjs +459 -0
- package/bin/proxyer.js +15 -10
- package/bin/register.js +3 -2
- package/bin/starter.js +26 -32
- package/index.js +35 -16
- package/index.mjs +1 -0
- package/logger.js +40 -0
- package/modules/http/index.js +15 -3
- package/modules/index.js +20 -20
- package/modules/socketio/index.js +20 -0
- package/modules/socketio/server.js +13 -7
- package/package.json +10 -5
- package/types/app.d.ts +14 -0
- package/types/bin/cli.d.ts +3 -1
- package/types/bin/configurer.d.ts +3 -1
- package/types/bin/starter.d.ts +3 -1
- package/types/index.d.ts +9 -3
- package/types/logger.d.ts +4 -0
- package/types/modules/http/utils.d.ts +2 -2
- package/types/modules/index.d.ts +1 -0
- package/types/modules/module.d.ts +2 -0
- package/types/modules/socketio/index.d.ts +3 -1
- package/types/modules/socketio/server.d.ts +2 -2
package/app.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.execute = exports.call = exports.on = exports.getMethods = exports.setMethods = exports.sourceKVMethods = exports.kvMethods = exports.eventHub = exports.asyncStore = exports.Context = void 0;
|
|
3
|
+
exports.execute = exports.call = exports.emit = exports.off = exports.once = exports.on = exports.getMethods = exports.setMethods = exports.sourceKVMethods = exports.kvMethods = exports.eventHub = exports.asyncStore = exports.Context = exports.logger = void 0;
|
|
4
4
|
const node_events_1 = require("node:events");
|
|
5
5
|
const node_async_hooks_1 = require("node:async_hooks");
|
|
6
6
|
const utils_1 = require("./utils");
|
|
7
|
+
exports.logger = require("./logger");
|
|
7
8
|
class Context {
|
|
8
9
|
// 请求溯源ID
|
|
9
10
|
traceId = '';
|
|
@@ -32,9 +33,21 @@ function getMethods() {
|
|
|
32
33
|
}
|
|
33
34
|
exports.getMethods = getMethods;
|
|
34
35
|
function on(event, listener) {
|
|
35
|
-
|
|
36
|
+
exports.eventHub.on(event, listener);
|
|
36
37
|
}
|
|
37
38
|
exports.on = on;
|
|
39
|
+
function once(event, listener) {
|
|
40
|
+
exports.eventHub.once(event, listener);
|
|
41
|
+
}
|
|
42
|
+
exports.once = once;
|
|
43
|
+
function off(event, listener) {
|
|
44
|
+
exports.eventHub.off(event, listener);
|
|
45
|
+
}
|
|
46
|
+
exports.off = off;
|
|
47
|
+
function emit(event, ...args) {
|
|
48
|
+
return exports.eventHub.emit(event, ...args);
|
|
49
|
+
}
|
|
50
|
+
exports.emit = emit;
|
|
38
51
|
/**
|
|
39
52
|
* Call an Function on RPC server
|
|
40
53
|
* @param action
|
|
@@ -124,18 +137,6 @@ async function execute(action, params, context) {
|
|
|
124
137
|
// ============================= PROXY END =============================
|
|
125
138
|
// make sure target action execute after all proxies
|
|
126
139
|
if (target) {
|
|
127
|
-
/*
|
|
128
|
-
const sourceMethod = wrappedActions.get ( action )
|
|
129
|
-
|
|
130
|
-
const middlewareNames = actionMiddlewares.get ( sourceMethod )
|
|
131
|
-
|
|
132
|
-
if ( middlewareNames && middlewareNames.length ) for ( const name of middlewareNames ) {
|
|
133
|
-
|
|
134
|
-
const middleware = middlewares.get ( name )
|
|
135
|
-
|
|
136
|
-
await middleware ( action, params, context )
|
|
137
|
-
}
|
|
138
|
-
*/
|
|
139
140
|
return await target(...params);
|
|
140
141
|
}
|
|
141
142
|
}
|
package/bin/cli.js
CHANGED
|
@@ -1,43 +1,49 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.startup = exports.version = void 0;
|
|
4
5
|
const chalk_1 = require("chalk");
|
|
5
6
|
const starter_1 = require("./starter");
|
|
7
|
+
Object.defineProperty(exports, "startup", { enumerable: true, get: function () { return starter_1.startup; } });
|
|
6
8
|
const pkg = require("../package.json");
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
exports.version = pkg.version;
|
|
10
|
+
const jsExecutionFilename = process.argv[1];
|
|
11
|
+
if (/(oox.*cli\.js)$/.test(jsExecutionFilename)) {
|
|
12
|
+
const args = process.argv.slice(2);
|
|
13
|
+
const command = args[0];
|
|
14
|
+
var isStartup = true;
|
|
15
|
+
if (!command || ['help', '-h', '-help', '--help', 'version', '-v', '-version', '--version'].includes(command)) {
|
|
16
|
+
isStartup = false;
|
|
17
|
+
console.log();
|
|
18
|
+
console.log('OOX Service');
|
|
19
|
+
console.log((0, chalk_1.bold) `version`, chalk_1.bold.green `${pkg.version}`);
|
|
20
|
+
console.log((0, chalk_1.underline) `${pkg.homepage}`);
|
|
21
|
+
console.log();
|
|
22
|
+
}
|
|
23
|
+
if (['help', '-h', '-help', '--help'].includes(command)) {
|
|
24
|
+
console.log((0, chalk_1.bold) `Usage:`);
|
|
25
|
+
console.log(' oox entry.js');
|
|
26
|
+
console.log();
|
|
27
|
+
console.log(' oox entry.js port=8080');
|
|
28
|
+
console.log();
|
|
29
|
+
console.log(' oox app/entry/index.js group=app/ env=envs/entry.js ignore=core');
|
|
30
|
+
console.log();
|
|
31
|
+
console.log((0, chalk_1.bold) `Params:`);
|
|
32
|
+
const params = [
|
|
33
|
+
[' default-env [ file ] ', '.js or .json file, merge to oox.config'],
|
|
34
|
+
[' env [ file ] ', '.js or .json file, merge to oox.config', (0, chalk_1.bold) `(after default-env)`],
|
|
35
|
+
[' port [ int ] ', 'set', (0, chalk_1.bold) `0`, 'for random port, or any integer > 0'],
|
|
36
|
+
[' group [ dir ] ', 'service group directory, all LocalCall transform to RPC'],
|
|
37
|
+
[' ignore [ name ] ', 'set a name for LocalCall do not transform to RPC, support string | array<string>'],
|
|
38
|
+
[' http [ json ] ', 'HTTP server options, support flat name, ex: http.path=/api'],
|
|
39
|
+
[' socketio [ json ] ', 'SocketIO server options, support flat name'],
|
|
40
|
+
[' registry [ urls ] ', 'registry service url, support string | array<string>'],
|
|
41
|
+
[' origin [ urls ] ', 'set', (0, chalk_1.bold) `*`, 'allow any connections <Access-Control-Allow-Origin>'],
|
|
42
|
+
[' ... ', 'set params as', (0, chalk_1.bold) `foo=bar` + ',', 'usage as', (0, chalk_1.bold) `oox.config.foo`]
|
|
43
|
+
];
|
|
44
|
+
params.forEach(row => console.log(...row, '\n'));
|
|
45
|
+
console.log();
|
|
46
|
+
}
|
|
47
|
+
if (isStartup)
|
|
48
|
+
(0, starter_1.startup)();
|
|
17
49
|
}
|
|
18
|
-
if (['help', '-h', '-help', '--help'].includes(command)) {
|
|
19
|
-
console.log((0, chalk_1.bold) `Usage:`);
|
|
20
|
-
console.log(' oox entry.js');
|
|
21
|
-
console.log();
|
|
22
|
-
console.log(' oox entry.js port=8080');
|
|
23
|
-
console.log();
|
|
24
|
-
console.log(' oox app/entry/index.js group=app/ env=envs/entry.js ignore=core');
|
|
25
|
-
console.log();
|
|
26
|
-
console.log((0, chalk_1.bold) `Params:`);
|
|
27
|
-
const params = [
|
|
28
|
-
[' default-env [ file ] ', '.js or .json file, merge to oox.config'],
|
|
29
|
-
[' env [ file ] ', '.js or .json file, merge to oox.config', (0, chalk_1.bold) `(after default-env)`],
|
|
30
|
-
[' port [ int ] ', 'set', (0, chalk_1.bold) `0`, 'for random port, or any integer > 0'],
|
|
31
|
-
[' group [ dir ] ', 'service group directory, all LocalCall transform to RPC'],
|
|
32
|
-
[' ignore [ name ] ', 'set a name for LocalCall do not transform to RPC, support string | array<string>'],
|
|
33
|
-
[' http [ json ] ', 'HTTP server options, support flat name, ex: http.path=/api'],
|
|
34
|
-
[' socketio [ json ] ', 'SocketIO server options, support flat name'],
|
|
35
|
-
[' registry [ urls ] ', 'registry service url, support string | array<string>'],
|
|
36
|
-
[' origin [ urls ] ', 'set', (0, chalk_1.bold) `*`, 'allow any connections <Access-Control-Allow-Origin>'],
|
|
37
|
-
[' ... ', 'set params as', (0, chalk_1.bold) `foo=bar` + ',', 'usage as', (0, chalk_1.bold) `oox.config.foo`]
|
|
38
|
-
];
|
|
39
|
-
params.forEach(row => console.log(...row, '\n'));
|
|
40
|
-
console.log();
|
|
41
|
-
}
|
|
42
|
-
if (isStartup)
|
|
43
|
-
(0, starter_1.startup)();
|
package/bin/configurer.js
CHANGED
|
@@ -25,17 +25,30 @@ function mergeFlatEnv(env) {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
function
|
|
29
|
-
let env =
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
async function readEnvFile(filePath) {
|
|
29
|
+
let env = {};
|
|
30
|
+
if (filePath && fs.existsSync(filePath)) {
|
|
31
|
+
if (filePath.endsWith('.json')) {
|
|
32
|
+
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
33
|
+
env = JSON.parse(raw);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const finalPath = path.resolve(filePath).replace(/\\/g, '/');
|
|
37
|
+
env = await eval(`import('file://${finalPath}')`);
|
|
38
|
+
}
|
|
33
39
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Object.assign(env, require(path.resolve(envPath)));
|
|
40
|
+
else {
|
|
41
|
+
throw new Error('Env file not found: ' + filePath);
|
|
37
42
|
}
|
|
38
|
-
|
|
43
|
+
return env.default || env;
|
|
44
|
+
}
|
|
45
|
+
async function configure(mergeEnv) {
|
|
46
|
+
const env = Object.create(null);
|
|
47
|
+
const defaultEnvPath = argv.getEnvArg('default-env');
|
|
48
|
+
const targetEnvPath = argv.getEnvArg('env');
|
|
49
|
+
const defaultEnv = defaultEnvPath ? await readEnvFile(defaultEnvPath) : {};
|
|
50
|
+
const targetEnv = targetEnvPath ? await readEnvFile(targetEnvPath) : {};
|
|
51
|
+
Object.assign(env, defaultEnv, targetEnv, argv.getAllEnvArgs());
|
|
39
52
|
mergeFlatEnv(env);
|
|
40
53
|
if ('string' === typeof env.ignore)
|
|
41
54
|
env.ignore = env.ignore.split(',');
|
|
@@ -44,6 +57,8 @@ function configure() {
|
|
|
44
57
|
if ('string' === typeof env.origin && env.origin.includes(',')) {
|
|
45
58
|
env.origin = env.origin.split(',');
|
|
46
59
|
}
|
|
60
|
+
if (mergeEnv)
|
|
61
|
+
Object.assign(env, mergeEnv);
|
|
47
62
|
return env;
|
|
48
63
|
}
|
|
49
64
|
exports.configure = configure;
|
package/bin/loader.mjs
ADDED
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
|
|
4
|
+
import os from 'node:os'
|
|
5
|
+
|
|
6
|
+
import fs from 'node:fs'
|
|
7
|
+
|
|
8
|
+
import { get as httpGet } from 'node:http'
|
|
9
|
+
|
|
10
|
+
import { get as httpsGet } from 'node:https'
|
|
11
|
+
|
|
12
|
+
import oox from '../index.mjs'
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* NodeJS versions < 16 dose not support loader chain
|
|
17
|
+
*/
|
|
18
|
+
const NodeJSBigVersion = +process.versions.node.split('.').shift()
|
|
19
|
+
const useCompatLoader = NodeJSBigVersion < 16
|
|
20
|
+
const compatLoaders = []
|
|
21
|
+
if ( useCompatLoader ) {
|
|
22
|
+
const args = process.execArgv
|
|
23
|
+
let index = -1, size = args.length
|
|
24
|
+
let isLoaderTag = false
|
|
25
|
+
while ( ++index < size ) {
|
|
26
|
+
|
|
27
|
+
const symbol = args [ index ]
|
|
28
|
+
|
|
29
|
+
if ( isLoaderTag ) {
|
|
30
|
+
|
|
31
|
+
isLoaderTag = false
|
|
32
|
+
|
|
33
|
+
if ( 'oox/loader' === symbol ) break
|
|
34
|
+
|
|
35
|
+
compatLoaders.push ( await import ( symbol ) )
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if ( [ '--loader', '--experimental-loader' ].includes ( symbol ) ) {
|
|
39
|
+
|
|
40
|
+
isLoaderTag = true
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
compatLoaders.reverse ( )
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
function generateRPCProxyScript ( name, attributes = [ ] ) {
|
|
50
|
+
|
|
51
|
+
let attrExports = ''
|
|
52
|
+
|
|
53
|
+
for ( const attr of attributes ) {
|
|
54
|
+
|
|
55
|
+
attrExports += `\nexport const ${attr} = proxyer.${attr}\n`
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const script = `
|
|
59
|
+
import oox from 'oox'
|
|
60
|
+
function RPC_${name} ( ) { }
|
|
61
|
+
function dotCall ( name, action ) {
|
|
62
|
+
|
|
63
|
+
return new Proxy ( RPC_${name}, {
|
|
64
|
+
|
|
65
|
+
get ( target, key ) {
|
|
66
|
+
|
|
67
|
+
return dotCall ( name, action ? action + '.' + key : key )
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
has ( target, key ) { return true },
|
|
71
|
+
|
|
72
|
+
apply ( target, thisArg, args ) {
|
|
73
|
+
|
|
74
|
+
return oox.rpc ( name, action, args )
|
|
75
|
+
}
|
|
76
|
+
} )
|
|
77
|
+
}
|
|
78
|
+
const proxyer = dotCall ( '${name}', '' )
|
|
79
|
+
export default proxyer
|
|
80
|
+
${attrExports}
|
|
81
|
+
`
|
|
82
|
+
|
|
83
|
+
return script
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
function generateRPCProxyURL ( name, attributes ) {
|
|
89
|
+
|
|
90
|
+
let searchText = ''
|
|
91
|
+
|
|
92
|
+
if ( attributes.length ) {
|
|
93
|
+
|
|
94
|
+
const search = new URLSearchParams ( )
|
|
95
|
+
|
|
96
|
+
for ( const attr of attributes ) {
|
|
97
|
+
|
|
98
|
+
search.append ( 'attr', attr )
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
searchText = '?' + search.toString ( )
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return `oox://rpc/${name}.mjs${searchText}`
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
function isWebURL ( url ) {
|
|
110
|
+
|
|
111
|
+
return url && ( url.startsWith ( 'https://' ) || url.startsWith ( 'http://' ) )
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
function isFileURL ( url ) {
|
|
117
|
+
|
|
118
|
+
return url && url.startsWith ( 'file://' )
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
function isOOXURL ( url ) {
|
|
124
|
+
|
|
125
|
+
return url && url.startsWith ( 'oox://' )
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
function pathCorrect ( path ) {
|
|
131
|
+
|
|
132
|
+
return os.platform ( ) === 'win32' && path.startsWith ( '/' ) ? path.replace ( '/', '' ) : path
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* make ESModule support dynamic <export *> attributes import
|
|
139
|
+
* @param {string} importerSpecifier the import url
|
|
140
|
+
* @param {string} specifier parentURL
|
|
141
|
+
* @returns {string[]}
|
|
142
|
+
*/
|
|
143
|
+
function getImportAttributes ( importerSpecifier, specifier ) {
|
|
144
|
+
|
|
145
|
+
const attributes = [ ]
|
|
146
|
+
|
|
147
|
+
const contents = fs.readFileSync ( importerSpecifier, 'utf-8' )
|
|
148
|
+
|
|
149
|
+
// import * as xxx from "xxx"
|
|
150
|
+
const mergeImport = contents.match ( new RegExp ( `import.+\\*\\s*as\\s+(\\w+)\\s+from\\s*["']${specifier}["']` ) )
|
|
151
|
+
|
|
152
|
+
if ( mergeImport ) {
|
|
153
|
+
|
|
154
|
+
const mergeName = mergeImport [ 1 ]
|
|
155
|
+
|
|
156
|
+
const attributesIterator = contents.matchAll ( new RegExp ( `${mergeName}\\s*\\.\\s*(\\w+)`, 'g' ) )
|
|
157
|
+
|
|
158
|
+
for ( const caseItem of attributesIterator ) {
|
|
159
|
+
|
|
160
|
+
attributes.push ( caseItem [ 1 ] )
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// import { a, b, c } from 'xxx'
|
|
165
|
+
const attributeImport = contents.match ( new RegExp ( `import.+{(.+)}\\s*from\\s*["']${specifier}["']` ) )
|
|
166
|
+
|
|
167
|
+
if ( attributeImport ) {
|
|
168
|
+
|
|
169
|
+
const definedAttributes = attributeImport [ 1 ].split ( ',' ).map ( v => v.trim ( ) ).filter ( v => !v.startsWith ( 'default' ) )
|
|
170
|
+
|
|
171
|
+
attributes.push ( ...definedAttributes )
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return Array.from ( new Set ( attributes ) )
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* transform local call => RPC
|
|
181
|
+
* @param {string} originalSpecifier
|
|
182
|
+
* @param {string} specifier
|
|
183
|
+
* @param {string} parentURL
|
|
184
|
+
* @returns
|
|
185
|
+
*/
|
|
186
|
+
function ooxRPCImportTransform ( originalSpecifier, specifier, parentURL ) {
|
|
187
|
+
|
|
188
|
+
const { entryFile } = oox.config
|
|
189
|
+
|
|
190
|
+
const url = new URL ( specifier )
|
|
191
|
+
|
|
192
|
+
const groupURL = entryFile.group ? new URL ( '/' + entryFile.group, 'file://' ) : null
|
|
193
|
+
|
|
194
|
+
// OOX RPC Proxy URL generation
|
|
195
|
+
if ( !specifier.endsWith ( entryFile.path ) && groupURL && url.href.startsWith ( groupURL.href ) ) {
|
|
196
|
+
|
|
197
|
+
const subSpecifier = url.href.slice ( groupURL.href.length )
|
|
198
|
+
|
|
199
|
+
const matchResult = subSpecifier.match ( /^\/?([\w-]+)(\/index)?(\.((\w?js)|(ts\w?)))?$/ )
|
|
200
|
+
|
|
201
|
+
if ( matchResult ) {
|
|
202
|
+
|
|
203
|
+
const importerSpecifier = parentURL.replace ( os.platform ( ) === 'win32' ? /file:\/+/ : 'file://', '' )
|
|
204
|
+
|
|
205
|
+
const attributes = getImportAttributes ( importerSpecifier, originalSpecifier )
|
|
206
|
+
|
|
207
|
+
return { shortCircuit: true, url: generateRPCProxyURL ( matchResult [ 1 ], attributes ) }
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return null
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Directory import supported
|
|
218
|
+
* Ignored '.ts|.js' suffix import supported
|
|
219
|
+
* @param {string} specifier
|
|
220
|
+
* @returns {string}
|
|
221
|
+
*/
|
|
222
|
+
function directoryImportTransform ( specifier ) {
|
|
223
|
+
|
|
224
|
+
let filename = new URL ( specifier ).pathname
|
|
225
|
+
|
|
226
|
+
if ( os.platform ( ) === 'win32' && filename.startsWith ( '/' ) ) {
|
|
227
|
+
|
|
228
|
+
filename = filename.replace ( '/', '' )
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const stat0 = fs.statSync ( filename, {
|
|
232
|
+
throwIfNoEntry: false
|
|
233
|
+
} )
|
|
234
|
+
|
|
235
|
+
if ( !stat0 || stat0.isDirectory ( ) ) {
|
|
236
|
+
|
|
237
|
+
const justNeedEntry = stat0 && stat0.isDirectory ( )
|
|
238
|
+
|
|
239
|
+
const dirname = justNeedEntry ? filename : path.dirname ( filename )
|
|
240
|
+
|
|
241
|
+
const stat1 = justNeedEntry ? stat0 : fs.statSync ( dirname, {
|
|
242
|
+
throwIfNoEntry: false
|
|
243
|
+
} )
|
|
244
|
+
|
|
245
|
+
// find entry file
|
|
246
|
+
if ( stat1 && stat1.isDirectory ( ) ) {
|
|
247
|
+
|
|
248
|
+
const paths = filename.split ( '/' )
|
|
249
|
+
|
|
250
|
+
const filenameWithoutExtension = justNeedEntry ? 'index' : paths.pop ( )
|
|
251
|
+
|
|
252
|
+
const matchEntryRegExp = new RegExp ( `^${filenameWithoutExtension}\\.((\\w?js)|(ts\\w?))$` )
|
|
253
|
+
|
|
254
|
+
const entries = fs.readdirSync ( dirname )
|
|
255
|
+
|
|
256
|
+
for ( const entry of entries ) {
|
|
257
|
+
|
|
258
|
+
if ( !matchEntryRegExp.test ( entry ) ) continue
|
|
259
|
+
|
|
260
|
+
paths.push ( entry )
|
|
261
|
+
|
|
262
|
+
specifier = 'file://' + paths.join ( '/' )
|
|
263
|
+
|
|
264
|
+
break
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return specifier
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* @param {string} specifier
|
|
276
|
+
* @param {{
|
|
277
|
+
* conditions: string[],
|
|
278
|
+
* parentURL: string | undefined,
|
|
279
|
+
* }} context
|
|
280
|
+
* @param {Function} defaultResolve
|
|
281
|
+
* @returns {Promise<{ url: string }>}
|
|
282
|
+
*/
|
|
283
|
+
export async function resolve ( specifier, context, defaultResolve ) {
|
|
284
|
+
|
|
285
|
+
const originalSpecifier = specifier
|
|
286
|
+
|
|
287
|
+
const { parentURL } = context
|
|
288
|
+
|
|
289
|
+
// HTTP & HTTPS
|
|
290
|
+
if ( isWebURL ( specifier ) ) {
|
|
291
|
+
|
|
292
|
+
return { shortCircuit: true, url: specifier }
|
|
293
|
+
} else if ( isWebURL ( parentURL ) && ( specifier.startsWith ( '.' ) || specifier.startsWith ( '/' ) ) ) {
|
|
294
|
+
|
|
295
|
+
return { shortCircuit: true, url: new URL ( specifier, parentURL ).href }
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// OOX special alias for web package
|
|
299
|
+
if ( specifier === 'oox' && !isFileURL ( parentURL ) ) {
|
|
300
|
+
|
|
301
|
+
return {
|
|
302
|
+
shortCircuit: true,
|
|
303
|
+
url: await import.meta.resolve ( specifier )
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if ( !isFileURL ( specifier ) ) {
|
|
308
|
+
|
|
309
|
+
try {
|
|
310
|
+
|
|
311
|
+
specifier = defaultResolve ( specifier, context, defaultResolve ).url
|
|
312
|
+
} catch ( error ) {
|
|
313
|
+
|
|
314
|
+
if ( !isFileURL ( parentURL ) ) throw error
|
|
315
|
+
|
|
316
|
+
const _specifier = directoryImportTransform ( new URL ( specifier, parentURL ).href )
|
|
317
|
+
|
|
318
|
+
if ( _specifier === specifier ) throw error
|
|
319
|
+
|
|
320
|
+
specifier = _specifier
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const ooxRPCTransform = ooxRPCImportTransform ( originalSpecifier, specifier, parentURL )
|
|
325
|
+
|
|
326
|
+
if ( ooxRPCTransform ) return ooxRPCTransform
|
|
327
|
+
|
|
328
|
+
if ( useCompatLoader ) {
|
|
329
|
+
|
|
330
|
+
const iterator = compatLoaders.values ( )
|
|
331
|
+
|
|
332
|
+
const { value } = iterator.next ( )
|
|
333
|
+
|
|
334
|
+
if ( value ) {
|
|
335
|
+
|
|
336
|
+
return value.resolve ( specifier, context, ( specifier, context, nextResolve ) => {
|
|
337
|
+
|
|
338
|
+
const { value } = iterator.next ( )
|
|
339
|
+
|
|
340
|
+
if ( value ) return value.resolve ( specifier, context, nextResolve )
|
|
341
|
+
|
|
342
|
+
return defaultResolve ( specifier, context, defaultResolve )
|
|
343
|
+
} )
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return defaultResolve ( specifier, context, defaultResolve )
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* @param {string} url
|
|
354
|
+
* @param {{
|
|
355
|
+
* format: string,
|
|
356
|
+
* }} context If resolve settled with a `format`, that value is included here.
|
|
357
|
+
* @param {Function} defaultLoad
|
|
358
|
+
* @returns {Promise<{
|
|
359
|
+
* format: string,
|
|
360
|
+
* source: string | ArrayBuffer | SharedArrayBuffer | Uint8Array,
|
|
361
|
+
* }>}
|
|
362
|
+
*/
|
|
363
|
+
export async function load ( url, context, defaultLoad ) {
|
|
364
|
+
|
|
365
|
+
if ( isWebURL ( url ) || isOOXURL ( url ) ) {
|
|
366
|
+
|
|
367
|
+
return getSource ( url, context, defaultLoad )
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if ( useCompatLoader ) {
|
|
371
|
+
|
|
372
|
+
const iterator = compatLoaders.values ( )
|
|
373
|
+
|
|
374
|
+
const { value } = iterator.next ( )
|
|
375
|
+
|
|
376
|
+
if ( value ) {
|
|
377
|
+
|
|
378
|
+
return value.load ( url, context, ( url, context, nextLoad ) => {
|
|
379
|
+
|
|
380
|
+
const { value } = iterator.next ( )
|
|
381
|
+
|
|
382
|
+
if ( value ) return value.load ( url, context, nextLoad )
|
|
383
|
+
|
|
384
|
+
return defaultLoad ( url, context, defaultLoad )
|
|
385
|
+
} )
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return defaultLoad ( url, context, defaultLoad )
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
export function getFormat ( url, context, defaultGetFormat ) {
|
|
395
|
+
|
|
396
|
+
if ( isWebURL ( url ) || isOOXURL ( url ) ) {
|
|
397
|
+
|
|
398
|
+
return {
|
|
399
|
+
format: 'module'
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if ( useCompatLoader ) {
|
|
404
|
+
|
|
405
|
+
const iterator = compatLoaders.values ( )
|
|
406
|
+
|
|
407
|
+
const { value } = iterator.next ( )
|
|
408
|
+
|
|
409
|
+
if ( value ) {
|
|
410
|
+
|
|
411
|
+
return value.getFormat ( url, context, ( url, context, nextGetFormat ) => {
|
|
412
|
+
|
|
413
|
+
const { value } = iterator.next ( )
|
|
414
|
+
|
|
415
|
+
if ( value ) return value.getFormat ( url, context, nextGetFormat )
|
|
416
|
+
|
|
417
|
+
return defaultGetFormat ( url, context, defaultGetFormat )
|
|
418
|
+
} )
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return defaultGetFormat ( url, context, defaultGetFormat )
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
export function getSource ( url, context, defaultGetSource ) {
|
|
428
|
+
|
|
429
|
+
if ( isWebURL ( url ) ) {
|
|
430
|
+
|
|
431
|
+
const getMethod = url.startsWith ( 'https://' ) ? httpsGet : httpGet
|
|
432
|
+
|
|
433
|
+
return new Promise ( ( resolve, reject ) => getMethod ( url, res => {
|
|
434
|
+
let source = ''
|
|
435
|
+
res
|
|
436
|
+
.on ( 'data', chunk => source += chunk )
|
|
437
|
+
.on ( 'end', () => resolve ( { shortCircuit: true, format: 'module', source } ) )
|
|
438
|
+
} ).on ( 'error', reject ) )
|
|
439
|
+
} else if ( isOOXURL ( url ) ) {
|
|
440
|
+
|
|
441
|
+
const mURL = new URL ( url )
|
|
442
|
+
|
|
443
|
+
if ( mURL.host === 'rpc' ) {
|
|
444
|
+
|
|
445
|
+
const regexp = /\/([\w-]+)\.mjs$/
|
|
446
|
+
|
|
447
|
+
const matchResult = mURL.pathname.match ( regexp )
|
|
448
|
+
|
|
449
|
+
// read all import attributes
|
|
450
|
+
const attributes = mURL.searchParams.getAll ( 'attr' )
|
|
451
|
+
|
|
452
|
+
const source = generateRPCProxyScript ( matchResult [ 1 ], attributes )
|
|
453
|
+
|
|
454
|
+
return { shortCircuit: true, format: 'module', source }
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return defaultGetSource ( url, context, defaultGetSource )
|
|
459
|
+
}
|
package/bin/proxyer.js
CHANGED
|
@@ -21,14 +21,14 @@ function rewriteModuleCache(id, exports) {
|
|
|
21
21
|
m.paths = paths;
|
|
22
22
|
require.cache[id] = m;
|
|
23
23
|
}
|
|
24
|
-
function dotCall(name,
|
|
24
|
+
function dotCall(name, action) {
|
|
25
25
|
return new Proxy(function () { }, {
|
|
26
26
|
get(target, key) {
|
|
27
|
-
return dotCall(name,
|
|
27
|
+
return dotCall(name, action ? action + '.' + key : key);
|
|
28
28
|
},
|
|
29
29
|
has(target, key) { return true; },
|
|
30
30
|
apply(target, thisArg, args) {
|
|
31
|
-
return oox.rpc(name,
|
|
31
|
+
return oox.rpc(name, action, args);
|
|
32
32
|
}
|
|
33
33
|
});
|
|
34
34
|
}
|
|
@@ -44,18 +44,23 @@ function proxyGroup(groupDirectory, excludes = []) {
|
|
|
44
44
|
const fullPath = path.resolve(directory + path.sep + filename);
|
|
45
45
|
const stat = fs.statSync(fullPath);
|
|
46
46
|
let id = '', name = '';
|
|
47
|
-
if (stat.isDirectory()
|
|
48
|
-
|
|
47
|
+
if (stat.isDirectory()) {
|
|
48
|
+
const entries = fs.readdirSync(fullPath);
|
|
49
|
+
for (const entry of entries) {
|
|
50
|
+
if (/^index\.((\w?js)|(ts\w?))$/.test(entry))
|
|
51
|
+
id = path.resolve(fullPath, entry);
|
|
52
|
+
}
|
|
49
53
|
name = filename;
|
|
50
54
|
}
|
|
51
|
-
else
|
|
55
|
+
else {
|
|
56
|
+
const scriptMatch = filename.match(/(\w+)\.((\w?js)|(ts\w?))$/);
|
|
57
|
+
if (!scriptMatch)
|
|
58
|
+
continue;
|
|
52
59
|
id = fullPath;
|
|
53
|
-
name =
|
|
60
|
+
name = scriptMatch[1];
|
|
54
61
|
}
|
|
55
|
-
else
|
|
56
|
-
continue;
|
|
57
62
|
if (!excludes.includes(name))
|
|
58
|
-
rewriteModuleCache(id, dotCall(name));
|
|
63
|
+
rewriteModuleCache(id, dotCall(name, ''));
|
|
59
64
|
}
|
|
60
65
|
}
|
|
61
66
|
exports.proxyGroup = proxyGroup;
|