hackmud-script-manager 0.20.4-8b61cf2 → 0.20.4-8b994a4
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 +302 -271
- package/env.d.ts +325 -317
- package/generateTypeDeclaration.js +2 -1
- package/index.d.ts +3 -0
- package/index.js +3 -1
- package/package.json +39 -38
- package/processScript/index.d.ts +2 -2
- package/processScript/index.js +13 -10
- package/processScript/minify.js +5 -14
- package/processScript/preprocess.js +7 -5
- package/processScript/transform.d.ts +3 -0
- package/processScript/transform.js +103 -86
- package/push.d.ts +2 -1
- package/push.js +13 -11
- package/watch.d.ts +2 -1
- package/watch.js +32 -29
@@ -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_`))
|
@@ -103,6 +110,11 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
103
110
|
}
|
104
111
|
const neededSubscriptLets = new Map()
|
105
112
|
let detectedSeclevel = 4
|
113
|
+
program.scope.hasGlobal("$s") &&
|
114
|
+
warnings.push({
|
115
|
+
message:
|
116
|
+
"Subscripts in the form of $s.foo.bar() and #s.foo.bar() are deprecated. Use explicit seclevels instead."
|
117
|
+
})
|
106
118
|
for (const fakeSubscriptObjectName of ["$fs", "$4s", "$s"])
|
107
119
|
program.scope.hasGlobal(fakeSubscriptObjectName) && processFakeSubscriptObject(fakeSubscriptObjectName, 4)
|
108
120
|
for (const fakeSubscriptObjectName of ["$hs", "$3s"])
|
@@ -129,12 +141,12 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
129
141
|
const neededDbMethodLets = new Set()
|
130
142
|
if (program.scope.hasGlobal("$db"))
|
131
143
|
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:
|
144
|
+
assert("MemberExpression" == referencePath.parentPath.node.type, "src/processScript/transform.ts:199:69")
|
145
|
+
assert("Identifier" == referencePath.parentPath.node.property.type, "src/processScript/transform.ts:200:72")
|
134
146
|
const databaseOpMethodName = referencePath.parentPath.node.property.name
|
135
147
|
assert(
|
136
148
|
validDBMethods.includes(databaseOpMethodName),
|
137
|
-
`src/processScript/transform.ts:
|
149
|
+
`src/processScript/transform.ts:206:8 invalid db method "${databaseOpMethodName}", valid db methods are "${validDBMethods.join('", "')}"`
|
138
150
|
)
|
139
151
|
if ("CallExpression" == referencePath.parentPath.parentPath?.type)
|
140
152
|
referencePath.parentPath.replaceWith(t.identifier(`$${uniqueId}$DB$${databaseOpMethodName}$`))
|
@@ -157,27 +169,32 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
157
169
|
if (program.scope.hasGlobal("$FMCL"))
|
158
170
|
for (const referencePath of getReferencePathsToGlobal("$FMCL", program))
|
159
171
|
referencePath.replaceWith(t.identifier(`$${uniqueId}$FMCL$`))
|
160
|
-
|
172
|
+
let needG = program.scope.hasGlobal("$G")
|
173
|
+
if (needG)
|
161
174
|
for (const referencePath of getReferencePathsToGlobal("$G", program))
|
162
|
-
referencePath.replaceWith(t.identifier(
|
175
|
+
referencePath.replaceWith(t.identifier(`_${uniqueId}_G_`))
|
163
176
|
if (program.scope.hasGlobal("_SECLEVEL"))
|
164
177
|
for (const referencePath of getReferencePathsToGlobal("_SECLEVEL", program))
|
165
178
|
referencePath.replaceWith(t.numericLiteral(seclevel))
|
166
|
-
let needGetPrototypeOf = !1
|
179
|
+
let needGetPrototypeOf = !1,
|
180
|
+
needHasOwn = !1
|
167
181
|
if (program.scope.hasGlobal("Object"))
|
168
182
|
for (const referencePath of getReferencePathsToGlobal("Object", program))
|
169
183
|
if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
|
170
|
-
assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:
|
184
|
+
assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:256:64")
|
171
185
|
if ("getPrototypeOf" == referencePath.parent.property.name) {
|
172
186
|
referencePath.parentPath.replaceWith(t.identifier(`_${uniqueId}_GET_PROTOTYPE_OF_`))
|
173
187
|
needGetPrototypeOf = !0
|
188
|
+
} else if ("hasOwn" == referencePath.parent.property.name) {
|
189
|
+
referencePath.parentPath.replaceWith(t.identifier(`_${uniqueId}_HAS_OWN_`))
|
190
|
+
needHasOwn = !0
|
174
191
|
}
|
175
192
|
}
|
176
193
|
const consoleMethodsReferenced = new Set()
|
177
194
|
if (program.scope.hasGlobal("console"))
|
178
195
|
for (const referencePath of getReferencePathsToGlobal("console", program))
|
179
196
|
if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
|
180
|
-
assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:
|
197
|
+
assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:274:64")
|
181
198
|
referencePath.parentPath.replaceWith(
|
182
199
|
t.identifier(`_${uniqueId}_CONSOLE_METHOD_${referencePath.parent.property.name}_`)
|
183
200
|
)
|
@@ -185,19 +202,20 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
185
202
|
}
|
186
203
|
const lastStatement = program.node.body.at(-1)
|
187
204
|
let exportDefaultName
|
188
|
-
assert(lastStatement, "src/processScript/transform.ts:
|
205
|
+
assert(lastStatement, "src/processScript/transform.ts:288:27 program is empty")
|
189
206
|
if ("ExportNamedDeclaration" == lastStatement.type) {
|
190
207
|
program.node.body.pop()
|
191
208
|
for (const specifier of lastStatement.specifiers) {
|
192
209
|
assert(
|
193
210
|
"ExportSpecifier" == specifier.type,
|
194
|
-
`src/processScript/transform.ts:
|
211
|
+
`src/processScript/transform.ts:294:51 ${specifier.type} is currently unsupported`
|
212
|
+
)
|
213
|
+
if (
|
214
|
+
"default" !=
|
215
|
+
("Identifier" == specifier.exported.type ? specifier.exported.name : specifier.exported.value)
|
195
216
|
)
|
196
|
-
|
197
|
-
|
198
|
-
"default" == exportedName ?
|
199
|
-
(exportDefaultName = specifier.local.name)
|
200
|
-
: exports.set(specifier.local.name, exportedName)
|
217
|
+
throw Error("Only default exports are supported")
|
218
|
+
exportDefaultName = specifier.local.name
|
201
219
|
}
|
202
220
|
}
|
203
221
|
const globalBlock = t.blockStatement([])
|
@@ -223,10 +241,6 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
223
241
|
t.returnStatement(t.callExpression(t.identifier(exportDefaultName), []))
|
224
242
|
])
|
225
243
|
))
|
226
|
-
if ("const" != statement.kind && exports.has(identifierName)) {
|
227
|
-
liveExports.set(identifierName, exports.get(identifierName))
|
228
|
-
exports.delete(identifierName)
|
229
|
-
}
|
230
244
|
globalBlock.body.push(
|
231
245
|
t.variableDeclaration("let", [t.variableDeclarator(t.identifier(identifierName))])
|
232
246
|
)
|
@@ -291,34 +305,16 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
291
305
|
}
|
292
306
|
program.node.body = [mainFunction]
|
293
307
|
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
308
|
program.scope.crawl()
|
313
309
|
const globalBlockVariables = new Set()
|
314
310
|
let hoistedGlobalBlockFunctions = 0
|
315
311
|
for (const [globalBlockIndex, globalBlockStatement] of [...globalBlock.body.entries()].reverse())
|
316
312
|
if ("VariableDeclaration" == globalBlockStatement.type) {
|
317
|
-
assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:
|
313
|
+
assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:408:59")
|
318
314
|
const declarator = globalBlockStatement.declarations[0]
|
319
315
|
assert(
|
320
316
|
"Identifier" == declarator.id.type,
|
321
|
-
`src/processScript/transform.ts:
|
317
|
+
`src/processScript/transform.ts:412:51 declarator.id.type was "${declarator.id.type}"`
|
322
318
|
)
|
323
319
|
program.scope.crawl()
|
324
320
|
if (program.scope.hasGlobal(declarator.id.name)) {
|
@@ -333,15 +329,16 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
333
329
|
Object.keys(program.scope.globals).some(global => globalBlockVariables.has(global))
|
334
330
|
) {
|
335
331
|
const binding = program.scope.getBinding(declarator.id.name)
|
336
|
-
assert(binding, "src/processScript/transform.ts:
|
332
|
+
assert(binding, "src/processScript/transform.ts:431:23")
|
337
333
|
for (const referencePath of binding.referencePaths) {
|
338
|
-
assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:
|
334
|
+
assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:434:56")
|
339
335
|
referencePath.replaceWith(
|
340
336
|
t.memberExpression(
|
341
|
-
t.identifier(
|
337
|
+
t.identifier(`_${uniqueId}_G_`),
|
342
338
|
t.identifier(referencePath.node.name)
|
343
339
|
)
|
344
340
|
)
|
341
|
+
needG = !0
|
345
342
|
}
|
346
343
|
for (const referencePath of binding.constantViolations)
|
347
344
|
if ("AssignmentExpression" == referencePath.node.type)
|
@@ -350,12 +347,13 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
350
347
|
clearObject(node)
|
351
348
|
Object.assign(
|
352
349
|
node,
|
353
|
-
t.memberExpression(t.identifier(
|
350
|
+
t.memberExpression(t.identifier(`_${uniqueId}_G_`), t.identifier(name))
|
354
351
|
)
|
352
|
+
needG = !0
|
355
353
|
}
|
356
354
|
globalBlockPath.remove()
|
357
355
|
globalBlockStatementPath.remove()
|
358
|
-
declarator.init
|
356
|
+
if (declarator.init) {
|
359
357
|
globalBlock.body.splice(
|
360
358
|
globalBlockIndex,
|
361
359
|
0,
|
@@ -363,13 +361,15 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
363
361
|
t.assignmentExpression(
|
364
362
|
"=",
|
365
363
|
t.memberExpression(
|
366
|
-
t.identifier(
|
364
|
+
t.identifier(`_${uniqueId}_G_`),
|
367
365
|
t.identifier(declarator.id.name)
|
368
366
|
),
|
369
367
|
declarator.init
|
370
368
|
)
|
371
369
|
)
|
372
370
|
)
|
371
|
+
needG = !0
|
372
|
+
}
|
373
373
|
} else {
|
374
374
|
globalBlockPath.remove()
|
375
375
|
globalBlockStatementPath.remove()
|
@@ -379,22 +379,20 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
379
379
|
} else globalBlockVariables.add(declarator.id.name)
|
380
380
|
} else if ("ClassDeclaration" == globalBlockStatement.type) {
|
381
381
|
program.scope.crawl()
|
382
|
-
assert(globalBlockStatement.id, "src/processScript/transform.ts:
|
382
|
+
assert(globalBlockStatement.id, "src/processScript/transform.ts:491:37")
|
383
383
|
if (program.scope.hasGlobal(globalBlockStatement.id.name)) {
|
384
384
|
globalBlock.body.splice(globalBlockIndex, 1)
|
385
385
|
const [globalBlockPath] = program.unshiftContainer("body", globalBlock),
|
386
386
|
[globalBlockStatementPath] = program.unshiftContainer("body", globalBlockStatement)
|
387
387
|
program.scope.crawl()
|
388
388
|
const binding = program.scope.getBinding(globalBlockStatement.id.name)
|
389
|
-
assert(binding, "src/processScript/transform.ts:
|
389
|
+
assert(binding, "src/processScript/transform.ts:503:22")
|
390
390
|
for (const referencePath of binding.referencePaths) {
|
391
|
-
assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:
|
391
|
+
assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:506:55")
|
392
392
|
referencePath.replaceWith(
|
393
|
-
t.memberExpression(
|
394
|
-
t.identifier(`$${uniqueId}$GLOBAL$`),
|
395
|
-
t.identifier(referencePath.node.name)
|
396
|
-
)
|
393
|
+
t.memberExpression(t.identifier(`_${uniqueId}_G_`), t.identifier(referencePath.node.name))
|
397
394
|
)
|
395
|
+
needG = !0
|
398
396
|
}
|
399
397
|
globalBlockPath.remove()
|
400
398
|
globalBlockStatementPath.remove()
|
@@ -405,7 +403,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
405
403
|
t.assignmentExpression(
|
406
404
|
"=",
|
407
405
|
t.memberExpression(
|
408
|
-
t.identifier(
|
406
|
+
t.identifier(`_${uniqueId}_G_`),
|
409
407
|
t.identifier(globalBlockStatement.id.name)
|
410
408
|
),
|
411
409
|
t.classExpression(
|
@@ -417,13 +415,9 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
417
415
|
)
|
418
416
|
)
|
419
417
|
)
|
418
|
+
needG = !0
|
420
419
|
}
|
421
420
|
}
|
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
421
|
globalBlock.body.length &&
|
428
422
|
mainFunction.body.body.splice(
|
429
423
|
hoistedGlobalBlockFunctions,
|
@@ -472,6 +466,31 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
472
466
|
)
|
473
467
|
])
|
474
468
|
)
|
469
|
+
needHasOwn &&
|
470
|
+
mainFunction.body.body.unshift(
|
471
|
+
t.variableDeclaration("let", [
|
472
|
+
t.variableDeclarator(
|
473
|
+
t.identifier(`_${uniqueId}_HAS_OWN_`),
|
474
|
+
t.callExpression(
|
475
|
+
t.memberExpression(
|
476
|
+
t.memberExpression(
|
477
|
+
t.identifier(
|
478
|
+
globalFunctionsUnder7Characters.find(name => !program.scope.hasOwnBinding(name))
|
479
|
+
),
|
480
|
+
t.identifier("call")
|
481
|
+
),
|
482
|
+
t.identifier("bind")
|
483
|
+
),
|
484
|
+
[
|
485
|
+
t.memberExpression(
|
486
|
+
t.memberExpression(t.identifier("Object"), t.identifier("prototype")),
|
487
|
+
t.identifier("hasOwnProperty")
|
488
|
+
)
|
489
|
+
]
|
490
|
+
)
|
491
|
+
)
|
492
|
+
])
|
493
|
+
)
|
475
494
|
consoleMethodsReferenced.size &&
|
476
495
|
mainFunction.body.body.unshift(
|
477
496
|
t.variableDeclaration(
|
@@ -535,6 +554,12 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
535
554
|
)
|
536
555
|
)
|
537
556
|
)
|
557
|
+
needG &&
|
558
|
+
mainFunction.body.body.unshift(
|
559
|
+
t.variableDeclaration("let", [
|
560
|
+
t.variableDeclarator(t.identifier(`_${uniqueId}_G_`), t.identifier(`$${uniqueId}$GLOBAL$`))
|
561
|
+
])
|
562
|
+
)
|
538
563
|
traverse(file, {
|
539
564
|
BlockStatement({ node: blockStatement }) {
|
540
565
|
for (const [index, functionDeclaration] of blockStatement.body.entries())
|
@@ -555,7 +580,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
555
580
|
}
|
556
581
|
},
|
557
582
|
ClassBody({ node: classBody, scope, parent }) {
|
558
|
-
assert(t.isClass(parent), "src/processScript/transform.ts:
|
583
|
+
assert(t.isClass(parent), "src/processScript/transform.ts:701:30")
|
559
584
|
let thisIsReferenced = !1
|
560
585
|
for (const classMethod of classBody.body) {
|
561
586
|
if ("ClassMethod" != classMethod.type) continue
|
@@ -645,41 +670,33 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
|
|
645
670
|
)
|
646
671
|
}
|
647
672
|
})
|
648
|
-
return { file, seclevel }
|
673
|
+
return { file, seclevel, warnings }
|
649
674
|
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
|
-
)
|
675
|
+
const name = globalFunctionsUnder7Characters.find(name => !program.scope.hasOwnBinding(name))
|
656
676
|
return t.memberExpression(
|
657
|
-
t.
|
658
|
-
|
659
|
-
t.identifier("constructor")
|
660
|
-
),
|
661
|
-
t.identifier("prototype")
|
677
|
+
name ? t.identifier(name) : t.arrowFunctionExpression([t.identifier("_")], t.identifier("_")),
|
678
|
+
t.identifier("__proto__")
|
662
679
|
)
|
663
680
|
}
|
664
681
|
function processFakeSubscriptObject(fakeSubscriptObjectName, seclevel) {
|
665
682
|
for (const referencePath of getReferencePathsToGlobal(fakeSubscriptObjectName, program)) {
|
666
|
-
assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:
|
683
|
+
assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:807:60")
|
667
684
|
assert("Identifier" == referencePath.parent.property.type)
|
668
685
|
assert(
|
669
686
|
"MemberExpression" == referencePath.parentPath.parentPath?.node.type,
|
670
|
-
"src/processScript/transform.ts:
|
687
|
+
"src/processScript/transform.ts:809:81"
|
671
688
|
)
|
672
689
|
assert(
|
673
690
|
"Identifier" == referencePath.parentPath.parentPath.node.property.type,
|
674
|
-
"src/processScript/transform.ts:
|
691
|
+
"src/processScript/transform.ts:810:83"
|
675
692
|
)
|
676
693
|
assert(
|
677
694
|
/^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parent.property.name),
|
678
|
-
`src/processScript/transform.ts:
|
695
|
+
`src/processScript/transform.ts:814:8 invalid user "${referencePath.parent.property.name}" in subscript`
|
679
696
|
)
|
680
697
|
assert(
|
681
698
|
/^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parentPath.parentPath.node.property.name),
|
682
|
-
`src/processScript/transform.ts:
|
699
|
+
`src/processScript/transform.ts:819:8 invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
|
683
700
|
)
|
684
701
|
if ("CallExpression" == referencePath.parentPath.parentPath.parentPath?.type)
|
685
702
|
referencePath.parentPath.parentPath.replaceWith(
|
package/push.d.ts
CHANGED
@@ -17,6 +17,7 @@ export type PushOptions = LaxPartial<{
|
|
17
17
|
* when left unset or set to `undefined`, automatically uses or doesn't use quine cheats based on character count
|
18
18
|
*/
|
19
19
|
forceQuineCheats: boolean;
|
20
|
+
rootFolderPath: string;
|
20
21
|
}>;
|
21
22
|
export declare class MissingSourceFolderError extends Error {
|
22
23
|
}
|
@@ -33,4 +34,4 @@ export declare class NoScriptsError extends Error {
|
|
33
34
|
* @param hackmudPath directory created by hackmud containing user data including scripts
|
34
35
|
* @param options {@link PushOptions details}
|
35
36
|
* @returns array of info on pushed scripts */
|
36
|
-
export declare function push(sourcePath: string, hackmudPath: string, { scripts, onPush, minify, mangleNames, forceQuineCheats }?: PushOptions): Promise<MissingSourceFolderError | MissingHackmudFolderError | NoUsersError | NoScriptsError | Info[]>;
|
37
|
+
export declare function push(sourcePath: string, hackmudPath: string, { scripts, onPush, minify, mangleNames, forceQuineCheats, rootFolderPath }?: 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"
|
@@ -25,6 +25,7 @@ import "@babel/plugin-transform-private-property-in-object"
|
|
25
25
|
import "@babel/plugin-transform-unicode-sets-regex"
|
26
26
|
import "@babel/traverse"
|
27
27
|
import "@babel/types"
|
28
|
+
import "@rollup/plugin-alias"
|
28
29
|
import "@rollup/plugin-babel"
|
29
30
|
import "@rollup/plugin-commonjs"
|
30
31
|
import "@rollup/plugin-json"
|
@@ -53,7 +54,7 @@ Object.defineProperty(NoScriptsError.prototype, "name", { value: "NoScriptsError
|
|
53
54
|
async function push(
|
54
55
|
sourcePath,
|
55
56
|
hackmudPath,
|
56
|
-
{ scripts = ["*.*"], onPush = () => {}, minify = !0, mangleNames = !1, forceQuineCheats } = {}
|
57
|
+
{ scripts = ["*.*"], onPush = () => {}, minify = !0, mangleNames = !1, forceQuineCheats, rootFolderPath } = {}
|
57
58
|
) {
|
58
59
|
const [sourceFolder, hackmudFolder] = await Promise.all([
|
59
60
|
readDirectoryWithStats(sourcePath).catch(error => {
|
@@ -72,7 +73,7 @@ async function push(
|
|
72
73
|
const sourceFolderFolders = sourceFolder.filter(({ stats }) => stats.isDirectory()),
|
73
74
|
allUsers = new Set([
|
74
75
|
...scripts
|
75
|
-
.map(scriptName => ensure(scriptName.split(".")[0], "src/push.ts:
|
76
|
+
.map(scriptName => ensure(scriptName.split(".")[0], "src/push.ts:85:65"))
|
76
77
|
.filter(name => "*" != name),
|
77
78
|
...sourceFolderFolders.map(({ name }) => name),
|
78
79
|
...hackmudFolder.filter(({ stats }) => stats.isDirectory()).map(({ name }) => name),
|
@@ -84,12 +85,12 @@ async function push(
|
|
84
85
|
return new NoUsersError(
|
85
86
|
"Could not find any users. Either provide the names of your users or log into a user in hackmud"
|
86
87
|
)
|
87
|
-
const usersToScriptsToPush = new
|
88
|
-
scriptNamesToUsers = new
|
88
|
+
const usersToScriptsToPush = new AutoMap(_user => new Map()),
|
89
|
+
scriptNamesToUsers = new AutoMap(_scriptName => new Set())
|
89
90
|
for (const script of scripts) {
|
90
91
|
const [user, scriptName] = script.split(".")
|
91
|
-
assert(user, "src/push.ts:
|
92
|
-
assert(scriptName, "src/push.ts:
|
92
|
+
assert(user, "src/push.ts:108:16")
|
93
|
+
assert(scriptName, "src/push.ts:109:22")
|
93
94
|
"*" == user ? scriptNamesToUsers.set(scriptName, allUsers) : scriptNamesToUsers.get(scriptName).add(user)
|
94
95
|
}
|
95
96
|
const sourceFolderFiles = sourceFolder.filter(({ stats }) => stats.isFile()),
|
@@ -121,7 +122,7 @@ async function push(
|
|
121
122
|
for (const user of users)
|
122
123
|
if (!usersToScriptsToPush.get(user).has(scriptName))
|
123
124
|
return new NoScriptsError(`Could not find script ${user}.${scriptName} to push`)
|
124
|
-
const pathsToUsers = new
|
125
|
+
const pathsToUsers = new AutoMap(_path => new Set())
|
125
126
|
for (const [user, scriptsToPush] of usersToScriptsToPush)
|
126
127
|
for (const path of scriptsToPush.values()) pathsToUsers.get(path).add(user)
|
127
128
|
const allInfo = []
|
@@ -131,16 +132,17 @@ async function push(
|
|
131
132
|
uniqueId = Math.floor(Math.random() * 2 ** 52)
|
132
133
|
.toString(36)
|
133
134
|
.padStart(11, "0"),
|
134
|
-
{ script: minifiedCode } = await processScript(await readFile(path, { encoding: "utf8" }), {
|
135
|
+
{ script: minifiedCode, warnings } = await processScript(await readFile(path, { encoding: "utf8" }), {
|
135
136
|
minify,
|
136
137
|
scriptUser: !0,
|
137
138
|
scriptName,
|
138
139
|
uniqueId,
|
139
140
|
filePath: path,
|
140
141
|
mangleNames,
|
141
|
-
forceQuineCheats
|
142
|
+
forceQuineCheats,
|
143
|
+
rootFolderPath
|
142
144
|
}),
|
143
|
-
info = { path, users, characterCount: countHackmudCharacters(minifiedCode), error: void 0 }
|
145
|
+
info = { path, users, characterCount: countHackmudCharacters(minifiedCode), error: void 0, warnings }
|
144
146
|
await Promise.all(
|
145
147
|
users.map(user =>
|
146
148
|
writeFilePersistent(
|
package/watch.d.ts
CHANGED
@@ -6,9 +6,10 @@ export type WatchOptions = PushOptions & LaxPartial<{
|
|
6
6
|
* writing the type declarations enables interscript type checking and autocompletetes for the args */
|
7
7
|
typeDeclarationPath: string;
|
8
8
|
onReady: () => void;
|
9
|
+
rootFolderPath: string;
|
9
10
|
}>;
|
10
11
|
/** Watches target file or folder for updates and builds and pushes updated file.
|
11
12
|
* @param sourceDirectory path to folder containing source files
|
12
13
|
* @param hackmudDirectory path to hackmud directory
|
13
14
|
* @param options {@link WatchOptions details} and {@link PushOptions more details} */
|
14
|
-
export declare function watch(sourceDirectory: string, hackmudDirectory: string, { scripts, onPush, minify, mangleNames, typeDeclarationPath: typeDeclarationPath_, onReady, forceQuineCheats }?: WatchOptions): Promise<void>;
|
15
|
+
export declare function watch(sourceDirectory: string, hackmudDirectory: string, { scripts, onPush, minify, mangleNames, typeDeclarationPath: typeDeclarationPath_, onReady, forceQuineCheats, rootFolderPath }?: WatchOptions): Promise<void>;
|