From 82dd28e5941b2d1d879563d5035969581b85641e Mon Sep 17 00:00:00 2001 From: cohix Date: Sat, 17 Jul 2021 16:39:58 -0400 Subject: [PATCH 1/8] added a test for json-as --- rwasm/testdata/as-json/.runnable.yaml | 5 + rwasm/testdata/as-json/as-json.wasm | Bin 0 -> 12035 bytes rwasm/testdata/as-json/asconfig.json | 12 + rwasm/testdata/as-json/package-lock.json | 305 +++++++++++++++++++++++ rwasm/testdata/as-json/package.json | 21 ++ rwasm/testdata/as-json/src/index.ts | 33 +++ rwasm/testdata/as-json/src/lib.ts | 43 ++++ rwasm/testdata/as-json/src/tsconfig.json | 6 + rwasm/wasmtest/assemblyscript_test.go | 17 ++ 9 files changed, 442 insertions(+) create mode 100755 rwasm/testdata/as-json/.runnable.yaml create mode 100644 rwasm/testdata/as-json/as-json.wasm create mode 100755 rwasm/testdata/as-json/asconfig.json create mode 100644 rwasm/testdata/as-json/package-lock.json create mode 100755 rwasm/testdata/as-json/package.json create mode 100755 rwasm/testdata/as-json/src/index.ts create mode 100755 rwasm/testdata/as-json/src/lib.ts create mode 100755 rwasm/testdata/as-json/src/tsconfig.json diff --git a/rwasm/testdata/as-json/.runnable.yaml b/rwasm/testdata/as-json/.runnable.yaml new file mode 100755 index 00000000..503619d7 --- /dev/null +++ b/rwasm/testdata/as-json/.runnable.yaml @@ -0,0 +1,5 @@ +name: as-json +namespace: default +lang: assemblyscript +version: "" +apiVersion: 0.10.0 diff --git a/rwasm/testdata/as-json/as-json.wasm b/rwasm/testdata/as-json/as-json.wasm new file mode 100644 index 0000000000000000000000000000000000000000..318eb36c706204efe3d57d1f8438bfe166bf9f68 GIT binary patch literal 12035 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 R`8q2Tee*AocKDZt{{_6Z+PMG# literal 0 HcmV?d00001 diff --git a/rwasm/testdata/as-json/asconfig.json b/rwasm/testdata/as-json/asconfig.json new file mode 100755 index 00000000..e4ad736c --- /dev/null +++ b/rwasm/testdata/as-json/asconfig.json @@ -0,0 +1,12 @@ +{ + "targets": { + "release": { + "binaryFile": "as-json.wasm", + "optimizeLevel": 3, + "shrinkLevel": 1, + "converge": false, + "noAssert": false + } + }, + "options": {} +} \ No newline at end of file diff --git a/rwasm/testdata/as-json/package-lock.json b/rwasm/testdata/as-json/package-lock.json new file mode 100644 index 00000000..d96ea9f5 --- /dev/null +++ b/rwasm/testdata/as-json/package-lock.json @@ -0,0 +1,305 @@ +{ + "name": "as-json", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@assemblyscript/loader": "^0.19", + "@suborbital/suborbital": "^0.10.0", + "json-as": "github:aspkg/as-json", + "source-map-support": "^0.5.19" + }, + "devDependencies": { + "assemblyscript": "^0.19" + } + }, + "node_modules/@assemblyscript/loader": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.19.7.tgz", + "integrity": "sha512-/BdvOMHnfW3uIHFEgDPRbmA+BoQjuYpjKIZgI3p4sG8Jxgy9UuQW7cQUFx7dRlFUk/SBVCoB8N7412NgKyctqg==" + }, + "node_modules/@suborbital/suborbital": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@suborbital/suborbital/-/suborbital-0.10.0.tgz", + "integrity": "sha512-Ggy58dYcqT3pBTvr6nOFuMyLKgsHFjdbz/B/UjPi0tHOQ3n91g0lwOcsIGq3Rlu01FW7ppseSAKkPe2zhvP67w==", + "dependencies": { + "@assemblyscript/loader": "^0.19" + } + }, + "node_modules/as-wasi": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/as-wasi/-/as-wasi-0.4.6.tgz", + "integrity": "sha512-HFWdxLVHrOfchf/M+gE2IczsHBkWXqekZZfHYmDj6WP1UnpQC4k44OeyjqmSwC/db1tppEwCUssDCuFGnMdJZw==" + }, + "node_modules/assemblyscript": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.19.7.tgz", + "integrity": "sha512-0Vs27D9yIqxbwAx/zp2CNMCgR/Aa2cQlMZO+ctW30rhQ0/UOS/J9PkFXRxUVNMYj0xwEMT/Cq6l9flXO2ZJFcQ==", + "dev": true, + "dependencies": { + "binaryen": "101.0.0-nightly.20210703", + "long": "^4.0.0" + }, + "bin": { + "asc": "bin/asc", + "asinit": "bin/asinit" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/assemblyscript" + } + }, + "node_modules/binaryen": { + "version": "101.0.0-nightly.20210703", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-101.0.0-nightly.20210703.tgz", + "integrity": "sha512-7iuRy/aSsd8BlO0ZOG4GqDI8z66UhazD10eeC3i14SOhZJ+MLC3I+BX5ydr3nk9g5j2PDGndxuYvm0gy+VJHYg==", + "dev": true, + "bin": { + "wasm-opt": "bin/wasm-opt" + } + }, + "node_modules/buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/json-as": { + "version": "0.1.0", + "resolved": "git+ssh://git@github.com/aspkg/as-json.git#fed5660b8f577bb43c16462b8e4aa1a1de482574", + "license": "MIT", + "dependencies": { + "as-wasi": "^0.4.5", + "line-column": "^1.0.2", + "visitor-as": "^0.6.0" + } + }, + "node_modules/json-as/node_modules/assemblyscript": { + "version": "0.18.32", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.18.32.tgz", + "integrity": "sha512-Py6zremwGhO3nSoI/VxyVUzTZfNhTjzNzFDaUdG4JhPJHeG+FzVlEoNCrw4bE5nPc7F+P2DJ8tZQCqIt15ceKw==", + "peer": true, + "dependencies": { + "binaryen": "100.0.0-nightly.20210413", + "long": "^4.0.0" + }, + "bin": { + "asc": "bin/asc", + "asinit": "bin/asinit" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/assemblyscript" + } + }, + "node_modules/json-as/node_modules/binaryen": { + "version": "100.0.0-nightly.20210413", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-100.0.0-nightly.20210413.tgz", + "integrity": "sha512-EeGLIxQmJS0xnYl+SH34mNBqVMoixKd9nsE7S7z+CtS9A4eoWn3Qjav+XElgunUgXIHAI5yLnYT2TUGnLX2f1w==", + "peer": true, + "bin": { + "wasm-opt": "bin/wasm-opt" + } + }, + "node_modules/json-as/node_modules/visitor-as": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/visitor-as/-/visitor-as-0.6.0.tgz", + "integrity": "sha512-4WcnwCLXWjhNkwJj9gSqh46sdIv9CyIvnSuwr61OOfrGCtN2mKcW5KE828OeEr1rYjEy0Z/CIdPBJKJRLsUgDA==", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "ts-mixer": "^5.4.1" + }, + "peerDependencies": { + "assemblyscript": "^0.18.31" + } + }, + "node_modules/line-column": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/line-column/-/line-column-1.0.2.tgz", + "integrity": "sha1-0lryk2tvSEkXKzEuR5LR2Ye8NKI=", + "dependencies": { + "isarray": "^1.0.0", + "isobject": "^2.0.0" + } + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/ts-mixer": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-5.4.1.tgz", + "integrity": "sha512-Zo9HgPCtNouDgJ+LGtrzVOjSg8+7WGQktIKLwAfaNrlOK1mWGlz1ejsAF/YqUEqAGjUTeB5fEg8gH9Aui6w9xA==" + } + }, + "dependencies": { + "@assemblyscript/loader": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.19.7.tgz", + "integrity": "sha512-/BdvOMHnfW3uIHFEgDPRbmA+BoQjuYpjKIZgI3p4sG8Jxgy9UuQW7cQUFx7dRlFUk/SBVCoB8N7412NgKyctqg==" + }, + "@suborbital/suborbital": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@suborbital/suborbital/-/suborbital-0.10.0.tgz", + "integrity": "sha512-Ggy58dYcqT3pBTvr6nOFuMyLKgsHFjdbz/B/UjPi0tHOQ3n91g0lwOcsIGq3Rlu01FW7ppseSAKkPe2zhvP67w==", + "requires": { + "@assemblyscript/loader": "^0.19" + } + }, + "as-wasi": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/as-wasi/-/as-wasi-0.4.6.tgz", + "integrity": "sha512-HFWdxLVHrOfchf/M+gE2IczsHBkWXqekZZfHYmDj6WP1UnpQC4k44OeyjqmSwC/db1tppEwCUssDCuFGnMdJZw==" + }, + "assemblyscript": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.19.7.tgz", + "integrity": "sha512-0Vs27D9yIqxbwAx/zp2CNMCgR/Aa2cQlMZO+ctW30rhQ0/UOS/J9PkFXRxUVNMYj0xwEMT/Cq6l9flXO2ZJFcQ==", + "dev": true, + "requires": { + "binaryen": "101.0.0-nightly.20210703", + "long": "^4.0.0" + } + }, + "binaryen": { + "version": "101.0.0-nightly.20210703", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-101.0.0-nightly.20210703.tgz", + "integrity": "sha512-7iuRy/aSsd8BlO0ZOG4GqDI8z66UhazD10eeC3i14SOhZJ+MLC3I+BX5ydr3nk9g5j2PDGndxuYvm0gy+VJHYg==", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + }, + "json-as": { + "version": "git+ssh://git@github.com/aspkg/as-json.git#fed5660b8f577bb43c16462b8e4aa1a1de482574", + "from": "json-as@github:aspkg/as-json", + "requires": { + "as-wasi": "^0.4.5", + "line-column": "^1.0.2", + "visitor-as": "^0.6.0" + }, + "dependencies": { + "assemblyscript": { + "version": "0.18.32", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.18.32.tgz", + "integrity": "sha512-Py6zremwGhO3nSoI/VxyVUzTZfNhTjzNzFDaUdG4JhPJHeG+FzVlEoNCrw4bE5nPc7F+P2DJ8tZQCqIt15ceKw==", + "peer": true, + "requires": { + "binaryen": "100.0.0-nightly.20210413", + "long": "^4.0.0" + } + }, + "binaryen": { + "version": "100.0.0-nightly.20210413", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-100.0.0-nightly.20210413.tgz", + "integrity": "sha512-EeGLIxQmJS0xnYl+SH34mNBqVMoixKd9nsE7S7z+CtS9A4eoWn3Qjav+XElgunUgXIHAI5yLnYT2TUGnLX2f1w==", + "peer": true + }, + "visitor-as": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/visitor-as/-/visitor-as-0.6.0.tgz", + "integrity": "sha512-4WcnwCLXWjhNkwJj9gSqh46sdIv9CyIvnSuwr61OOfrGCtN2mKcW5KE828OeEr1rYjEy0Z/CIdPBJKJRLsUgDA==", + "requires": { + "lodash.clonedeep": "^4.5.0", + "ts-mixer": "^5.4.1" + } + } + } + }, + "line-column": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/line-column/-/line-column-1.0.2.tgz", + "integrity": "sha1-0lryk2tvSEkXKzEuR5LR2Ye8NKI=", + "requires": { + "isarray": "^1.0.0", + "isobject": "^2.0.0" + } + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "ts-mixer": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-5.4.1.tgz", + "integrity": "sha512-Zo9HgPCtNouDgJ+LGtrzVOjSg8+7WGQktIKLwAfaNrlOK1mWGlz1ejsAF/YqUEqAGjUTeB5fEg8gH9Aui6w9xA==" + } + } +} diff --git a/rwasm/testdata/as-json/package.json b/rwasm/testdata/as-json/package.json new file mode 100755 index 00000000..9623f0dd --- /dev/null +++ b/rwasm/testdata/as-json/package.json @@ -0,0 +1,21 @@ +{ + "name": "as-json", + "version": "1.0.0", + "description": "", + "main": "src/index.ts", + "scripts": { + "test": "node tests", + "asbuild": "asc src/index.ts --transform ./node_modules/json-as/transform --target release --use abort=src/index/abort" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "assemblyscript": "^0.19" + }, + "dependencies": { + "@assemblyscript/loader": "^0.19", + "@suborbital/suborbital": "^0.10.0", + "json-as": "github:aspkg/as-json", + "source-map-support": "^0.5.19" + } +} diff --git a/rwasm/testdata/as-json/src/index.ts b/rwasm/testdata/as-json/src/index.ts new file mode 100755 index 00000000..38f997ab --- /dev/null +++ b/rwasm/testdata/as-json/src/index.ts @@ -0,0 +1,33 @@ +// DO NOT EDIT; generated file + +import { return_result, return_abort, toFFI, fromFFI, getIdent, setIdent } from "@suborbital/suborbital"; +import { run } from "./lib" + +export function run_e(ptr: usize, size: i32, ident: i32): void { + // set the current ident for other API methods to use + setIdent(ident) + + // read the memory that was passed as input + var inBuffer = fromFFI(ptr, size) + + // execute the Runnable + let result = run(inBuffer) + + // return the result to the host + return_result(changetype(result), result.byteLength, getIdent()) +} + +export function allocate(size: i32): usize { + return heap.alloc(size) +} + +export function deallocate(ptr: i32, _: i32): void { + heap.free(ptr) +} + +function abort(message: string | null, fileName: string | null, lineNumber: u32, columnNumber: u32): void { + let msgFFI = toFFI(String.UTF8.encode(message ? message : "")) + let fileFFI = toFFI(String.UTF8.encode(fileName ? fileName : "")) + + return_abort(msgFFI.ptr, msgFFI.size, fileFFI.ptr, fileFFI.size, lineNumber, columnNumber, getIdent()) +} \ No newline at end of file diff --git a/rwasm/testdata/as-json/src/lib.ts b/rwasm/testdata/as-json/src/lib.ts new file mode 100755 index 00000000..db8014d9 --- /dev/null +++ b/rwasm/testdata/as-json/src/lib.ts @@ -0,0 +1,43 @@ +import { logInfo } from "@suborbital/suborbital" +import { JSON } from "json-as" + +// @ts-ignore +@json +class JSONSchema { + firstName: string + lastName: string + age: i32 + meta: Meta + tags: Array +} + +// @ts-ignore +@json +class Meta { + country: string +} + +export function run(_: ArrayBuffer): ArrayBuffer { + + const data: JSONSchema = { + firstName: 'Connor', + lastName: 'Hicks', + age: 26, + meta: { + country: "Canada", + }, + tags: ["hello", "world"] + } + + const stringified = JSON.stringify(data) + + logInfo(stringified) + + // const stringified2 = "{\"firstName\":\"Connor\",\"lastName\":\"Hicks\",\"age\":14,\"meta\":{\"country\":\"Canada\"},\"tags\":[\"hello\",\"world\"]}" + + // const parsed = JSON.parse(stringified2) + + // const stringifiedAgain = JSON.stringify(parsed) + + return String.UTF8.encode(stringified) +} \ No newline at end of file diff --git a/rwasm/testdata/as-json/src/tsconfig.json b/rwasm/testdata/as-json/src/tsconfig.json new file mode 100755 index 00000000..e28fcf25 --- /dev/null +++ b/rwasm/testdata/as-json/src/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "assemblyscript/std/assembly.json", + "include": [ + "./**/*.ts" + ] +} \ No newline at end of file diff --git a/rwasm/wasmtest/assemblyscript_test.go b/rwasm/wasmtest/assemblyscript_test.go index 7b7ad51d..d4f7173d 100644 --- a/rwasm/wasmtest/assemblyscript_test.go +++ b/rwasm/wasmtest/assemblyscript_test.go @@ -48,6 +48,23 @@ func TestASFetch(t *testing.T) { } } +func TestASJSON(t *testing.T) { + r := rt.New() + + // test a WASM module that is loaded directly instead of through the bundle + doWasm := r.Register("as-json", rwasm.NewRunner("../testdata/as-json/as-json.wasm")) + + res, err := doWasm("").Then() + if err != nil { + t.Error(errors.Wrap(err, "failed to Then")) + return + } + + if string(res.([]byte)) != `{"firstName":"Connor","lastName":"Hicks","age":26,"meta":{"country":"Canada"},"tags":["hello","world"]}` { + t.Error("as-json failed, got:", string(res.([]byte))) + } +} + func TestASLargeData(t *testing.T) { r := rt.New() From 31a19072b6785dfd25b97b10213969b3e4c4122c Mon Sep 17 00:00:00 2001 From: cohix Date: Mon, 19 Jul 2021 16:33:05 -0400 Subject: [PATCH 2/8] updated as-json test --- rwasm/testdata/as-json/as-json.wasm | Bin 12035 -> 17248 bytes rwasm/testdata/as-json/package-lock.json | 111 +---------------------- rwasm/testdata/as-json/package.json | 3 +- rwasm/testdata/as-json/src/lib.ts | 12 ++- rwasm/wasmtest/assemblyscript_test.go | 2 +- 5 files changed, 13 insertions(+), 115 deletions(-) diff --git a/rwasm/testdata/as-json/as-json.wasm b/rwasm/testdata/as-json/as-json.wasm index 318eb36c706204efe3d57d1f8438bfe166bf9f68..21d41314a83b8161d0eed19310c4680f7b523a4b 100644 GIT binary patch literal 17248 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 delta 3155 zcmZuzU1(g#6`q-UclYkjm2@r1yISqay8EMQtw@$_MRFV4wMI>h|I)P3*8Q<6343w6 z`b(s>>rj`gwonRjl69vKwIhNEi7;&nY78Y1QPhV(9s)J(OG@+L5{gR*#UXwOMUZ}H z?rJ5|?(UqqbIzIb^Uaxa_wLX6&%WQsrWR*8V~ih8Oo||2M0haCiC6(KI0nP-`hm># zukSwZSmn9Pv6=ac6SIpKS&UXq3+3vig}I4^^5UhLDzmJSVG&`>vTcxv9pzjwZV6$* z4@R5|&N&m7V0I)D6E>$G=h2A88IL~Rq&d%Czh9_4xWQ$t&yFlynwu!IUT11%X8!zC zwaiM13+2XQZ*;aiJHPOpU=DvIaqG$9R_5b7BJ6N-d?tT~5CXN*p|CJ8RAAMWLEu=U3J_*!jeI z1+->&TF}-1u-o*8Jpqm%IRZK!AzxP_lc0Z#{1o(DbQtuPhQ1rE=5BI@lo8)*_+X79 zfE0XT5>>TyQ;)}T{H6|K-CfXqZIvHm%By-VM7)@g;{XWRKe(aaj(r)H{}a2y`}CqS zAi#Rn8N=eA&bSj|1lFne@1eCB|1Rj+#0cn%i51X6nE^d5i+terGx7n)RBrl^^L~A@ z%v*P%c*NuHXH~V-c$6YR^3gqLID5ry-&Wn=J``W+VyI&q-1y?!K zMc3;uxMS>)#e7i&kF0q^0Jh+IhxGo=y^+@iw*o!c+3hA6Pb4fm5{)@=eXX;sKkxjB z{&OZxh<%jF7aycgAn+Q{-oU_@%0e!q_5(Qcj5EDITXX-w$$Ll0c&RJpAbz;?nf`aS zAiPI)y6frYcgQc)zPP1!sLjrEQsZ9E9;HxA!q$H*>`kmCM?^nRSWD_p3a9u!eWduM zZsHRl_6}& zq5{wK_MNixfPqe6LlPVUv*%Okc!Pw(O3Fxm4tOa;oK6a|o^4UM5p2EDTh&Y5NAD1Gnf{~)`kf$XXXVYCg5Fh>`-;N~KD40-yagGB_{GIShw>RUr|pzjPl60F-i zPIx_3uVPe;Zr>v`y~c^=t*4NU>JzMSwKx-#O4CV>L6 z=w>NinW-pVMe(-hZK^g~1+XE&^Rm9kaa=shkD~qgHcF0HE4VUIng=;M%%M-*O5TXb zdwnNL4tJ6?E4e6LO$<16j+;`3-)bHNPQwz1QOnE17xN>5SAZ;7q$8pTtCbygk!B?q zA%g@Ej^A_u%fyMj*cuJD+VxvQ2DY-Z(PI!q%#Zq!>3qCWLH`62VPYl)ub8(3REY#L zMy@F!Gsi)J2-tqSk~h2^VF^D{$&uZy=zQCR9|L%BCH}uB<4722cQ^~+HAJx z4E}pudF;$S3ZmX(8}ZShI07Xf_A-}nT}sf4Odr^r3l7qG*3zbD5LoSmgaZ!lHZ`ZZ zsNS4vY3~ar9WsLh^Kq|SXg$stvpf+z9WfhnQxVp^kq8(_4 z$sC=aN7oInxYg!~+ZPVMX`Rh7^{-uW7iWwmFrH>*HiPdxQ=7Xahx8Y%+tMF`zX0h4 zrj}cc^o>@TaIo(_h!eFM-IP2|_AECwc=)pakSWslUWt{d1jQy~*Tk>;E-O_K5 zek0h#f>e^Sg;Xd+a#w|MwVX6D-b%{dBx}YvkHjvqImj2-b47h_Tmg5t9znR+9Xzm?jKgrc|z7}R@^0j>8_IyTl5-^A)F yV(!qxV?Q{%*%4-t-f4H+>`GcT(Si9P3$t2J%ecal@WAo|>=d-dM^I?^*y_I(a4-u1 diff --git a/rwasm/testdata/as-json/package-lock.json b/rwasm/testdata/as-json/package-lock.json index d96ea9f5..63d4c740 100644 --- a/rwasm/testdata/as-json/package-lock.json +++ b/rwasm/testdata/as-json/package-lock.json @@ -10,8 +10,7 @@ "dependencies": { "@assemblyscript/loader": "^0.19", "@suborbital/suborbital": "^0.10.0", - "json-as": "github:aspkg/as-json", - "source-map-support": "^0.5.19" + "json-as": "github:aspkg/as-json" }, "devDependencies": { "assemblyscript": "^0.19" @@ -30,11 +29,6 @@ "@assemblyscript/loader": "^0.19" } }, - "node_modules/as-wasi": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/as-wasi/-/as-wasi-0.4.6.tgz", - "integrity": "sha512-HFWdxLVHrOfchf/M+gE2IczsHBkWXqekZZfHYmDj6WP1UnpQC4k44OeyjqmSwC/db1tppEwCUssDCuFGnMdJZw==" - }, "node_modules/assemblyscript": { "version": "0.19.7", "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.19.7.tgz", @@ -62,34 +56,11 @@ "wasm-opt": "bin/wasm-opt" } }, - "node_modules/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/json-as": { - "version": "0.1.0", - "resolved": "git+ssh://git@github.com/aspkg/as-json.git#fed5660b8f577bb43c16462b8e4aa1a1de482574", + "version": "0.1.1", + "resolved": "git+ssh://git@github.com/aspkg/as-json.git#f5b00039ed9cd0b95f21bec0c85abf5cdbb32e3b", "license": "MIT", "dependencies": { - "as-wasi": "^0.4.5", - "line-column": "^1.0.2", "visitor-as": "^0.6.0" } }, @@ -132,15 +103,6 @@ "assemblyscript": "^0.18.31" } }, - "node_modules/line-column": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/line-column/-/line-column-1.0.2.tgz", - "integrity": "sha1-0lryk2tvSEkXKzEuR5LR2Ye8NKI=", - "dependencies": { - "isarray": "^1.0.0", - "isobject": "^2.0.0" - } - }, "node_modules/lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -151,23 +113,6 @@ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "node_modules/ts-mixer": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-5.4.1.tgz", @@ -188,11 +133,6 @@ "@assemblyscript/loader": "^0.19" } }, - "as-wasi": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/as-wasi/-/as-wasi-0.4.6.tgz", - "integrity": "sha512-HFWdxLVHrOfchf/M+gE2IczsHBkWXqekZZfHYmDj6WP1UnpQC4k44OeyjqmSwC/db1tppEwCUssDCuFGnMdJZw==" - }, "assemblyscript": { "version": "0.19.7", "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.19.7.tgz", @@ -209,30 +149,10 @@ "integrity": "sha512-7iuRy/aSsd8BlO0ZOG4GqDI8z66UhazD10eeC3i14SOhZJ+MLC3I+BX5ydr3nk9g5j2PDGndxuYvm0gy+VJHYg==", "dev": true }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - }, "json-as": { - "version": "git+ssh://git@github.com/aspkg/as-json.git#fed5660b8f577bb43c16462b8e4aa1a1de482574", + "version": "git+ssh://git@github.com/aspkg/as-json.git#f5b00039ed9cd0b95f21bec0c85abf5cdbb32e3b", "from": "json-as@github:aspkg/as-json", "requires": { - "as-wasi": "^0.4.5", - "line-column": "^1.0.2", "visitor-as": "^0.6.0" }, "dependencies": { @@ -263,15 +183,6 @@ } } }, - "line-column": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/line-column/-/line-column-1.0.2.tgz", - "integrity": "sha1-0lryk2tvSEkXKzEuR5LR2Ye8NKI=", - "requires": { - "isarray": "^1.0.0", - "isobject": "^2.0.0" - } - }, "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -282,20 +193,6 @@ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "ts-mixer": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-5.4.1.tgz", diff --git a/rwasm/testdata/as-json/package.json b/rwasm/testdata/as-json/package.json index 9623f0dd..7242b6aa 100755 --- a/rwasm/testdata/as-json/package.json +++ b/rwasm/testdata/as-json/package.json @@ -15,7 +15,6 @@ "dependencies": { "@assemblyscript/loader": "^0.19", "@suborbital/suborbital": "^0.10.0", - "json-as": "github:aspkg/as-json", - "source-map-support": "^0.5.19" + "json-as": "github:aspkg/as-json" } } diff --git a/rwasm/testdata/as-json/src/lib.ts b/rwasm/testdata/as-json/src/lib.ts index db8014d9..efd3471a 100755 --- a/rwasm/testdata/as-json/src/lib.ts +++ b/rwasm/testdata/as-json/src/lib.ts @@ -15,6 +15,8 @@ class JSONSchema { @json class Meta { country: string + province: string + isAwesome: boolean } export function run(_: ArrayBuffer): ArrayBuffer { @@ -25,6 +27,8 @@ export function run(_: ArrayBuffer): ArrayBuffer { age: 26, meta: { country: "Canada", + province: "Ontario", + isAwesome: true, }, tags: ["hello", "world"] } @@ -33,11 +37,9 @@ export function run(_: ArrayBuffer): ArrayBuffer { logInfo(stringified) - // const stringified2 = "{\"firstName\":\"Connor\",\"lastName\":\"Hicks\",\"age\":14,\"meta\":{\"country\":\"Canada\"},\"tags\":[\"hello\",\"world\"]}" - - // const parsed = JSON.parse(stringified2) + const parsed = JSON.parse(stringified) - // const stringifiedAgain = JSON.stringify(parsed) + const stringifiedAgain = JSON.stringify(parsed) - return String.UTF8.encode(stringified) + return String.UTF8.encode(stringifiedAgain) } \ No newline at end of file diff --git a/rwasm/wasmtest/assemblyscript_test.go b/rwasm/wasmtest/assemblyscript_test.go index d4f7173d..72e0f16c 100644 --- a/rwasm/wasmtest/assemblyscript_test.go +++ b/rwasm/wasmtest/assemblyscript_test.go @@ -60,7 +60,7 @@ func TestASJSON(t *testing.T) { return } - if string(res.([]byte)) != `{"firstName":"Connor","lastName":"Hicks","age":26,"meta":{"country":"Canada"},"tags":["hello","world"]}` { + if string(res.([]byte)) != `{"firstName":"Connor","lastName":"Hicks","age":26,"meta":{"country":"Canada","province":"Ontario","isAwesome":true},"tags":["hello","world"]}` { t.Error("as-json failed, got:", string(res.([]byte))) } } From f7fe840d9d88fb86f301a695cef84cac8dcc33ed Mon Sep 17 00:00:00 2001 From: cohix Date: Mon, 26 Jul 2021 16:06:18 -0400 Subject: [PATCH 3/8] added the ability to authenticate GraphQL endpoints --- rcap/authentication.go | 81 ++++++++++++++++++++++ rcap/graphql.go | 17 +++-- rcap/tester/main.go | 30 -------- rt/capabilities.go | 2 + rwasm/api_graphql.go | 2 +- rwasm/testdata/as-graphql/as-graphql.wasm | Bin 6792 -> 6839 bytes rwasm/testdata/as-graphql/src/lib.ts | 2 +- rwasm/testdata/rs-graphql/rs-graphql.wasm | Bin 1814949 -> 1811054 bytes rwasm/testdata/rs-graphql/src/lib.rs | 16 ++--- rwasm/wasmtest/assemblyscript_test.go | 17 ++++- rwasm/wasmtest/rust_test.go | 20 +++++- 11 files changed, 137 insertions(+), 50 deletions(-) create mode 100644 rcap/authentication.go delete mode 100644 rcap/tester/main.go diff --git a/rcap/authentication.go b/rcap/authentication.go new file mode 100644 index 00000000..4c3ecb28 --- /dev/null +++ b/rcap/authentication.go @@ -0,0 +1,81 @@ +package rcap + +import ( + "os" + "strings" +) + +// AuthProvider is a provider for various kinds of auth +type AuthProvider interface { + HeaderForDomain(string) *AuthHeader +} + +// AuthHeader is an HTTP header designed to authenticate requests +type AuthHeader struct { + HeaderType string `json:"headerType"` + Value string `json:"value"` +} + +// AuthProviderConfig is a config for the default auth provider +type AuthProviderConfig struct { + // Headers is a map between domains and auth header that should be added to requests to those domains + Headers map[string]AuthHeader `json:"headers"` +} + +type defaultAuthProvider struct { + config *AuthProviderConfig + + augmentedHeaders map[string]AuthHeader +} + +// DefaultAuthProvider creates the default static auth provider +func DefaultAuthProvider(config *AuthProviderConfig) AuthProvider { + ap := &defaultAuthProvider{ + config: config, + augmentedHeaders: map[string]AuthHeader{}, + } + + return ap +} + +// HeadersForDomain returns the appropriate auth headers for the given domain +func (ap *defaultAuthProvider) HeaderForDomain(domain string) *AuthHeader { + header, ok := ap.augmentedHeaders[domain] + if !ok { + if ap.config == nil { + return nil + } + + origignalHeader, exists := ap.config.Headers[domain] + if !exists { + return nil + } + + augmented := augmentHeaderFromEnv(origignalHeader) + + ap.augmentedHeaders[domain] = augmented + header = augmented + } + + return &header +} + +// augmentHeadersFromEnv takes a an AuthHeader and replaces and `env()` values with their representative values from the environment +func augmentHeaderFromEnv(header AuthHeader) AuthHeader { + // turn env(SOME_HEADER_KEY) into SOME_HEADER_KEY + if strings.HasPrefix(header.Value, "env(") && strings.HasSuffix(header.Value, ")") { + headerKey := strings.TrimPrefix(header.Value, "env(") + headerKey = strings.TrimSuffix(headerKey, ")") + + val := os.Getenv(headerKey) + + augmentedHeader := AuthHeader{ + HeaderType: header.HeaderType, + Value: val, + } + + return augmentedHeader + } + + return header +} diff --git a/rcap/graphql.go b/rcap/graphql.go index eeb12bd7..f78411c2 100644 --- a/rcap/graphql.go +++ b/rcap/graphql.go @@ -6,13 +6,14 @@ import ( "fmt" "io/ioutil" "net/http" + "net/url" "github.com/pkg/errors" ) // GraphQLClient is a GraphQL capability for Reactr Modules type GraphQLClient interface { - Do(endpoint, query string) (*GraphQLResponse, error) + Do(auth AuthProvider, endpoint, query string) (*GraphQLResponse, error) } // defaultGraphQLClient is the default implementation of the GraphQL capability @@ -48,7 +49,7 @@ type GraphQLError struct { Path string `json:"path"` } -func (g *defaultGraphQLClient) Do(endpoint, query string) (*GraphQLResponse, error) { +func (g *defaultGraphQLClient) Do(auth AuthProvider, endpoint, query string) (*GraphQLResponse, error) { r := &GraphQLRequest{ Query: query, Variables: map[string]string{}, @@ -59,6 +60,11 @@ func (g *defaultGraphQLClient) Do(endpoint, query string) (*GraphQLResponse, err return nil, errors.Wrap(err, "failed to Marshal request") } + endpointURL, err := url.Parse(endpoint) + if err != nil { + return nil, errors.Wrap(err, "failed to Parse endpoint") + } + req, err := http.NewRequest(http.MethodPost, endpoint, bytes.NewBuffer(reqBytes)) if err != nil { return nil, errors.Wrap(err, "failed to NewRequest") @@ -66,6 +72,11 @@ func (g *defaultGraphQLClient) Do(endpoint, query string) (*GraphQLResponse, err req.Header.Add("Content-Type", "application/json") + authHeader := auth.HeaderForDomain(endpointURL.Host) + if authHeader.Value != "" { + req.Header.Add("Authorization", fmt.Sprintf("%s %s", authHeader.HeaderType, authHeader.Value)) + } + resp, err := g.client.Do(req) if err != nil { return nil, errors.Wrap(err, "failed to Do") @@ -78,8 +89,6 @@ func (g *defaultGraphQLClient) Do(endpoint, query string) (*GraphQLResponse, err return nil, errors.Wrap(err, "failed to ReadAll body") } - fmt.Println(string(respJSON)) - gqlResp := &GraphQLResponse{} if err := json.Unmarshal(respJSON, gqlResp); err != nil { return nil, errors.Wrap(err, "failed to Unmarshal response") diff --git a/rcap/tester/main.go b/rcap/tester/main.go deleted file mode 100644 index 24710c0f..00000000 --- a/rcap/tester/main.go +++ /dev/null @@ -1,30 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "log" - - "github.com/suborbital/reactr/rcap" -) - -func main() { - gqlClient := rcap.DefaultGraphQLClient() - - resp, err := gqlClient.Do("https://api.rawkode.dev", `{ - allProfiles { - forename - surname - } - } - `) - - if err != nil { - fmt.Println(resp) - log.Fatal(err) - } - - jsonBytes, _ := json.Marshal(resp.Data) - - fmt.Println(string(jsonBytes)) -} diff --git a/rt/capabilities.go b/rt/capabilities.go index af2381a2..1860547b 100644 --- a/rt/capabilities.go +++ b/rt/capabilities.go @@ -10,6 +10,7 @@ var ErrCapabilityNotAvailable = errors.New("capability not available") // Capabilities define the capabilities available to a Runnable type Capabilities struct { + Auth rcap.AuthProvider LoggerSource rcap.LoggerSource HTTPClient rcap.HTTPClient GraphQLClient rcap.GraphQLClient @@ -25,6 +26,7 @@ type Capabilities struct { func defaultCaps(logger *vlog.Logger) Capabilities { caps := Capabilities{ + Auth: rcap.DefaultAuthProvider(nil), // no authentication config is set up by default LoggerSource: rcap.DefaultLoggerSource(logger), HTTPClient: rcap.DefaultHTTPClient(), GraphQLClient: rcap.DefaultGraphQLClient(), diff --git a/rwasm/api_graphql.go b/rwasm/api_graphql.go index b79b34ef..8f502a9b 100644 --- a/rwasm/api_graphql.go +++ b/rwasm/api_graphql.go @@ -36,7 +36,7 @@ func graphql_query(endpointPointer int32, endpointSize int32, queryPointer int32 queryBytes := inst.readMemory(queryPointer, querySize) query := string(queryBytes) - resp, err := inst.ctx.GraphQLClient.Do(endpoint, query) + resp, err := inst.ctx.GraphQLClient.Do(inst.ctx.Auth, endpoint, query) if err != nil { internalLogger.Error(errors.Wrap(err, "failed to GraphQLClient.Do")) return -1 diff --git a/rwasm/testdata/as-graphql/as-graphql.wasm b/rwasm/testdata/as-graphql/as-graphql.wasm index eaf676e4754e283d4810f816fb9134baaf0e5066..e9fe26a2825ba462ad5998bd140dd47a7d343718 100644 GIT binary patch delta 312 zcmeA$-EO);n2~ACgw3Li#vppK7gK~>gMbDTgExzVV*{7t0WL=|M;QSn25tpLN9Gd8 z7JFj} z21kJs0X|0{SA~l^mXWDmfx!`IWi+f*9dq3U3CCx+=tDK!Z9q2H#WzK7cud!VQ}2R$32&kk%56>+T=TunU>WI3JiG+ zi43_6sSG+u>~Mxmh7yJh27iWfpnNJr5m2rc2p#Y6b2G{?IKG%1ASI#DAi&Mb3N%Xr Th(Q48&N%|yoQ^;y6Nn1{NM=jg delta 265 zcmdmP+F`mun33sE|7KA}V-P*riz!0x0>1_mgExzVV*{7t0WL=|M;QSn25tpLN9Gd8 zEBu=eFiEp0HcVi2WH4i5a9l74!eDj)DiHT%0Z~jPjt!IluqiS&OqOGpmjkI?GKbNg z!BL<@fX@-gRpH`}Wn`*XU~mLl8O{C_WU~{;GLS=Faqw_*AK(WW&8WidcwjQ4&_$5+ z6(J?=Kl~m*S4{vKcVIK4a10CM%FS`&MNB+3430baxbqnq7#K1p-<8bdu4Qms!_Unq j0~DWJFD0RHfuEa~6)39!#2^5)_zgcdrz4Qb1mXe!J>5g6 diff --git a/rwasm/testdata/as-graphql/src/lib.ts b/rwasm/testdata/as-graphql/src/lib.ts index afce4ce2..2f3f3082 100755 --- a/rwasm/testdata/as-graphql/src/lib.ts +++ b/rwasm/testdata/as-graphql/src/lib.ts @@ -1,7 +1,7 @@ import { graphQLQuery, logInfo } from "@suborbital/suborbital" export function run(_: ArrayBuffer): ArrayBuffer { - let result = graphQLQuery("https://api.github.com/graphql", "{ repository (owner: \"suborbital\", name: \"reactr\") }") + let result = graphQLQuery("https://api.github.com/graphql", "{ repository (owner: \"suborbital\", name: \"reactr\") { name, nameWithOwner }}") if (result.byteLength == 0) { return String.UTF8.encode("failed") } diff --git a/rwasm/testdata/rs-graphql/rs-graphql.wasm b/rwasm/testdata/rs-graphql/rs-graphql.wasm index 4ab6ba47fef10507909b6bd297cd1e29fad7c509..d3351ef946a3d676c3a6f6cb6c69c7c3b2b94f49 100755 GIT binary patch delta 69242 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 vIwjD+*6+ZH_$|B5Y z9%ZvRQS5Qr!owq6GN|xyr%kd+lHF#biu}j!U{l!W(GDAvqMgaMAX6$U4@=&lq#QYJ zd3SYpIVV<3oILeDS+b9vG!%(u9*vQqMT;|vJ6+s}NT%_j6cJF~0rHi!$#xw1WA_uG`RaejQ3 zvK;j0&XRp!5Tjg9|NORGxlCalA>HPeOJyJ4?4@!z-W;WnO0|`9m4_=OB~iJ?-|P66 zQ}dSEov5~QL?TTCGCm&0#~@my){k-6r&1li+#!Pb?S5JGA)I-^Qald7^y;PPq0Mj0 zlUp{muH{7$orQ0|m8E(a}EN>MPPZZo+(KA{;13zBqnnZ~h9!GysO7Vs`9+c|NJe*0b} z1tqUWKQdBZ1yFI+{eBI)Y|>;KJ`U>X(kv-m#{6 zVF?*h&`CSY5j76ArPuhVN)iA!fIR5{0Zlmo>IFg3D6}O{+@(%(X0XNTW6tId61_=1 z>1@irQ0=bzKpVP7rx{Z$38UkO3!Nj4@DW3G`iNS`ot3K(Hs&Qm*AYJSN$F=%HMS&l zlRDX5hx)bB?awzIM23TKQyBh1COAz^1kgw>T2n8(D~%@LPflWYz;ZgfOD^|Ix(y=Wb~MU|5c>P((x64yc{64M@Dey8)K|}kHHhV!M$sg-DNL`arg?LRg=lEF zqeXKi9=$L{a-07@)Hz>0=?#xEnuh`;aFhClcPD#F)xx`^7z&tXgU!crzgE@X!>6#v z)$tMaQn>~JTR4VL#v1|{LIL{6d`r|F5p(OWdW1ZM`97c?z~OB)-^uI0A^@y>a?@P* zeXS0SOlIGxGa@IlLsg$eE@SMFdatiZ#*d32qf{ogmOTP%1jf|VNPRcDJ-ehP#ALem⩔lchr_K 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�)EBgB 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 K8xLBdbpAgJKqY7Z diff --git a/rwasm/testdata/rs-graphql/src/lib.rs b/rwasm/testdata/rs-graphql/src/lib.rs index 881c0dcb..06570a95 100755 --- a/rwasm/testdata/rs-graphql/src/lib.rs +++ b/rwasm/testdata/rs-graphql/src/lib.rs @@ -6,19 +6,19 @@ use suborbital::util; struct RsGraqhql{} impl Runnable for RsGraqhql { - fn run(&self, input: Vec) -> Result, RunErr> { - let in_string = String::from_utf8(input).unwrap(); - - match query("https://api.rawkode.dev", "{ allProfiles { forename, surname } }") { + fn run(&self, _: Vec) -> Result, RunErr> { + let result = match query("https://api.github.com/graphql", "{ repository (owner: \"suborbital\", name: \"reactr\") { name, nameWithOwner }}") { Ok(response) => { - info(util::to_string(response).as_str()) + info(util::to_string(response.clone()).as_str()); + response } Err(e) => { - error(e.message.as_str()) + error(e.message.as_str()); + return Err(RunErr::new(1, e.message.as_str())) } - } + }; - Ok(String::from(format!("hello {}", in_string)).as_bytes().to_vec()) + Ok(result) } } diff --git a/rwasm/wasmtest/assemblyscript_test.go b/rwasm/wasmtest/assemblyscript_test.go index 203f1e53..7d8be639 100644 --- a/rwasm/wasmtest/assemblyscript_test.go +++ b/rwasm/wasmtest/assemblyscript_test.go @@ -7,6 +7,7 @@ import ( "github.com/google/uuid" "github.com/pkg/errors" + "github.com/suborbital/reactr/rcap" "github.com/suborbital/reactr/request" "github.com/suborbital/reactr/rt" "github.com/suborbital/reactr/rwasm" @@ -68,16 +69,26 @@ func TestASJSON(t *testing.T) { func TestASGraphql(t *testing.T) { r := rt.New() + caps := r.DefaultCaps() + caps.Auth = rcap.DefaultAuthProvider(&rcap.AuthProviderConfig{ + Headers: map[string]rcap.AuthHeader{ + "api.github.com": { + HeaderType: "bearer", + Value: "env(GITHUB_TOKEN)", + }, + }, + }) + // test a WASM module that is loaded directly instead of through the bundle - doWasm := r.Register("as-graphql", rwasm.NewRunner("../testdata/as-graphql/as-graphql.wasm")) + r.RegisterWithCaps("as-graphql", rwasm.NewRunner("../testdata/as-graphql/as-graphql.wasm"), caps) - res, err := doWasm("").Then() + res, err := r.Do(rt.NewJob("as-graphql", nil)).Then() if err != nil { t.Error(errors.Wrap(err, "failed to Then")) return } - if string(res.([]byte)) != `{"data":{"allProfiles":[{"forename":"David","surname":"McKay"}]}}` { + if string(res.([]byte)) != `{"data":{"repository":{"name":"reactr","nameWithOwner":"suborbital/reactr"}}}` { t.Error("as-graphql failed, got:", string(res.([]byte))) } } diff --git a/rwasm/wasmtest/rust_test.go b/rwasm/wasmtest/rust_test.go index 7a41fa73..e5edc7c5 100644 --- a/rwasm/wasmtest/rust_test.go +++ b/rwasm/wasmtest/rust_test.go @@ -7,6 +7,7 @@ import ( "github.com/google/uuid" "github.com/pkg/errors" + "github.com/suborbital/reactr/rcap" "github.com/suborbital/reactr/request" "github.com/suborbital/reactr/rt" "github.com/suborbital/reactr/rwasm" @@ -36,14 +37,27 @@ func TestWasmRunnerWithFetch(t *testing.T) { func TestGraphQLRunner(t *testing.T) { r := rt.New() - // test a WASM module that is loaded directly instead of through the bundle - doWasm := r.Register("wasm", rwasm.NewRunner("../testdata/rs-graphql/rs-graphql.wasm")) + caps := r.DefaultCaps() + caps.Auth = rcap.DefaultAuthProvider(&rcap.AuthProviderConfig{ + Headers: map[string]rcap.AuthHeader{ + "api.github.com": { + HeaderType: "bearer", + Value: "env(GITHUB_TOKEN)", + }, + }, + }) + + r.RegisterWithCaps("rs-graphql", rwasm.NewRunner("../testdata/rs-graphql/rs-graphql.wasm"), caps) - _, err := doWasm("").Then() + res, err := r.Do(rt.NewJob("rs-graphql", nil)).Then() if err != nil { t.Error(errors.Wrap(err, "failed to Then")) return } + + if string(res.([]byte)) != `{"data":{"repository":{"name":"reactr","nameWithOwner":"suborbital/reactr"}}}` { + t.Error("as-graphql failed, got:", string(res.([]byte))) + } } func TestWasmRunnerReturnError(t *testing.T) { From bfbef597d60ebcb7e02c53e1bdd204558094e1ce Mon Sep 17 00:00:00 2001 From: cohix Date: Mon, 26 Jul 2021 16:10:50 -0400 Subject: [PATCH 4/8] include response body in error message --- rcap/graphql.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rcap/graphql.go b/rcap/graphql.go index f78411c2..56c3f47a 100644 --- a/rcap/graphql.go +++ b/rcap/graphql.go @@ -95,7 +95,7 @@ func (g *defaultGraphQLClient) Do(auth AuthProvider, endpoint, query string) (*G } if resp.StatusCode > 299 { - return gqlResp, errors.New("non-200 HTTP response code") + return gqlResp, fmt.Errorf("non-200 HTTP response code; %s", string(respJSON)) } if gqlResp.Errors != nil && len(gqlResp.Errors) > 0 { From b8fd47ec33568311f183d447dde0596502d9934d Mon Sep 17 00:00:00 2001 From: cohix Date: Mon, 26 Jul 2021 16:15:37 -0400 Subject: [PATCH 5/8] trigger tests From a34fc17b30089179e5293e11860e348a3bd86d79 Mon Sep 17 00:00:00 2001 From: cohix Date: Mon, 26 Jul 2021 16:20:46 -0400 Subject: [PATCH 6/8] debug github workflow --- .github/workflows/sanity.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/sanity.yml b/.github/workflows/sanity.yml index 1b10402e..4e09f27a 100644 --- a/.github/workflows/sanity.yml +++ b/.github/workflows/sanity.yml @@ -33,4 +33,5 @@ jobs: - name: Run test run: | + echo $GITHUB_TOKEN go test -v ./... From ca1a29fd88b618ceb6f8a355d77bfd4c04590494 Mon Sep 17 00:00:00 2001 From: cohix Date: Mon, 26 Jul 2021 16:24:48 -0400 Subject: [PATCH 7/8] set github token in env --- .github/workflows/sanity.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sanity.yml b/.github/workflows/sanity.yml index 4e09f27a..62074694 100644 --- a/.github/workflows/sanity.yml +++ b/.github/workflows/sanity.yml @@ -33,5 +33,5 @@ jobs: - name: Run test run: | - echo $GITHUB_TOKEN + export GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} go test -v ./... From 1ee15e2ac70fd98e6e199d4ef9c7f07c62dad7b9 Mon Sep 17 00:00:00 2001 From: cohix Date: Tue, 27 Jul 2021 08:57:40 -0400 Subject: [PATCH 8/8] bail on GraphQL tests if github is not authenticated --- rwasm/wasmtest/assemblyscript_test.go | 6 ++++++ rwasm/wasmtest/rust_test.go | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/rwasm/wasmtest/assemblyscript_test.go b/rwasm/wasmtest/assemblyscript_test.go index 7d8be639..1bd27b60 100644 --- a/rwasm/wasmtest/assemblyscript_test.go +++ b/rwasm/wasmtest/assemblyscript_test.go @@ -3,6 +3,7 @@ package wasmtest import ( "encoding/json" "fmt" + "os" "testing" "github.com/google/uuid" @@ -67,6 +68,11 @@ func TestASJSON(t *testing.T) { } func TestASGraphql(t *testing.T) { + // bail out if GitHub auth is not set up (i.e. in Travis) + if _, ok := os.LookupEnv("GITHUB_TOKEN"); !ok { + return + } + r := rt.New() caps := r.DefaultCaps() diff --git a/rwasm/wasmtest/rust_test.go b/rwasm/wasmtest/rust_test.go index e5edc7c5..e6657a33 100644 --- a/rwasm/wasmtest/rust_test.go +++ b/rwasm/wasmtest/rust_test.go @@ -3,6 +3,7 @@ package wasmtest import ( "encoding/json" "fmt" + "os" "testing" "github.com/google/uuid" @@ -35,6 +36,11 @@ func TestWasmRunnerWithFetch(t *testing.T) { } func TestGraphQLRunner(t *testing.T) { + // bail out if GitHub auth is not set up (i.e. in Travis) + if _, ok := os.LookupEnv("GITHUB_TOKEN"); !ok { + return + } + r := rt.New() caps := r.DefaultCaps()