diff --git a/README.md b/README.md index 95a9ad6..907289f 100644 --- a/README.md +++ b/README.md @@ -33,48 +33,28 @@ select extism_call(data, 'count_vowels', 'Hello World!') from plugins where id = If you want more control over your plugin, you can use `extism_create_plugin`: ```sql -CREATE TABLE public.kv ( - id serial4 NOT NULL, - "key" bytea NOT NULL, - value bytea NULL, - CONSTRAINT kv_pkey PRIMARY KEY (id) -); +-- DROP FUNCTION public.count_vowels_kv(varchar); CREATE OR REPLACE FUNCTION public.count_vowels_kv(input character varying) RETURNS character varying LANGUAGE plv8 AS $function$ - function encodeString(str) { - var arr = []; - for (var i = 0, len = str.length; i < len; i++) { - arr.push(str.charCodeAt(i)); - } - return new Uint8Array(arr); - } - function decodeString(arr) { - var str = ""; - for (var i = 0, len = arr.length; i < len; i++) { - str += String.fromCharCode(arr[i]); - } - return str; - } - const createPlugin = plv8.find_function("extism_create_plugin"); - const wasm = plv8.execute("select data from plugins where id = 3")[0]; -- Assume our plugin ID is 3 + const wasm = plv8.execute("select data from plugins where id = 3")[0]; const opts = { useWasi: true, functions: { "extism:host/user": { kv_read(cp, offs) { - const key = cp.readString(offs); + const key = cp.read(offs).text(); let result = plv8.execute("SELECT value FROM kv WHERE key = $1", [key]); let value = result.length > 0 ? result[0].value : new Uint8Array([0, 0, 0, 0]); - return cp.writeBytes(value); + return cp.store(value); }, kv_write(cp, kOffs, vOffs) { - const key = cp.readString(kOffs); - const value = cp.readBytes(vOffs); + const key = cp.read(kOffs).text(); + const value = cp.read(vOffs).bytes(); let result = plv8.execute("SELECT value FROM kv WHERE key = $1", [key]); if (result.length > 0) { plv8.execute("UPDATE kv SET value = $1 WHERE key = $2", [value, key]); @@ -87,9 +67,8 @@ AS $function$ }; const plugin = createPlugin(wasm, opts); - return decodeString(plugin.call("count_vowels", encodeString(input))) + return plugin.call("count_vowels", input).text() $function$ ; - ``` The above example shows how you can use `extism_create_plugin` to supply your own host functions to the plugin. You can find th source code for the plugin [here](https://github.com/extism/plugins/tree/main/count_vowels_kvstore). diff --git a/dist/index.sql b/dist/index.sql index e03febc..e5d46ea 100644 --- a/dist/index.sql +++ b/dist/index.sql @@ -132,6 +132,536 @@ AS $function$ } }); + // (disabled):crypto + var require_crypto = __commonJS({ + "(disabled):crypto"() { + } + }); + + // (disabled):buffer + var require_buffer = __commonJS({ + "(disabled):buffer"() { + } + }); + + // node_modules/js-sha256/src/sha256.js + var require_sha256 = __commonJS({ + "node_modules/js-sha256/src/sha256.js"(exports, module2) { + (function() { + "use strict"; + var ERROR2 = "input is invalid type"; + var WINDOW = typeof window === "object"; + var root = WINDOW ? window : {}; + if (root.JS_SHA256_NO_WINDOW) { + WINDOW = false; + } + var WEB_WORKER = !WINDOW && typeof self === "object"; + var NODE_JS = !root.JS_SHA256_NO_NODE_JS && typeof process === "object" && process.versions && process.versions.node; + if (NODE_JS) { + root = global; + } else if (WEB_WORKER) { + root = self; + } + var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && typeof module2 === "object" && module2.exports; + var AMD = typeof define === "function" && define.amd; + var ARRAY_BUFFER = !root.JS_SHA256_NO_ARRAY_BUFFER && typeof ArrayBuffer !== "undefined"; + var HEX_CHARS = "0123456789abcdef".split(""); + var EXTRA = [-2147483648, 8388608, 32768, 128]; + var SHIFT = [24, 16, 8, 0]; + var K = [ + 1116352408, + 1899447441, + 3049323471, + 3921009573, + 961987163, + 1508970993, + 2453635748, + 2870763221, + 3624381080, + 310598401, + 607225278, + 1426881987, + 1925078388, + 2162078206, + 2614888103, + 3248222580, + 3835390401, + 4022224774, + 264347078, + 604807628, + 770255983, + 1249150122, + 1555081692, + 1996064986, + 2554220882, + 2821834349, + 2952996808, + 3210313671, + 3336571891, + 3584528711, + 113926993, + 338241895, + 666307205, + 773529912, + 1294757372, + 1396182291, + 1695183700, + 1986661051, + 2177026350, + 2456956037, + 2730485921, + 2820302411, + 3259730800, + 3345764771, + 3516065817, + 3600352804, + 4094571909, + 275423344, + 430227734, + 506948616, + 659060556, + 883997877, + 958139571, + 1322822218, + 1537002063, + 1747873779, + 1955562222, + 2024104815, + 2227730452, + 2361852424, + 2428436474, + 2756734187, + 3204031479, + 3329325298 + ]; + var OUTPUT_TYPES = ["hex", "array", "digest", "arrayBuffer"]; + var blocks = []; + if (root.JS_SHA256_NO_NODE_JS || !Array.isArray) { + Array.isArray = function(obj) { + return Object.prototype.toString.call(obj) === "[object Array]"; + }; + } + if (ARRAY_BUFFER && (root.JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) { + ArrayBuffer.isView = function(obj) { + return typeof obj === "object" && obj.buffer && obj.buffer.constructor === ArrayBuffer; + }; + } + var createOutputMethod = function(outputType, is224) { + return function(message) { + return new Sha256(is224, true).update(message)[outputType](); + }; + }; + var createMethod = function(is224) { + var method = createOutputMethod("hex", is224); + if (NODE_JS) { + method = nodeWrap(method, is224); + } + method.create = function() { + return new Sha256(is224); + }; + method.update = function(message) { + return method.create().update(message); + }; + for (var i = 0; i < OUTPUT_TYPES.length; ++i) { + var type = OUTPUT_TYPES[i]; + method[type] = createOutputMethod(type, is224); + } + return method; + }; + var nodeWrap = function(method, is224) { + var crypto = require_crypto(); + var Buffer2 = require_buffer().Buffer; + var algorithm = is224 ? "sha224" : "sha256"; + var bufferFrom; + if (Buffer2.from && !root.JS_SHA256_NO_BUFFER_FROM) { + bufferFrom = Buffer2.from; + } else { + bufferFrom = function(message) { + return new Buffer2(message); + }; + } + var nodeMethod = function(message) { + if (typeof message === "string") { + return crypto.createHash(algorithm).update(message, "utf8").digest("hex"); + } else { + if (message === null || message === void 0) { + throw new Error(ERROR2); + } else if (message.constructor === ArrayBuffer) { + message = new Uint8Array(message); + } + } + if (Array.isArray(message) || ArrayBuffer.isView(message) || message.constructor === Buffer2) { + return crypto.createHash(algorithm).update(bufferFrom(message)).digest("hex"); + } else { + return method(message); + } + }; + return nodeMethod; + }; + var createHmacOutputMethod = function(outputType, is224) { + return function(key, message) { + return new HmacSha256(key, is224, true).update(message)[outputType](); + }; + }; + var createHmacMethod = function(is224) { + var method = createHmacOutputMethod("hex", is224); + method.create = function(key) { + return new HmacSha256(key, is224); + }; + method.update = function(key, message) { + return method.create(key).update(message); + }; + for (var i = 0; i < OUTPUT_TYPES.length; ++i) { + var type = OUTPUT_TYPES[i]; + method[type] = createHmacOutputMethod(type, is224); + } + return method; + }; + function Sha256(is224, sharedMemory) { + if (sharedMemory) { + blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; + this.blocks = blocks; + } else { + this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } + if (is224) { + this.h0 = 3238371032; + this.h1 = 914150663; + this.h2 = 812702999; + this.h3 = 4144912697; + this.h4 = 4290775857; + this.h5 = 1750603025; + this.h6 = 1694076839; + this.h7 = 3204075428; + } else { + this.h0 = 1779033703; + this.h1 = 3144134277; + this.h2 = 1013904242; + this.h3 = 2773480762; + this.h4 = 1359893119; + this.h5 = 2600822924; + this.h6 = 528734635; + this.h7 = 1541459225; + } + this.block = this.start = this.bytes = this.hBytes = 0; + this.finalized = this.hashed = false; + this.first = true; + this.is224 = is224; + } + Sha256.prototype.update = function(message) { + if (this.finalized) { + return; + } + var notString, type = typeof message; + if (type !== "string") { + if (type === "object") { + if (message === null) { + throw new Error(ERROR2); + } else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) { + message = new Uint8Array(message); + } else if (!Array.isArray(message)) { + if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) { + throw new Error(ERROR2); + } + } + } else { + throw new Error(ERROR2); + } + notString = true; + } + var code, index = 0, i, length = message.length, blocks2 = this.blocks; + while (index < length) { + if (this.hashed) { + this.hashed = false; + blocks2[0] = this.block; + this.block = blocks2[16] = blocks2[1] = blocks2[2] = blocks2[3] = blocks2[4] = blocks2[5] = blocks2[6] = blocks2[7] = blocks2[8] = blocks2[9] = blocks2[10] = blocks2[11] = blocks2[12] = blocks2[13] = blocks2[14] = blocks2[15] = 0; + } + if (notString) { + for (i = this.start; index < length && i < 64; ++index) { + blocks2[i >>> 2] |= message[index] << SHIFT[i++ & 3]; + } + } else { + for (i = this.start; index < length && i < 64; ++index) { + code = message.charCodeAt(index); + if (code < 128) { + blocks2[i >>> 2] |= code << SHIFT[i++ & 3]; + } else if (code < 2048) { + blocks2[i >>> 2] |= (192 | code >>> 6) << SHIFT[i++ & 3]; + blocks2[i >>> 2] |= (128 | code & 63) << SHIFT[i++ & 3]; + } else if (code < 55296 || code >= 57344) { + blocks2[i >>> 2] |= (224 | code >>> 12) << SHIFT[i++ & 3]; + blocks2[i >>> 2] |= (128 | code >>> 6 & 63) << SHIFT[i++ & 3]; + blocks2[i >>> 2] |= (128 | code & 63) << SHIFT[i++ & 3]; + } else { + code = 65536 + ((code & 1023) << 10 | message.charCodeAt(++index) & 1023); + blocks2[i >>> 2] |= (240 | code >>> 18) << SHIFT[i++ & 3]; + blocks2[i >>> 2] |= (128 | code >>> 12 & 63) << SHIFT[i++ & 3]; + blocks2[i >>> 2] |= (128 | code >>> 6 & 63) << SHIFT[i++ & 3]; + blocks2[i >>> 2] |= (128 | code & 63) << SHIFT[i++ & 3]; + } + } + } + this.lastByteIndex = i; + this.bytes += i - this.start; + if (i >= 64) { + this.block = blocks2[16]; + this.start = i - 64; + this.hash(); + this.hashed = true; + } else { + this.start = i; + } + } + if (this.bytes > 4294967295) { + this.hBytes += this.bytes / 4294967296 << 0; + this.bytes = this.bytes % 4294967296; + } + return this; + }; + Sha256.prototype.finalize = function() { + if (this.finalized) { + return; + } + this.finalized = true; + var blocks2 = this.blocks, i = this.lastByteIndex; + blocks2[16] = this.block; + blocks2[i >>> 2] |= EXTRA[i & 3]; + this.block = blocks2[16]; + if (i >= 56) { + if (!this.hashed) { + this.hash(); + } + blocks2[0] = this.block; + blocks2[16] = blocks2[1] = blocks2[2] = blocks2[3] = blocks2[4] = blocks2[5] = blocks2[6] = blocks2[7] = blocks2[8] = blocks2[9] = blocks2[10] = blocks2[11] = blocks2[12] = blocks2[13] = blocks2[14] = blocks2[15] = 0; + } + blocks2[14] = this.hBytes << 3 | this.bytes >>> 29; + blocks2[15] = this.bytes << 3; + this.hash(); + }; + Sha256.prototype.hash = function() { + var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6, h = this.h7, blocks2 = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc; + for (j = 16; j < 64; ++j) { + t1 = blocks2[j - 15]; + s0 = (t1 >>> 7 | t1 << 25) ^ (t1 >>> 18 | t1 << 14) ^ t1 >>> 3; + t1 = blocks2[j - 2]; + s1 = (t1 >>> 17 | t1 << 15) ^ (t1 >>> 19 | t1 << 13) ^ t1 >>> 10; + blocks2[j] = blocks2[j - 16] + s0 + blocks2[j - 7] + s1 << 0; + } + bc = b & c; + for (j = 0; j < 64; j += 4) { + if (this.first) { + if (this.is224) { + ab = 300032; + t1 = blocks2[0] - 1413257819; + h = t1 - 150054599 << 0; + d = t1 + 24177077 << 0; + } else { + ab = 704751109; + t1 = blocks2[0] - 210244248; + h = t1 - 1521486534 << 0; + d = t1 + 143694565 << 0; + } + this.first = false; + } else { + s0 = (a >>> 2 | a << 30) ^ (a >>> 13 | a << 19) ^ (a >>> 22 | a << 10); + s1 = (e >>> 6 | e << 26) ^ (e >>> 11 | e << 21) ^ (e >>> 25 | e << 7); + ab = a & b; + maj = ab ^ a & c ^ bc; + ch = e & f ^ ~e & g; + t1 = h + s1 + ch + K[j] + blocks2[j]; + t2 = s0 + maj; + h = d + t1 << 0; + d = t1 + t2 << 0; + } + s0 = (d >>> 2 | d << 30) ^ (d >>> 13 | d << 19) ^ (d >>> 22 | d << 10); + s1 = (h >>> 6 | h << 26) ^ (h >>> 11 | h << 21) ^ (h >>> 25 | h << 7); + da = d & a; + maj = da ^ d & b ^ ab; + ch = h & e ^ ~h & f; + t1 = g + s1 + ch + K[j + 1] + blocks2[j + 1]; + t2 = s0 + maj; + g = c + t1 << 0; + c = t1 + t2 << 0; + s0 = (c >>> 2 | c << 30) ^ (c >>> 13 | c << 19) ^ (c >>> 22 | c << 10); + s1 = (g >>> 6 | g << 26) ^ (g >>> 11 | g << 21) ^ (g >>> 25 | g << 7); + cd = c & d; + maj = cd ^ c & a ^ da; + ch = g & h ^ ~g & e; + t1 = f + s1 + ch + K[j + 2] + blocks2[j + 2]; + t2 = s0 + maj; + f = b + t1 << 0; + b = t1 + t2 << 0; + s0 = (b >>> 2 | b << 30) ^ (b >>> 13 | b << 19) ^ (b >>> 22 | b << 10); + s1 = (f >>> 6 | f << 26) ^ (f >>> 11 | f << 21) ^ (f >>> 25 | f << 7); + bc = b & c; + maj = bc ^ b & d ^ cd; + ch = f & g ^ ~f & h; + t1 = e + s1 + ch + K[j + 3] + blocks2[j + 3]; + t2 = s0 + maj; + e = a + t1 << 0; + a = t1 + t2 << 0; + this.chromeBugWorkAround = true; + } + this.h0 = this.h0 + a << 0; + this.h1 = this.h1 + b << 0; + this.h2 = this.h2 + c << 0; + this.h3 = this.h3 + d << 0; + this.h4 = this.h4 + e << 0; + this.h5 = this.h5 + f << 0; + this.h6 = this.h6 + g << 0; + this.h7 = this.h7 + h << 0; + }; + Sha256.prototype.hex = function() { + this.finalize(); + var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5, h6 = this.h6, h7 = this.h7; + var hex = HEX_CHARS[h0 >>> 28 & 15] + HEX_CHARS[h0 >>> 24 & 15] + HEX_CHARS[h0 >>> 20 & 15] + HEX_CHARS[h0 >>> 16 & 15] + HEX_CHARS[h0 >>> 12 & 15] + HEX_CHARS[h0 >>> 8 & 15] + HEX_CHARS[h0 >>> 4 & 15] + HEX_CHARS[h0 & 15] + HEX_CHARS[h1 >>> 28 & 15] + HEX_CHARS[h1 >>> 24 & 15] + HEX_CHARS[h1 >>> 20 & 15] + HEX_CHARS[h1 >>> 16 & 15] + HEX_CHARS[h1 >>> 12 & 15] + HEX_CHARS[h1 >>> 8 & 15] + HEX_CHARS[h1 >>> 4 & 15] + HEX_CHARS[h1 & 15] + HEX_CHARS[h2 >>> 28 & 15] + HEX_CHARS[h2 >>> 24 & 15] + HEX_CHARS[h2 >>> 20 & 15] + HEX_CHARS[h2 >>> 16 & 15] + HEX_CHARS[h2 >>> 12 & 15] + HEX_CHARS[h2 >>> 8 & 15] + HEX_CHARS[h2 >>> 4 & 15] + HEX_CHARS[h2 & 15] + HEX_CHARS[h3 >>> 28 & 15] + HEX_CHARS[h3 >>> 24 & 15] + HEX_CHARS[h3 >>> 20 & 15] + HEX_CHARS[h3 >>> 16 & 15] + HEX_CHARS[h3 >>> 12 & 15] + HEX_CHARS[h3 >>> 8 & 15] + HEX_CHARS[h3 >>> 4 & 15] + HEX_CHARS[h3 & 15] + HEX_CHARS[h4 >>> 28 & 15] + HEX_CHARS[h4 >>> 24 & 15] + HEX_CHARS[h4 >>> 20 & 15] + HEX_CHARS[h4 >>> 16 & 15] + HEX_CHARS[h4 >>> 12 & 15] + HEX_CHARS[h4 >>> 8 & 15] + HEX_CHARS[h4 >>> 4 & 15] + HEX_CHARS[h4 & 15] + HEX_CHARS[h5 >>> 28 & 15] + HEX_CHARS[h5 >>> 24 & 15] + HEX_CHARS[h5 >>> 20 & 15] + HEX_CHARS[h5 >>> 16 & 15] + HEX_CHARS[h5 >>> 12 & 15] + HEX_CHARS[h5 >>> 8 & 15] + HEX_CHARS[h5 >>> 4 & 15] + HEX_CHARS[h5 & 15] + HEX_CHARS[h6 >>> 28 & 15] + HEX_CHARS[h6 >>> 24 & 15] + HEX_CHARS[h6 >>> 20 & 15] + HEX_CHARS[h6 >>> 16 & 15] + HEX_CHARS[h6 >>> 12 & 15] + HEX_CHARS[h6 >>> 8 & 15] + HEX_CHARS[h6 >>> 4 & 15] + HEX_CHARS[h6 & 15]; + if (!this.is224) { + hex += HEX_CHARS[h7 >>> 28 & 15] + HEX_CHARS[h7 >>> 24 & 15] + HEX_CHARS[h7 >>> 20 & 15] + HEX_CHARS[h7 >>> 16 & 15] + HEX_CHARS[h7 >>> 12 & 15] + HEX_CHARS[h7 >>> 8 & 15] + HEX_CHARS[h7 >>> 4 & 15] + HEX_CHARS[h7 & 15]; + } + return hex; + }; + Sha256.prototype.toString = Sha256.prototype.hex; + Sha256.prototype.digest = function() { + this.finalize(); + var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5, h6 = this.h6, h7 = this.h7; + var arr = [ + h0 >>> 24 & 255, + h0 >>> 16 & 255, + h0 >>> 8 & 255, + h0 & 255, + h1 >>> 24 & 255, + h1 >>> 16 & 255, + h1 >>> 8 & 255, + h1 & 255, + h2 >>> 24 & 255, + h2 >>> 16 & 255, + h2 >>> 8 & 255, + h2 & 255, + h3 >>> 24 & 255, + h3 >>> 16 & 255, + h3 >>> 8 & 255, + h3 & 255, + h4 >>> 24 & 255, + h4 >>> 16 & 255, + h4 >>> 8 & 255, + h4 & 255, + h5 >>> 24 & 255, + h5 >>> 16 & 255, + h5 >>> 8 & 255, + h5 & 255, + h6 >>> 24 & 255, + h6 >>> 16 & 255, + h6 >>> 8 & 255, + h6 & 255 + ]; + if (!this.is224) { + arr.push(h7 >>> 24 & 255, h7 >>> 16 & 255, h7 >>> 8 & 255, h7 & 255); + } + return arr; + }; + Sha256.prototype.array = Sha256.prototype.digest; + Sha256.prototype.arrayBuffer = function() { + this.finalize(); + var buffer = new ArrayBuffer(this.is224 ? 28 : 32); + var dataView = new DataView(buffer); + dataView.setUint32(0, this.h0); + dataView.setUint32(4, this.h1); + dataView.setUint32(8, this.h2); + dataView.setUint32(12, this.h3); + dataView.setUint32(16, this.h4); + dataView.setUint32(20, this.h5); + dataView.setUint32(24, this.h6); + if (!this.is224) { + dataView.setUint32(28, this.h7); + } + return buffer; + }; + function HmacSha256(key, is224, sharedMemory) { + var i, type = typeof key; + if (type === "string") { + var bytes = [], length = key.length, index = 0, code; + for (i = 0; i < length; ++i) { + code = key.charCodeAt(i); + if (code < 128) { + bytes[index++] = code; + } else if (code < 2048) { + bytes[index++] = 192 | code >>> 6; + bytes[index++] = 128 | code & 63; + } else if (code < 55296 || code >= 57344) { + bytes[index++] = 224 | code >>> 12; + bytes[index++] = 128 | code >>> 6 & 63; + bytes[index++] = 128 | code & 63; + } else { + code = 65536 + ((code & 1023) << 10 | key.charCodeAt(++i) & 1023); + bytes[index++] = 240 | code >>> 18; + bytes[index++] = 128 | code >>> 12 & 63; + bytes[index++] = 128 | code >>> 6 & 63; + bytes[index++] = 128 | code & 63; + } + } + key = bytes; + } else { + if (type === "object") { + if (key === null) { + throw new Error(ERROR2); + } else if (ARRAY_BUFFER && key.constructor === ArrayBuffer) { + key = new Uint8Array(key); + } else if (!Array.isArray(key)) { + if (!ARRAY_BUFFER || !ArrayBuffer.isView(key)) { + throw new Error(ERROR2); + } + } + } else { + throw new Error(ERROR2); + } + } + if (key.length > 64) { + key = new Sha256(is224, true).update(key).array(); + } + var oKeyPad = [], iKeyPad = []; + for (i = 0; i < 64; ++i) { + var b = key[i] || 0; + oKeyPad[i] = 92 ^ b; + iKeyPad[i] = 54 ^ b; + } + Sha256.call(this, is224, sharedMemory); + this.update(iKeyPad); + this.oKeyPad = oKeyPad; + this.inner = true; + this.sharedMemory = sharedMemory; + } + HmacSha256.prototype = new Sha256(); + HmacSha256.prototype.finalize = function() { + Sha256.prototype.finalize.call(this); + if (this.inner) { + this.inner = false; + var innerHash = this.array(); + Sha256.call(this, this.is224, this.sharedMemory); + this.update(this.oKeyPad); + this.update(innerHash); + Sha256.prototype.finalize.call(this); + } + }; + var exports2 = createMethod(); + exports2.sha256 = exports2; + exports2.sha224 = createMethod(true); + exports2.sha256.hmac = createHmacMethod(); + exports2.sha224.hmac = createHmacMethod(true); + if (COMMON_JS) { + module2.exports = exports2; + } else { + root.sha256 = exports2.sha256; + root.sha224 = exports2.sha224; + if (AMD) { + define(function() { + return exports2; + }); + } + } + })(); + } + }); + // src/index.ts var src_exports = {}; __export(src_exports, { @@ -148,6 +678,7 @@ AS $function$ }); var import_base64_js = __toESM(require_base64_js()); + var import_js_sha256 = __toESM(require_sha256()); var PluginOutput = class extends DataView { #output; constructor(output) { @@ -225,20 +756,7 @@ AS $function$ loadWasi(options) { const args = []; const envVars = []; - return new PluginWasi({}, {}, (instance) => this.initialize({}, instance)); - } - initialize(wasi, instance) { - const wrapper = { - exports: { - memory: instance.exports.memory, - _start() { - } - } - }; - if (!wrapper.exports.memory) { - throw new Error("The module has to export a default memory."); - } - wasi.start(wrapper); + return new PluginWasi(); } instantiateModule() { if (this.module) { @@ -270,8 +788,8 @@ AS $function$ module: this.moduleData, instance }; - if (this.module.instance.exports._start) { - pluginWasi?.initialize(this.module.instance); + if (pluginWasi) { + pluginWasi.initialize(this.module.instance); } this.guestRuntime = detectGuestRuntime(this.module.instance); return this.module; @@ -384,19 +902,155 @@ AS $function$ } }; var PluginWasi = class { - wasi; imports; - #initialize; - constructor(wasi, imports, init) { - this.wasi = wasi; - this.imports = imports; - this.#initialize = init; + inst = null; + args; + env; + constructor(args = [], env = []) { + this.args = args; + this.env = env; + const self2 = this; + function memory() { + return self2.inst.exports.memory; + } + this.imports = { + fd_write: (fd, iovs, iovs_len, nwritten) => { + if (fd < 0 || fd > 2) { + throw new Error("fd_write not implemented"); + } + const buffer = memory().buffer; + const view = new DataView(buffer); + let written = 0; + let totalLength = 0; + for (let i = 0; i < iovs_len; i++) { + const len = view.getUint32(iovs + i * 8 + 4, true); + totalLength += len; + } + const temp = new Uint8Array(totalLength); + for (let i = 0; i < iovs_len; i++) { + const iov = view.getUint32(iovs + i * 8, true); + const len = view.getUint32(iovs + i * 8 + 4, true); + const bytes = new Uint8Array(buffer, iov, len); + temp.set(bytes, written); + written += len; + } + const output = new TextDecoder().decode(temp); + console.log(output); + view.setUint32(nwritten, written, true); + return 0; + }, + fd_close(fd) { + if (fd < 0 || fd > 2) { + throw new Error("fd_close not implemented"); + } + return 0; + }, + fd_seek(fd, offset, whence, newoffset) { + throw new Error("fd_seek not implemented"); + }, + fd_fdstat_get(fd, buf) { + throw new Error("fd_fdstat_get not implemented"); + }, + fd_read(fd, iovs_ptr, iovs_len, nread_ptr) { + throw new Error("fd_read not implemented"); + }, + fd_fdstat_set_flags(fd, flags) { + throw new Error("fd_fdstat_set_flags not implemented"); + }, + fd_filestat_get(fd, buf) { + throw new Error("fd_filestat_get not implemented"); + }, + fd_filestat_set_size(fd, size) { + throw new Error("fd_filestat_set_size not implemented"); + }, + path_create_directory(fd, path_ptr, path_len) { + throw new Error("path_create_directory not implemented"); + }, + path_filestat_get(fd, flags, path_ptr, path_len, filestat_ptr) { + throw new Error("path_filestat_get not implemented"); + }, + fd_prestat_get(fd, buf_ptr) { + throw new Error("fd_prestat_get not implemented"); + }, + fd_prestat_dir_name(fd, path_ptr, path_len) { + throw new Error("fd_prestat_dir_name not implemented"); + }, + path_open(fd, dirflags, path_ptr, path_len, oflags, fs_rights_base, fs_rights_inheriting, fd_flags, opened_fd_ptr) { + throw new Error("path_open not implemented"); + }, + poll_oneoff(in_ptr, out_ptr, nsubscriptions, nevents) { + throw new Error("poll_oneoff not implemented"); + }, + proc_exit(rval) { + throw new Error(`proc_exit: ${rval}`); + }, + clock_time_get(id, precision, time) { + const buffer = new DataView(memory().buffer); + buffer.setBigUint64( + time, + BigInt(new Date().getTime()) * 1000000n, + true + ); + return 0; + }, + args_sizes_get(argc, argv_buf_size) { + const buffer = new DataView(memory().buffer); + buffer.setUint32(argc, self2.args.length, true); + let buf_size = 0; + for (const arg of self2.args) { + buf_size += arg.length + 1; + } + buffer.setUint32(argv_buf_size, buf_size, true); + return 0; + }, + args_get(argv, argv_buf) { + const buffer = new DataView(memory().buffer); + const buffer8 = new Uint8Array(memory().buffer); + const orig_argv_buf = argv_buf; + for (let i = 0; i < self2.args.length; i++) { + buffer.setUint32(argv, argv_buf, true); + argv += 4; + const arg = new TextEncoder().encode(self2.args[i]); + buffer8.set(arg, argv_buf); + buffer.setUint8(argv_buf + arg.length, 0); + argv_buf += arg.length + 1; + } + return 0; + }, + environ_sizes_get(environ_count, environ_size) { + const buffer = new DataView(memory().buffer); + buffer.setUint32(environ_count, self2.env.length, true); + let buf_size = 0; + for (const environ of self2.env) { + buf_size += environ.length + 1; + } + buffer.setUint32(environ_size, buf_size, true); + return 0; + }, + environ_get(environ, environ_buf) { + const buffer = new DataView(memory().buffer); + const buffer8 = new Uint8Array(memory().buffer); + const orig_environ_buf = environ_buf; + for (let i = 0; i < self2.env.length; i++) { + buffer.setUint32(environ, environ_buf, true); + environ += 4; + const e = new TextEncoder().encode(self2.env[i]); + buffer8.set(e, environ_buf); + buffer.setUint8(environ_buf + e.length, 0); + environ_buf += e.length + 1; + } + return 0; + } + }; } importObject() { return this.imports; } initialize(instance) { - this.#initialize(instance); + if (!instance.exports.memory) { + throw new Error("The module has to export a default memory."); + } + this.inst = instance; } }; var GuestRuntimeType = /* @__PURE__ */ ((GuestRuntimeType2) => { @@ -408,20 +1062,27 @@ AS $function$ function fetchModuleData(manifestData) { let moduleData = null; if (manifestData instanceof Uint8Array) { - moduleData = manifestData; + moduleData = { data: manifestData }; } else if (manifestData.wasm) { const wasmData = manifestData.wasm; if (wasmData.length > 1) throw Error("This runtime only supports one module in Manifest.wasm"); const wasm = wasmData[0]; - moduleData = wasm.data; + moduleData = wasm; } else if (manifestData.data) { - moduleData = manifestData.data; + moduleData = manifestData; } if (!moduleData) { throw Error(`Unsure how to interpret manifest ${manifestData}`); } - return moduleData; + const expected = moduleData.hash; + if (expected) { + const actual = (0, import_js_sha256.sha256)(moduleData.data); + if (actual !== expected) { + throw Error(`Plugin error: hash mismatch. Expected: ${expected}. Actual: ${actual}`); + } + } + return moduleData.data; } function haskellRuntime(module2) { const haskellInit = module2.exports.hs_init; @@ -451,7 +1112,6 @@ AS $function$ return null; } const kind = reactorInit ? "reactor" : "command"; - console.debug(`WASI (${kind}) runtime detected.`); return { type: 2 /* Wasi */, init, initialized: false }; } function detectGuestRuntime(module2) { @@ -469,7 +1129,7 @@ AS $function$ return extismInstance; } var embeddedRuntime = "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"; - var embeddedRuntimeHash = "80fcbfb1d046f0779adf0e3c4861b264a1c56df2d6c9ee051fc02188e83d45f7"; + var embeddedRuntimeHash = "c04772bc7c7541980fe2e35fae881c190fcc8b4dbf20688ab7b42bec175366ca"; var CurrentPlugin = class { vars; plugin; @@ -569,6 +1229,14 @@ AS $function$ const module2 = fetchModuleData(manifest); return new Plugin(runtime, module2, opts); } + /** + * [js-sha256]{@link https://github.com/emn178/js-sha256} + * + * @version 0.11.0 + * @author Chen, Yi-Cyuan [emn178@gmail.com] + * @copyright Chen, Yi-Cyuan 2014-2024 + * @license MIT + */ return createPlugin(manifest, opts);