hackmud-script-manager 0.20.4-23a791c → 0.20.4-34a1e78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/bin/hsm.js +296 -262
- package/env.d.ts +363 -289
- package/generateTypeDeclaration.js +2 -1
- package/index.d.ts +3 -0
- package/index.js +2 -1
- package/package.json +38 -38
- package/processScript/index.d.ts +0 -1
- package/processScript/index.js +5 -5
- package/processScript/minify.js +11 -17
- package/processScript/postprocess.d.ts +1 -1
- package/processScript/postprocess.js +3 -3
- package/processScript/preprocess.js +5 -3
- package/processScript/transform.d.ts +3 -0
- package/processScript/transform.js +110 -97
- package/push.d.ts +9 -1
- package/push.js +38 -16
- package/watch.js +25 -26
@@ -22,9 +22,8 @@ const { default: traverse } = babelTraverse,
|
|
22
22
|
"BigInt"
|
23
23
|
]
|
24
24
|
function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scriptName, seclevel = 4 }) {
|
25
|
-
const
|
26
|
-
|
27
|
-
liveExports = new Map()
|
25
|
+
const warnings = [],
|
26
|
+
topFunctionName = `_${uniqueId}_SCRIPT_`
|
28
27
|
let program
|
29
28
|
traverse(file, {
|
30
29
|
Program(path) {
|
@@ -46,9 +45,17 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
46
45
|
referencePath.replaceWith(t.identifier(`_${uniqueId}_SCRIPT_USER_`))
|
47
46
|
} else
|
48
47
|
referencePath.replaceWith(t.stringLiteral(1 == scriptUser ? `$${uniqueId}$SCRIPT_USER$` : scriptUser))
|
49
|
-
if (program.scope.hasGlobal("_SCRIPT_NAME"))
|
48
|
+
if (program.scope.hasGlobal("_SCRIPT_NAME")) {
|
49
|
+
warnings.push({
|
50
|
+
message:
|
51
|
+
"Global _SCRIPT_NAME is deprecated and will be removed in the next minor release of HSM, use _SCRIPT_SUBNAME instead"
|
52
|
+
})
|
50
53
|
for (const referencePath of getReferencePathsToGlobal("_SCRIPT_NAME", program))
|
51
54
|
referencePath.replaceWith(t.stringLiteral(1 == scriptName ? `$${uniqueId}$SCRIPT_NAME$` : scriptName))
|
55
|
+
}
|
56
|
+
if (program.scope.hasGlobal("_SCRIPT_SUBNAME"))
|
57
|
+
for (const referencePath of getReferencePathsToGlobal("_SCRIPT_SUBNAME", program))
|
58
|
+
referencePath.replaceWith(t.stringLiteral(1 == scriptName ? `$${uniqueId}$SCRIPT_NAME$` : scriptName))
|
52
59
|
if (program.scope.hasGlobal("_FULL_SCRIPT_NAME"))
|
53
60
|
for (const referencePath of getReferencePathsToGlobal("_FULL_SCRIPT_NAME", program))
|
54
61
|
if (1 == scriptUser || 1 == scriptName)
|
@@ -70,30 +77,30 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
70
77
|
const referencePath = FunctionReferencePaths[0]
|
71
78
|
assert(
|
72
79
|
"MemberExpression" == referencePath.parent.type,
|
73
|
-
"src/processScript/transform.ts:
|
80
|
+
"src/processScript/transform.ts:111:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
|
74
81
|
)
|
75
82
|
assert(
|
76
83
|
"Identifier" == referencePath.parent.property.type,
|
77
|
-
"src/processScript/transform.ts:
|
84
|
+
"src/processScript/transform.ts:116:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
|
78
85
|
)
|
79
86
|
assert(
|
80
87
|
"prototype" == referencePath.parent.property.name,
|
81
|
-
"src/processScript/transform.ts:
|
88
|
+
"src/processScript/transform.ts:121:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
|
82
89
|
)
|
83
90
|
referencePath.parentPath.replaceWith(createGetFunctionPrototypeNode())
|
84
91
|
} else {
|
85
92
|
for (const referencePath of FunctionReferencePaths) {
|
86
93
|
assert(
|
87
94
|
"MemberExpression" == referencePath.parent.type,
|
88
|
-
"src/processScript/transform.ts:
|
95
|
+
"src/processScript/transform.ts:129:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
|
89
96
|
)
|
90
97
|
assert(
|
91
98
|
"Identifier" == referencePath.parent.property.type,
|
92
|
-
"src/processScript/transform.ts:
|
99
|
+
"src/processScript/transform.ts:134:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
|
93
100
|
)
|
94
101
|
assert(
|
95
102
|
"prototype" == referencePath.parent.property.name,
|
96
|
-
"src/processScript/transform.ts:
|
103
|
+
"src/processScript/transform.ts:139:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
|
97
104
|
)
|
98
105
|
functionDotPrototypeIsReferencedMultipleTimes = !0
|
99
106
|
referencePath.parentPath.replaceWith(t.identifier(`_${uniqueId}_FUNCTION_DOT_PROTOTYPE_`))
|
@@ -101,40 +108,40 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
101
108
|
functionDotPrototypeIsReferencedMultipleTimes = !0
|
102
109
|
}
|
103
110
|
}
|
104
|
-
const neededSubscriptLets = new
|
111
|
+
const neededSubscriptLets = new Map()
|
105
112
|
let detectedSeclevel = 4
|
106
113
|
for (const fakeSubscriptObjectName of ["$fs", "$4s", "$s"])
|
107
|
-
program.scope.hasGlobal(fakeSubscriptObjectName) && processFakeSubscriptObject(fakeSubscriptObjectName)
|
114
|
+
program.scope.hasGlobal(fakeSubscriptObjectName) && processFakeSubscriptObject(fakeSubscriptObjectName, 4)
|
108
115
|
for (const fakeSubscriptObjectName of ["$hs", "$3s"])
|
109
116
|
if (program.scope.hasGlobal(fakeSubscriptObjectName)) {
|
110
117
|
detectedSeclevel = 3
|
111
|
-
processFakeSubscriptObject(fakeSubscriptObjectName)
|
118
|
+
processFakeSubscriptObject(fakeSubscriptObjectName, 3)
|
112
119
|
}
|
113
120
|
for (const fakeSubscriptObjectName of ["$ms", "$2s"])
|
114
121
|
if (program.scope.hasGlobal(fakeSubscriptObjectName)) {
|
115
122
|
detectedSeclevel = 2
|
116
|
-
processFakeSubscriptObject(fakeSubscriptObjectName)
|
123
|
+
processFakeSubscriptObject(fakeSubscriptObjectName, 2)
|
117
124
|
}
|
118
125
|
for (const fakeSubscriptObjectName of ["$ls", "$1s"])
|
119
126
|
if (program.scope.hasGlobal(fakeSubscriptObjectName)) {
|
120
127
|
detectedSeclevel = 1
|
121
|
-
processFakeSubscriptObject(fakeSubscriptObjectName)
|
128
|
+
processFakeSubscriptObject(fakeSubscriptObjectName, 1)
|
122
129
|
}
|
123
130
|
for (const fakeSubscriptObjectName of ["$ns", "$0s"])
|
124
131
|
if (program.scope.hasGlobal(fakeSubscriptObjectName)) {
|
125
132
|
detectedSeclevel = 0
|
126
|
-
processFakeSubscriptObject(fakeSubscriptObjectName)
|
133
|
+
processFakeSubscriptObject(fakeSubscriptObjectName, 0)
|
127
134
|
}
|
128
135
|
seclevel = Math.min(seclevel, detectedSeclevel)
|
129
136
|
const neededDbMethodLets = new Set()
|
130
137
|
if (program.scope.hasGlobal("$db"))
|
131
138
|
for (const referencePath of getReferencePathsToGlobal("$db", program)) {
|
132
|
-
assert("MemberExpression" == referencePath.parentPath.node.type, "src/processScript/transform.ts:
|
133
|
-
assert("Identifier" == referencePath.parentPath.node.property.type, "src/processScript/transform.ts:
|
139
|
+
assert("MemberExpression" == referencePath.parentPath.node.type, "src/processScript/transform.ts:193:69")
|
140
|
+
assert("Identifier" == referencePath.parentPath.node.property.type, "src/processScript/transform.ts:194:72")
|
134
141
|
const databaseOpMethodName = referencePath.parentPath.node.property.name
|
135
142
|
assert(
|
136
143
|
validDBMethods.includes(databaseOpMethodName),
|
137
|
-
`src/processScript/transform.ts:
|
144
|
+
`src/processScript/transform.ts:200:8 invalid db method "${databaseOpMethodName}", valid db methods are "${validDBMethods.join('", "')}"`
|
138
145
|
)
|
139
146
|
if ("CallExpression" == referencePath.parentPath.parentPath?.type)
|
140
147
|
referencePath.parentPath.replaceWith(t.identifier(`$${uniqueId}$DB$${databaseOpMethodName}$`))
|
@@ -157,27 +164,32 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
157
164
|
if (program.scope.hasGlobal("$FMCL"))
|
158
165
|
for (const referencePath of getReferencePathsToGlobal("$FMCL", program))
|
159
166
|
referencePath.replaceWith(t.identifier(`$${uniqueId}$FMCL$`))
|
160
|
-
|
167
|
+
let needG = program.scope.hasGlobal("$G")
|
168
|
+
if (needG)
|
161
169
|
for (const referencePath of getReferencePathsToGlobal("$G", program))
|
162
|
-
referencePath.replaceWith(t.identifier(
|
170
|
+
referencePath.replaceWith(t.identifier(`_${uniqueId}_G_`))
|
163
171
|
if (program.scope.hasGlobal("_SECLEVEL"))
|
164
172
|
for (const referencePath of getReferencePathsToGlobal("_SECLEVEL", program))
|
165
173
|
referencePath.replaceWith(t.numericLiteral(seclevel))
|
166
|
-
let needGetPrototypeOf = !1
|
174
|
+
let needGetPrototypeOf = !1,
|
175
|
+
needHasOwn = !1
|
167
176
|
if (program.scope.hasGlobal("Object"))
|
168
177
|
for (const referencePath of getReferencePathsToGlobal("Object", program))
|
169
178
|
if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
|
170
|
-
assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:
|
179
|
+
assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:250:64")
|
171
180
|
if ("getPrototypeOf" == referencePath.parent.property.name) {
|
172
181
|
referencePath.parentPath.replaceWith(t.identifier(`_${uniqueId}_GET_PROTOTYPE_OF_`))
|
173
182
|
needGetPrototypeOf = !0
|
183
|
+
} else if ("hasOwn" == referencePath.parent.property.name) {
|
184
|
+
referencePath.parentPath.replaceWith(t.identifier(`_${uniqueId}_HAS_OWN_`))
|
185
|
+
needHasOwn = !0
|
174
186
|
}
|
175
187
|
}
|
176
188
|
const consoleMethodsReferenced = new Set()
|
177
189
|
if (program.scope.hasGlobal("console"))
|
178
190
|
for (const referencePath of getReferencePathsToGlobal("console", program))
|
179
191
|
if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
|
180
|
-
assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:
|
192
|
+
assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:268:64")
|
181
193
|
referencePath.parentPath.replaceWith(
|
182
194
|
t.identifier(`_${uniqueId}_CONSOLE_METHOD_${referencePath.parent.property.name}_`)
|
183
195
|
)
|
@@ -185,19 +197,20 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
185
197
|
}
|
186
198
|
const lastStatement = program.node.body.at(-1)
|
187
199
|
let exportDefaultName
|
188
|
-
assert(lastStatement, "src/processScript/transform.ts:
|
200
|
+
assert(lastStatement, "src/processScript/transform.ts:282:27 program is empty")
|
189
201
|
if ("ExportNamedDeclaration" == lastStatement.type) {
|
190
202
|
program.node.body.pop()
|
191
203
|
for (const specifier of lastStatement.specifiers) {
|
192
204
|
assert(
|
193
205
|
"ExportSpecifier" == specifier.type,
|
194
|
-
`src/processScript/transform.ts:
|
206
|
+
`src/processScript/transform.ts:288:51 ${specifier.type} is currently unsupported`
|
207
|
+
)
|
208
|
+
if (
|
209
|
+
"default" !=
|
210
|
+
("Identifier" == specifier.exported.type ? specifier.exported.name : specifier.exported.value)
|
195
211
|
)
|
196
|
-
|
197
|
-
|
198
|
-
"default" == exportedName ?
|
199
|
-
(exportDefaultName = specifier.local.name)
|
200
|
-
: exports.set(specifier.local.name, exportedName)
|
212
|
+
throw Error("Only default exports are supported")
|
213
|
+
exportDefaultName = specifier.local.name
|
201
214
|
}
|
202
215
|
}
|
203
216
|
const globalBlock = t.blockStatement([])
|
@@ -223,10 +236,6 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
223
236
|
t.returnStatement(t.callExpression(t.identifier(exportDefaultName), []))
|
224
237
|
])
|
225
238
|
))
|
226
|
-
if ("const" != statement.kind && exports.has(identifierName)) {
|
227
|
-
liveExports.set(identifierName, exports.get(identifierName))
|
228
|
-
exports.delete(identifierName)
|
229
|
-
}
|
230
239
|
globalBlock.body.push(
|
231
240
|
t.variableDeclaration("let", [t.variableDeclarator(t.identifier(identifierName))])
|
232
241
|
)
|
@@ -291,34 +300,16 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
291
300
|
}
|
292
301
|
program.node.body = [mainFunction]
|
293
302
|
if (globalBlock.body.length) {
|
294
|
-
;(exports.size || liveExports.size) &&
|
295
|
-
mainFunction.body.body.push(
|
296
|
-
t.returnStatement(
|
297
|
-
t.objectExpression([
|
298
|
-
...[...exports].map(([local, exported]) =>
|
299
|
-
t.objectProperty(t.identifier(exported), t.identifier(local))
|
300
|
-
),
|
301
|
-
...[...liveExports].map(([local, exported]) =>
|
302
|
-
t.objectMethod(
|
303
|
-
"get",
|
304
|
-
t.identifier(exported),
|
305
|
-
[],
|
306
|
-
t.blockStatement([t.returnStatement(t.identifier(local))])
|
307
|
-
)
|
308
|
-
)
|
309
|
-
])
|
310
|
-
)
|
311
|
-
)
|
312
303
|
program.scope.crawl()
|
313
304
|
const globalBlockVariables = new Set()
|
314
305
|
let hoistedGlobalBlockFunctions = 0
|
315
306
|
for (const [globalBlockIndex, globalBlockStatement] of [...globalBlock.body.entries()].reverse())
|
316
307
|
if ("VariableDeclaration" == globalBlockStatement.type) {
|
317
|
-
assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:
|
308
|
+
assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:402:59")
|
318
309
|
const declarator = globalBlockStatement.declarations[0]
|
319
310
|
assert(
|
320
311
|
"Identifier" == declarator.id.type,
|
321
|
-
`src/processScript/transform.ts:
|
312
|
+
`src/processScript/transform.ts:406:51 declarator.id.type was "${declarator.id.type}"`
|
322
313
|
)
|
323
314
|
program.scope.crawl()
|
324
315
|
if (program.scope.hasGlobal(declarator.id.name)) {
|
@@ -333,15 +324,16 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
333
324
|
Object.keys(program.scope.globals).some(global => globalBlockVariables.has(global))
|
334
325
|
) {
|
335
326
|
const binding = program.scope.getBinding(declarator.id.name)
|
336
|
-
assert(binding, "src/processScript/transform.ts:
|
327
|
+
assert(binding, "src/processScript/transform.ts:425:23")
|
337
328
|
for (const referencePath of binding.referencePaths) {
|
338
|
-
assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:
|
329
|
+
assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:428:56")
|
339
330
|
referencePath.replaceWith(
|
340
331
|
t.memberExpression(
|
341
|
-
t.identifier(
|
332
|
+
t.identifier(`_${uniqueId}_G_`),
|
342
333
|
t.identifier(referencePath.node.name)
|
343
334
|
)
|
344
335
|
)
|
336
|
+
needG = !0
|
345
337
|
}
|
346
338
|
for (const referencePath of binding.constantViolations)
|
347
339
|
if ("AssignmentExpression" == referencePath.node.type)
|
@@ -350,12 +342,13 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
350
342
|
clearObject(node)
|
351
343
|
Object.assign(
|
352
344
|
node,
|
353
|
-
t.memberExpression(t.identifier(
|
345
|
+
t.memberExpression(t.identifier(`_${uniqueId}_G_`), t.identifier(name))
|
354
346
|
)
|
347
|
+
needG = !0
|
355
348
|
}
|
356
349
|
globalBlockPath.remove()
|
357
350
|
globalBlockStatementPath.remove()
|
358
|
-
declarator.init
|
351
|
+
if (declarator.init) {
|
359
352
|
globalBlock.body.splice(
|
360
353
|
globalBlockIndex,
|
361
354
|
0,
|
@@ -363,13 +356,15 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
363
356
|
t.assignmentExpression(
|
364
357
|
"=",
|
365
358
|
t.memberExpression(
|
366
|
-
t.identifier(
|
359
|
+
t.identifier(`_${uniqueId}_G_`),
|
367
360
|
t.identifier(declarator.id.name)
|
368
361
|
),
|
369
362
|
declarator.init
|
370
363
|
)
|
371
364
|
)
|
372
365
|
)
|
366
|
+
needG = !0
|
367
|
+
}
|
373
368
|
} else {
|
374
369
|
globalBlockPath.remove()
|
375
370
|
globalBlockStatementPath.remove()
|
@@ -379,22 +374,20 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
379
374
|
} else globalBlockVariables.add(declarator.id.name)
|
380
375
|
} else if ("ClassDeclaration" == globalBlockStatement.type) {
|
381
376
|
program.scope.crawl()
|
382
|
-
assert(globalBlockStatement.id, "src/processScript/transform.ts:
|
377
|
+
assert(globalBlockStatement.id, "src/processScript/transform.ts:485:37")
|
383
378
|
if (program.scope.hasGlobal(globalBlockStatement.id.name)) {
|
384
379
|
globalBlock.body.splice(globalBlockIndex, 1)
|
385
380
|
const [globalBlockPath] = program.unshiftContainer("body", globalBlock),
|
386
381
|
[globalBlockStatementPath] = program.unshiftContainer("body", globalBlockStatement)
|
387
382
|
program.scope.crawl()
|
388
383
|
const binding = program.scope.getBinding(globalBlockStatement.id.name)
|
389
|
-
assert(binding, "src/processScript/transform.ts:
|
384
|
+
assert(binding, "src/processScript/transform.ts:497:22")
|
390
385
|
for (const referencePath of binding.referencePaths) {
|
391
|
-
assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:
|
386
|
+
assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:500:55")
|
392
387
|
referencePath.replaceWith(
|
393
|
-
t.memberExpression(
|
394
|
-
t.identifier(`$${uniqueId}$GLOBAL$`),
|
395
|
-
t.identifier(referencePath.node.name)
|
396
|
-
)
|
388
|
+
t.memberExpression(t.identifier(`_${uniqueId}_G_`), t.identifier(referencePath.node.name))
|
397
389
|
)
|
390
|
+
needG = !0
|
398
391
|
}
|
399
392
|
globalBlockPath.remove()
|
400
393
|
globalBlockStatementPath.remove()
|
@@ -405,7 +398,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
405
398
|
t.assignmentExpression(
|
406
399
|
"=",
|
407
400
|
t.memberExpression(
|
408
|
-
t.identifier(
|
401
|
+
t.identifier(`_${uniqueId}_G_`),
|
409
402
|
t.identifier(globalBlockStatement.id.name)
|
410
403
|
),
|
411
404
|
t.classExpression(
|
@@ -417,13 +410,9 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
417
410
|
)
|
418
411
|
)
|
419
412
|
)
|
413
|
+
needG = !0
|
420
414
|
}
|
421
415
|
}
|
422
|
-
if (program.scope.hasGlobal("_EXPORTS"))
|
423
|
-
for (const referencePath of getReferencePathsToGlobal("_EXPORTS", program))
|
424
|
-
referencePath.replaceWith(
|
425
|
-
t.arrayExpression([...exports.keys(), ...liveExports.keys()].map(name => t.stringLiteral(name)))
|
426
|
-
)
|
427
416
|
globalBlock.body.length &&
|
428
417
|
mainFunction.body.body.splice(
|
429
418
|
hoistedGlobalBlockFunctions,
|
@@ -472,6 +461,31 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
472
461
|
)
|
473
462
|
])
|
474
463
|
)
|
464
|
+
needHasOwn &&
|
465
|
+
mainFunction.body.body.unshift(
|
466
|
+
t.variableDeclaration("let", [
|
467
|
+
t.variableDeclarator(
|
468
|
+
t.identifier(`_${uniqueId}_HAS_OWN_`),
|
469
|
+
t.callExpression(
|
470
|
+
t.memberExpression(
|
471
|
+
t.memberExpression(
|
472
|
+
t.identifier(
|
473
|
+
globalFunctionsUnder7Characters.find(name => !program.scope.hasOwnBinding(name))
|
474
|
+
),
|
475
|
+
t.identifier("call")
|
476
|
+
),
|
477
|
+
t.identifier("bind")
|
478
|
+
),
|
479
|
+
[
|
480
|
+
t.memberExpression(
|
481
|
+
t.memberExpression(t.identifier("Object"), t.identifier("prototype")),
|
482
|
+
t.identifier("hasOwnProperty")
|
483
|
+
)
|
484
|
+
]
|
485
|
+
)
|
486
|
+
)
|
487
|
+
])
|
488
|
+
)
|
475
489
|
consoleMethodsReferenced.size &&
|
476
490
|
mainFunction.body.body.unshift(
|
477
491
|
t.variableDeclaration(
|
@@ -522,12 +536,12 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
522
536
|
mainFunction.body.body.unshift(
|
523
537
|
t.variableDeclaration(
|
524
538
|
"let",
|
525
|
-
[...neededSubscriptLets].map(name =>
|
539
|
+
[...neededSubscriptLets].map(([name, seclevel]) =>
|
526
540
|
t.variableDeclarator(
|
527
541
|
t.identifier(`_${uniqueId}_SUBSCRIPT_${name}_`),
|
528
542
|
t.arrowFunctionExpression(
|
529
543
|
[t.restElement(t.identifier("args"))],
|
530
|
-
t.callExpression(t.identifier(`$${uniqueId}$SUBSCRIPT$${name}$`), [
|
544
|
+
t.callExpression(t.identifier(`$${uniqueId}$${seclevel}$SUBSCRIPT$${name}$`), [
|
531
545
|
t.spreadElement(t.identifier("args"))
|
532
546
|
])
|
533
547
|
)
|
@@ -535,6 +549,12 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
535
549
|
)
|
536
550
|
)
|
537
551
|
)
|
552
|
+
needG &&
|
553
|
+
mainFunction.body.body.unshift(
|
554
|
+
t.variableDeclaration("let", [
|
555
|
+
t.variableDeclarator(t.identifier(`_${uniqueId}_G_`), t.identifier(`$${uniqueId}$GLOBAL$`))
|
556
|
+
])
|
557
|
+
)
|
538
558
|
traverse(file, {
|
539
559
|
BlockStatement({ node: blockStatement }) {
|
540
560
|
for (const [index, functionDeclaration] of blockStatement.body.entries())
|
@@ -555,7 +575,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
555
575
|
}
|
556
576
|
},
|
557
577
|
ClassBody({ node: classBody, scope, parent }) {
|
558
|
-
assert(t.isClass(parent), "src/processScript/transform.ts:
|
578
|
+
assert(t.isClass(parent), "src/processScript/transform.ts:695:30")
|
559
579
|
let thisIsReferenced = !1
|
560
580
|
for (const classMethod of classBody.body) {
|
561
581
|
if ("ClassMethod" != classMethod.type) continue
|
@@ -645,52 +665,45 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
645
665
|
)
|
646
666
|
}
|
647
667
|
})
|
648
|
-
return { file, seclevel }
|
668
|
+
return { file, seclevel, warnings }
|
649
669
|
function createGetFunctionPrototypeNode() {
|
650
|
-
|
651
|
-
if (!program.scope.hasOwnBinding(globalFunction))
|
652
|
-
return t.memberExpression(
|
653
|
-
t.memberExpression(t.identifier(globalFunction), t.identifier("constructor")),
|
654
|
-
t.identifier("prototype")
|
655
|
-
)
|
670
|
+
const name = globalFunctionsUnder7Characters.find(name => !program.scope.hasOwnBinding(name))
|
656
671
|
return t.memberExpression(
|
657
|
-
t.
|
658
|
-
|
659
|
-
t.identifier("constructor")
|
660
|
-
),
|
661
|
-
t.identifier("prototype")
|
672
|
+
name ? t.identifier(name) : t.arrowFunctionExpression([t.identifier("_")], t.identifier("_")),
|
673
|
+
t.identifier("__proto__")
|
662
674
|
)
|
663
675
|
}
|
664
|
-
function processFakeSubscriptObject(fakeSubscriptObjectName) {
|
676
|
+
function processFakeSubscriptObject(fakeSubscriptObjectName, seclevel) {
|
665
677
|
for (const referencePath of getReferencePathsToGlobal(fakeSubscriptObjectName, program)) {
|
666
|
-
assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:
|
678
|
+
assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:801:60")
|
667
679
|
assert("Identifier" == referencePath.parent.property.type)
|
668
680
|
assert(
|
669
681
|
"MemberExpression" == referencePath.parentPath.parentPath?.node.type,
|
670
|
-
"src/processScript/transform.ts:
|
682
|
+
"src/processScript/transform.ts:803:81"
|
671
683
|
)
|
672
684
|
assert(
|
673
685
|
"Identifier" == referencePath.parentPath.parentPath.node.property.type,
|
674
|
-
"src/processScript/transform.ts:
|
686
|
+
"src/processScript/transform.ts:804:83"
|
675
687
|
)
|
676
688
|
assert(
|
677
689
|
/^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parent.property.name),
|
678
|
-
`src/processScript/transform.ts:
|
690
|
+
`src/processScript/transform.ts:808:8 invalid user "${referencePath.parent.property.name}" in subscript`
|
679
691
|
)
|
680
692
|
assert(
|
681
693
|
/^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parentPath.parentPath.node.property.name),
|
682
|
-
`src/processScript/transform.ts:
|
694
|
+
`src/processScript/transform.ts:813:8 invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
|
683
695
|
)
|
684
696
|
if ("CallExpression" == referencePath.parentPath.parentPath.parentPath?.type)
|
685
697
|
referencePath.parentPath.parentPath.replaceWith(
|
686
698
|
t.identifier(
|
687
|
-
`$${uniqueId}$SUBSCRIPT$${referencePath.parent.property.name}$${referencePath.parentPath.parentPath.node.property.name}$`
|
699
|
+
`$${uniqueId}$${seclevel}$SUBSCRIPT$${referencePath.parent.property.name}$${referencePath.parentPath.parentPath.node.property.name}$`
|
688
700
|
)
|
689
701
|
)
|
690
702
|
else {
|
691
703
|
const name = `${referencePath.parent.property.name}$${referencePath.parentPath.parentPath.node.property.name}`
|
692
704
|
referencePath.parentPath.parentPath.replaceWith(t.identifier(`_${uniqueId}_SUBSCRIPT_${name}_`))
|
693
|
-
neededSubscriptLets.
|
705
|
+
const maxSecLevel = Math.max(neededSubscriptLets.get(name) || 0, seclevel)
|
706
|
+
neededSubscriptLets.set(name, maxSecLevel)
|
694
707
|
}
|
695
708
|
}
|
696
709
|
}
|
package/push.d.ts
CHANGED
@@ -18,6 +18,14 @@ export type PushOptions = LaxPartial<{
|
|
18
18
|
*/
|
19
19
|
forceQuineCheats: boolean;
|
20
20
|
}>;
|
21
|
+
export declare class MissingSourceFolderError extends Error {
|
22
|
+
}
|
23
|
+
export declare class MissingHackmudFolderError extends Error {
|
24
|
+
}
|
25
|
+
export declare class NoUsersError extends Error {
|
26
|
+
}
|
27
|
+
export declare class NoScriptsError extends Error {
|
28
|
+
}
|
21
29
|
/** Push scripts from a source directory to the hackmud directory.
|
22
30
|
*
|
23
31
|
* Pushes files directly in the source folder to all users
|
@@ -25,4 +33,4 @@ export type PushOptions = LaxPartial<{
|
|
25
33
|
* @param hackmudPath directory created by hackmud containing user data including scripts
|
26
34
|
* @param options {@link PushOptions details}
|
27
35
|
* @returns array of info on pushed scripts */
|
28
|
-
export declare function push(sourcePath: string, hackmudPath: string, { scripts, onPush, minify, mangleNames, forceQuineCheats }?: PushOptions): Promise<Info[]>;
|
36
|
+
export declare function push(sourcePath: string, hackmudPath: string, { scripts, onPush, minify, mangleNames, forceQuineCheats }?: PushOptions): Promise<MissingSourceFolderError | MissingHackmudFolderError | NoUsersError | NoScriptsError | Info[]>;
|
package/push.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { AutoMap } from "@samual/lib/AutoMap"
|
2
2
|
import { ensure, assert } from "@samual/lib/assert"
|
3
3
|
import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
|
4
4
|
import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
|
@@ -42,32 +42,54 @@ import "./processScript/preprocess.js"
|
|
42
42
|
import "import-meta-resolve"
|
43
43
|
import "./processScript/transform.js"
|
44
44
|
import "@samual/lib/clearObject"
|
45
|
+
class MissingSourceFolderError extends Error {}
|
46
|
+
Object.defineProperty(MissingSourceFolderError.prototype, "name", { value: "MissingSourceFolderError" })
|
47
|
+
class MissingHackmudFolderError extends Error {}
|
48
|
+
Object.defineProperty(MissingHackmudFolderError.prototype, "name", { value: "MissingHackmudFolderError" })
|
49
|
+
class NoUsersError extends Error {}
|
50
|
+
Object.defineProperty(NoUsersError.prototype, "name", { value: "NoUsersError" })
|
51
|
+
class NoScriptsError extends Error {}
|
52
|
+
Object.defineProperty(NoScriptsError.prototype, "name", { value: "NoScriptsError" })
|
45
53
|
async function push(
|
46
54
|
sourcePath,
|
47
55
|
hackmudPath,
|
48
56
|
{ scripts = ["*.*"], onPush = () => {}, minify = !0, mangleNames = !1, forceQuineCheats } = {}
|
49
57
|
) {
|
50
58
|
const [sourceFolder, hackmudFolder] = await Promise.all([
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
59
|
+
readDirectoryWithStats(sourcePath).catch(error => {
|
60
|
+
if (error && "ENOENT" == error.code)
|
61
|
+
return new MissingSourceFolderError("There is no folder at " + sourcePath)
|
62
|
+
throw error
|
63
|
+
}),
|
64
|
+
readDirectoryWithStats(hackmudPath).catch(error => {
|
65
|
+
if (error && "ENOENT" == error.code)
|
66
|
+
return new MissingHackmudFolderError("There is no folder at " + hackmudPath)
|
67
|
+
throw error
|
68
|
+
})
|
69
|
+
])
|
70
|
+
if (sourceFolder instanceof Error) return sourceFolder
|
71
|
+
if (hackmudFolder instanceof Error) return hackmudFolder
|
72
|
+
const sourceFolderFolders = sourceFolder.filter(({ stats }) => stats.isDirectory()),
|
55
73
|
allUsers = new Set([
|
56
74
|
...scripts
|
57
|
-
.map(scriptName => ensure(scriptName.split(".")[0], "src/push.ts:
|
75
|
+
.map(scriptName => ensure(scriptName.split(".")[0], "src/push.ts:82:65"))
|
58
76
|
.filter(name => "*" != name),
|
59
77
|
...sourceFolderFolders.map(({ name }) => name),
|
60
78
|
...hackmudFolder.filter(({ stats }) => stats.isDirectory()).map(({ name }) => name),
|
61
79
|
...hackmudFolder
|
62
80
|
.filter(({ stats, name }) => stats.isFile() && name.endsWith(".key"))
|
63
81
|
.map(({ name }) => name.slice(0, -4))
|
64
|
-
])
|
65
|
-
|
66
|
-
|
82
|
+
])
|
83
|
+
if (!allUsers.size)
|
84
|
+
return new NoUsersError(
|
85
|
+
"Could not find any users. Either provide the names of your users or log into a user in hackmud"
|
86
|
+
)
|
87
|
+
const usersToScriptsToPush = new AutoMap(_user => new Map()),
|
88
|
+
scriptNamesToUsers = new AutoMap(_scriptName => new Set())
|
67
89
|
for (const script of scripts) {
|
68
90
|
const [user, scriptName] = script.split(".")
|
69
|
-
assert(user, "src/push.ts:
|
70
|
-
assert(scriptName, "src/push.ts:
|
91
|
+
assert(user, "src/push.ts:105:16")
|
92
|
+
assert(scriptName, "src/push.ts:106:22")
|
71
93
|
"*" == user ? scriptNamesToUsers.set(scriptName, allUsers) : scriptNamesToUsers.get(scriptName).add(user)
|
72
94
|
}
|
73
95
|
const sourceFolderFiles = sourceFolder.filter(({ stats }) => stats.isFile()),
|
@@ -98,8 +120,8 @@ async function push(
|
|
98
120
|
for (const [scriptName, users] of scriptNamesToUsers)
|
99
121
|
for (const user of users)
|
100
122
|
if (!usersToScriptsToPush.get(user).has(scriptName))
|
101
|
-
|
102
|
-
const pathsToUsers = new
|
123
|
+
return new NoScriptsError(`Could not find script ${user}.${scriptName} to push`)
|
124
|
+
const pathsToUsers = new AutoMap(_path => new Set())
|
103
125
|
for (const [user, scriptsToPush] of usersToScriptsToPush)
|
104
126
|
for (const path of scriptsToPush.values()) pathsToUsers.get(path).add(user)
|
105
127
|
const allInfo = []
|
@@ -109,7 +131,7 @@ async function push(
|
|
109
131
|
uniqueId = Math.floor(Math.random() * 2 ** 52)
|
110
132
|
.toString(36)
|
111
133
|
.padStart(11, "0"),
|
112
|
-
{ script: minifiedCode } = await processScript(await readFile(path, { encoding: "utf8" }), {
|
134
|
+
{ script: minifiedCode, warnings } = await processScript(await readFile(path, { encoding: "utf8" }), {
|
113
135
|
minify,
|
114
136
|
scriptUser: !0,
|
115
137
|
scriptName,
|
@@ -118,7 +140,7 @@ async function push(
|
|
118
140
|
mangleNames,
|
119
141
|
forceQuineCheats
|
120
142
|
}),
|
121
|
-
info = { path, users, characterCount: countHackmudCharacters(minifiedCode), error: void 0 }
|
143
|
+
info = { path, users, characterCount: countHackmudCharacters(minifiedCode), error: void 0, warnings }
|
122
144
|
await Promise.all(
|
123
145
|
users.map(user =>
|
124
146
|
writeFilePersistent(
|
@@ -135,4 +157,4 @@ async function push(
|
|
135
157
|
)
|
136
158
|
return allInfo
|
137
159
|
}
|
138
|
-
export { push }
|
160
|
+
export { MissingHackmudFolderError, MissingSourceFolderError, NoScriptsError, NoUsersError, push }
|