Compare commits

..

71 Commits

Author SHA1 Message Date
Benjamin Eckel
b5db12e667 Merge branch 'main' into symlink-plugin-in-example-files 2023-03-16 09:54:02 -05:00
Benjamin Eckel
c7f533f9c6 chore: update dotnet to 0.4.0 2023-03-15 10:39:13 -05:00
Benjamin Eckel
8d76cf0440 release: 0.3.0 (#281)
Co-authored-by: zach <zach@dylib.so>
2023-03-15 09:42:05 -05:00
zach
d950e9149b chore: update haskell base upper bound (#282) 2023-03-13 20:15:16 -07:00
dependabot[bot]
3e65e067e2 chore(deps-dev): Bump @types/node from 18.14.6 to 18.15.0 in /node (#279)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 18.14.6 to 18.15.0.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=18.14.6&new-version=18.15.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-13 11:23:22 -05:00
dependabot[bot]
88a612ab8c chore(deps-dev): Bump jest from 29.4.3 to 29.5.0 in /node (#280)
Bumps [jest](https://github.com/facebook/jest/tree/HEAD/packages/jest)
from 29.4.3 to 29.5.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/jest/releases">jest's
releases</a>.</em></p>
<blockquote>
<h2>v29.5.0</h2>
<h2>Features</h2>
<ul>
<li><code>[jest-changed-files]</code> Support Sapling (<a
href="https://redirect.github.com/facebook/jest/pull/13941">#13941</a>)</li>
<li><code>[jest-circus, @jest/cli, jest-config]</code> Add feature to
randomize order of tests via CLI flag or through the config file(<a
href="https://redirect.github.com/facebook/jest/pull/12922">#12922</a>)</li>
<li><code>[jest-cli, jest-config, @jest/core, jest-haste-map,
@jest/reporters, jest-runner, jest-runtime, @jest/types]</code> Add
<code>workerThreads</code> configuration option to allow using <a
href="https://nodejs.org/dist/latest/docs/api/worker_threads.html">worker
threads</a> for parallelization (<a
href="https://redirect.github.com/facebook/jest/pull/13939">#13939</a>)</li>
<li><code>[jest-cli]</code> Export <code>yargsOptions</code> (<a
href="https://redirect.github.com/facebook/jest/pull/13970">#13970</a>)</li>
<li><code>[jest-config]</code> Add <code>openHandlesTimeout</code>
option to configure possible open handles warning. (<a
href="https://redirect.github.com/facebook/jest/pull/13875">#13875</a>)</li>
<li><code>[@jest/create-cache-key-function]</code> Allow passing
<code>length</code> argument to <code>createCacheKey()</code> function
and set its default value to <code>16</code> on Windows (<a
href="https://redirect.github.com/facebook/jest/pull/13827">#13827</a>)</li>
<li><code>[jest-message-util]</code> Add support for <a
href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError">AggregateError</a>
(<a
href="https://redirect.github.com/facebook/jest/pull/13946">#13946</a>
&amp; <a
href="https://redirect.github.com/facebook/jest/pull/13947">#13947</a>)</li>
<li><code>[jest-message-util]</code> Add support for <a
href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause">Error
causes</a> in <code>test</code> and <code>it</code> (<a
href="https://redirect.github.com/facebook/jest/pull/13935">#13935</a>
&amp; <a
href="https://redirect.github.com/facebook/jest/pull/13966">#13966</a>)</li>
<li><code>[jest-reporters]</code> Add <code>summaryThreshold</code>
option to summary reporter to allow overriding the internal threshold
that is used to print the summary of all failed tests when the number of
test suites surpasses it (<a
href="https://redirect.github.com/facebook/jest/pull/13895">#13895</a>)</li>
<li><code>[jest-runtime]</code> Expose <code>@sinonjs/fake-timers</code>
async APIs functions <code>advanceTimersByTimeAsync(msToRun)</code>
(<code>tickAsync(msToRun)</code>),
<code>advanceTimersToNextTimerAsync(steps)</code>
(<code>nextAsync</code>), <code>runAllTimersAsync</code>
(<code>runAllAsync</code>), and <code>runOnlyPendingTimersAsync</code>
(<code>runToLastAsync</code>) (<a
href="https://redirect.github.com/facebook/jest/pull/13981">#13981</a>)</li>
<li><code>[jest-runtime, @jest/transform]</code> Allow V8 coverage
provider to collect coverage from files which were not loaded explicitly
(<a
href="https://redirect.github.com/facebook/jest/pull/13974">#13974</a>)</li>
<li><code>[jest-snapshot]</code> Add support to <code>cts</code> and
<code>mts</code> TypeScript files to inline snapshots (<a
href="https://redirect.github.com/facebook/jest/pull/13975">#13975</a>)</li>
<li><code>[jest-worker]</code> Add <code>start</code> method to worker
farms (<a
href="https://redirect.github.com/facebook/jest/pull/13937">#13937</a>)</li>
<li><code>[jest-worker]</code> Support passing a URL as path to worker
(<a
href="https://redirect.github.com/facebook/jest/pull/13982">#13982</a>)</li>
</ul>
<h2>Fixes</h2>
<ul>
<li><code>[babel-plugin-jest-hoist]</code> Fix unwanted hoisting of
nested <code>jest</code> usages (<a
href="https://redirect.github.com/facebook/jest/pull/13952">#13952</a>)</li>
<li><code>[jest-circus]</code> Send test case results for
<code>todo</code> tests (<a
href="https://redirect.github.com/facebook/jest/pull/13915">#13915</a>)</li>
<li><code>[jest-circus]</code> Update message printed on test timeout
(<a
href="https://redirect.github.com/facebook/jest/pull/13830">#13830</a>)</li>
<li><code>[jest-circus]</code> Avoid creating the word
&quot;testfalse&quot; when <code>takesDoneCallback</code> is
<code>false</code> in the message printed on test timeout AND updated
timeouts test (<a
href="https://redirect.github.com/facebook/jest/pull/13954">#13954</a>)</li>
<li><code>[jest-environment-jsdom]</code> Stop setting
<code>document</code> to <code>null</code> on teardown (<a
href="https://redirect.github.com/facebook/jest/pull/13972">#13972</a>)</li>
<li><code>[@jest/expect-utils]</code> Update
<code>toStrictEqual()</code> to be able to check
<code>jest.fn().mock.calls</code> (<a
href="https://redirect.github.com/facebook/jest/pull/13960">#13960</a>)</li>
<li><code>[@jest/test-result]</code> Allow
<code>TestResultsProcessor</code> type to return a Promise (<a
href="https://redirect.github.com/facebook/jest/pull/13950">#13950</a>)</li>
</ul>
<h2>Chore &amp; Maintenance</h2>
<ul>
<li><code>[jest-snapshot]</code> Remove dependency on
<code>jest-haste-map</code> (<a
href="https://redirect.github.com/facebook/jest/pull/13977">#13977</a>)</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/frosas"><code>@​frosas</code></a> made
their first contribution in <a
href="https://redirect.github.com/facebook/jest/pull/13932">facebook/jest#13932</a></li>
<li><a
href="https://github.com/akshitsinha"><code>@​akshitsinha</code></a>
made their first contribution in <a
href="https://redirect.github.com/facebook/jest/pull/13915">facebook/jest#13915</a></li>
<li><a href="https://github.com/trajano"><code>@​trajano</code></a> made
their first contribution in <a
href="https://redirect.github.com/facebook/jest/pull/13827">facebook/jest#13827</a></li>
<li><a
href="https://github.com/DercilioFontes"><code>@​DercilioFontes</code></a>
made their first contribution in <a
href="https://redirect.github.com/facebook/jest/pull/13954">facebook/jest#13954</a></li>
<li><a href="https://github.com/jsnajdr"><code>@​jsnajdr</code></a> made
their first contribution in <a
href="https://redirect.github.com/facebook/jest/pull/13952">facebook/jest#13952</a></li>
<li><a
href="https://github.com/SteveFlames"><code>@​SteveFlames</code></a>
made their first contribution in <a
href="https://redirect.github.com/facebook/jest/pull/13895">facebook/jest#13895</a></li>
<li><a href="https://github.com/willc001"><code>@​willc001</code></a>
made their first contribution in <a
href="https://redirect.github.com/facebook/jest/pull/13970">facebook/jest#13970</a></li>
<li><a
href="https://github.com/benjaminhobbs"><code>@​benjaminhobbs</code></a>
made their first contribution in <a
href="https://redirect.github.com/facebook/jest/pull/13901">facebook/jest#13901</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/facebook/jest/compare/v29.4.3...v29.5.0">https://github.com/facebook/jest/compare/v29.4.3...v29.5.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/jest/blob/main/CHANGELOG.md">jest's
changelog</a>.</em></p>
<blockquote>
<h2>29.5.0</h2>
<h3>Features</h3>
<ul>
<li><code>[jest-changed-files]</code> Support Sapling (<a
href="https://redirect.github.com/facebook/jest/pull/13941">#13941</a>)</li>
<li><code>[jest-circus, @jest/cli, jest-config]</code> Add feature to
randomize order of tests via CLI flag or through the config file(<a
href="https://redirect.github.com/facebook/jest/pull/12922">#12922</a>)</li>
<li><code>[jest-cli, jest-config, @jest/core, jest-haste-map,
@jest/reporters, jest-runner, jest-runtime, @jest/types]</code> Add
<code>workerThreads</code> configuration option to allow using <a
href="https://nodejs.org/dist/latest/docs/api/worker_threads.html">worker
threads</a> for parallelization (<a
href="https://redirect.github.com/facebook/jest/pull/13939">#13939</a>)</li>
<li><code>[jest-cli]</code> Export <code>yargsOptions</code> (<a
href="https://redirect.github.com/facebook/jest/pull/13970">#13970</a>)</li>
<li><code>[jest-config]</code> Add <code>openHandlesTimeout</code>
option to configure possible open handles warning. (<a
href="https://redirect.github.com/facebook/jest/pull/13875">#13875</a>)</li>
<li><code>[@jest/create-cache-key-function]</code> Allow passing
<code>length</code> argument to <code>createCacheKey()</code> function
and set its default value to <code>16</code> on Windows (<a
href="https://redirect.github.com/facebook/jest/pull/13827">#13827</a>)</li>
<li><code>[jest-message-util]</code> Add support for <a
href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError">AggregateError</a>
(<a
href="https://redirect.github.com/facebook/jest/pull/13946">#13946</a>
&amp; <a
href="https://redirect.github.com/facebook/jest/pull/13947">#13947</a>)</li>
<li><code>[jest-message-util]</code> Add support for <a
href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause">Error
causes</a> in <code>test</code> and <code>it</code> (<a
href="https://redirect.github.com/facebook/jest/pull/13935">#13935</a>
&amp; <a
href="https://redirect.github.com/facebook/jest/pull/13966">#13966</a>)</li>
<li><code>[jest-reporters]</code> Add <code>summaryThreshold</code>
option to summary reporter to allow overriding the internal threshold
that is used to print the summary of all failed tests when the number of
test suites surpasses it (<a
href="https://redirect.github.com/facebook/jest/pull/13895">#13895</a>)</li>
<li><code>[jest-runtime]</code> Expose <code>@sinonjs/fake-timers</code>
async APIs functions <code>advanceTimersByTimeAsync(msToRun)</code>
(<code>tickAsync(msToRun)</code>),
<code>advanceTimersToNextTimerAsync(steps)</code>
(<code>nextAsync</code>), <code>runAllTimersAsync</code>
(<code>runAllAsync</code>), and <code>runOnlyPendingTimersAsync</code>
(<code>runToLastAsync</code>) (<a
href="https://redirect.github.com/facebook/jest/pull/13981">#13981</a>)</li>
<li><code>[jest-runtime, @jest/transform]</code> Allow V8 coverage
provider to collect coverage from files which were not loaded explicitly
(<a
href="https://redirect.github.com/facebook/jest/pull/13974">#13974</a>)</li>
<li><code>[jest-snapshot]</code> Add support to <code>cts</code> and
<code>mts</code> TypeScript files to inline snapshots (<a
href="https://redirect.github.com/facebook/jest/pull/13975">#13975</a>)</li>
<li><code>[jest-worker]</code> Add <code>start</code> method to worker
farms (<a
href="https://redirect.github.com/facebook/jest/pull/13937">#13937</a>)</li>
<li><code>[jest-worker]</code> Support passing a URL as path to worker
(<a
href="https://redirect.github.com/facebook/jest/pull/13982">#13982</a>)</li>
</ul>
<h3>Fixes</h3>
<ul>
<li><code>[babel-plugin-jest-hoist]</code> Fix unwanted hoisting of
nested <code>jest</code> usages (<a
href="https://redirect.github.com/facebook/jest/pull/13952">#13952</a>)</li>
<li><code>[jest-circus]</code> Send test case results for
<code>todo</code> tests (<a
href="https://redirect.github.com/facebook/jest/pull/13915">#13915</a>)</li>
<li><code>[jest-circus]</code> Update message printed on test timeout
(<a
href="https://redirect.github.com/facebook/jest/pull/13830">#13830</a>)</li>
<li><code>[jest-circus]</code> Avoid creating the word
&quot;testfalse&quot; when <code>takesDoneCallback</code> is
<code>false</code> in the message printed on test timeout AND updated
timeouts test (<a
href="https://redirect.github.com/facebook/jest/pull/13954">#13954</a>)</li>
<li><code>[jest-environment-jsdom]</code> Stop setting
<code>document</code> to <code>null</code> on teardown (<a
href="https://redirect.github.com/facebook/jest/pull/13972">#13972</a>)</li>
<li><code>[@jest/expect-utils]</code> Update
<code>toStrictEqual()</code> to be able to check
<code>jest.fn().mock.calls</code> (<a
href="https://redirect.github.com/facebook/jest/pull/13960">#13960</a>)</li>
<li><code>[@jest/test-result]</code> Allow
<code>TestResultsProcessor</code> type to return a Promise (<a
href="https://redirect.github.com/facebook/jest/pull/13950">#13950</a>)</li>
</ul>
<h3>Chore &amp; Maintenance</h3>
<ul>
<li><code>[jest-snapshot]</code> Remove dependency on
<code>jest-haste-map</code> (<a
href="https://redirect.github.com/facebook/jest/pull/13977">#13977</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="39f3beda6b"><code>39f3bed</code></a>
v29.5.0</li>
<li>See full diff in <a
href="https://github.com/facebook/jest/commits/v29.5.0/packages/jest">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=jest&package-manager=npm_and_yarn&previous-version=29.4.3&new-version=29.5.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-13 11:23:10 -05:00
Mathieu ANCELIN
3fc51ac373 feat: Support allowed_paths in the Java SDK (#277) 2023-03-11 11:30:26 -07:00
zach
12373ca34a chore: update to wasmtime 6.0.1 (#276) 2023-03-08 17:44:57 -08:00
zach
94d5bd98c8 feat: Add plugin cancellation (#270)
This PR adds the ability to cancel running plugins from another thread
in the host.

- All SDKs have been updated except  .NET
- Adds a new SDK type: `ExtismCancelHandle`
- Adds 2 new SDK functions: `extism_plugin_cancel_handle` and
`extism_plugin_cancel`
- `extism_plugin_cancel_handle` returns a pointer to
`ExtismCancelHandle`, which can be passed to `extism_plugin_cancel` to
stop plugin execution.
- One thing that's worth noting is when plugin is executing a host
function it cannot be cancelled until after the host function returns.

---------

Co-authored-by: Etienne ANNE <etienne.anne@icloud.com>
2023-03-08 17:44:40 -08:00
Etienne ANNE
2922f4aad3 feat: add ability to set host function namespace for Java SDK (#275) 2023-03-08 17:13:43 -08:00
dependabot[bot]
a39381f552 chore(deps-dev): Update minitest requirement from ~> 5.17.0 to ~> 5.18.0 in /ruby (#271)
Updates the requirements on
[minitest](https://github.com/seattlerb/minitest) to permit the latest
version.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/minitest/minitest/blob/master/History.rdoc">minitest's
changelog</a>.</em></p>
<blockquote>
<p>=== 5.18.0 / 2023-03-04</p>
<ul>
<li>
<p>2 major enhancements:</p>
<ul>
<li>Added assert_pattern &amp; refute_pattern for pattern matching.
(flavorjones)</li>
<li>Added matching must_pattern_match &amp; wont_pattern_match to
minitest/spec.</li>
</ul>
</li>
<li>
<p>1 bug fix:</p>
<ul>
<li>Support the new message format of NameError in Ruby 3.3 (mame)</li>
</ul>
</li>
</ul>
<p>=== 5.17.0 / 2022-12-31</p>
<ul>
<li>
<p>1 minor enhancement:</p>
<ul>
<li>Refactor setup hooks into a SETUP_METHODS constant. (MSP-Greg)</li>
</ul>
</li>
<li>
<p>3 bug fixes:</p>
<ul>
<li>Fix kwargs for Mock calls to delegator. (blowmage)</li>
<li>Fix kwargs for expectations. (bobmazanec, blowmage)</li>
<li>Remove check for .b method. (tenderlove)</li>
</ul>
</li>
</ul>
<p>=== 5.16.3 / 2022-08-17</p>
<ul>
<li>
<p>2 bug fixes:</p>
<ul>
<li>Fixed exception sanitization by removing TypeError restriction on
rescue.</li>
<li>Use A instead of deprecated TESTOPTS in rake test:slow.
(davidstosik)</li>
</ul>
</li>
</ul>
<p>=== 5.16.2 / 2022-07-03</p>
<ul>
<li>
<p>4 bug fixes:</p>
<ul>
<li>Added MT_KWARGS_HACK kludge for stub to deal with ruby 2.7 kwargs
nastiness. (tsugimoto)</li>
<li>In #expect, pop Hash class from args if $MT_KWARGS_HACK.
(casperisfine)</li>
<li>In above scenario, set expected kwargs (as Objects) based on actual
kwargs.</li>
<li>Nuke ivars if exception fails to marshal twice (eg better_errors).
(irphilli)</li>
</ul>
</li>
</ul>
<p>=== 5.16.1 / 2022-06-20</p>
<ul>
<li>
<p>2 bug fixes:</p>
<ul>
<li>Apparently adding real kwarg support to mocks/stubs broke some code.
Fixed.
<ul>
<li>Use <code>MT_KWARGS_HACK=1</code> to activate the kludgy kwargs
support w/ caveats.</li>
</ul>
</li>
<li>Clarified some doco wrt the block on #stub.</li>
</ul>
</li>
</ul>
<p>=== 5.16.0 / 2022-06-14</p>
<ul>
<li>2 major enhancements:</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="506ce83b45"><code>506ce83</code></a>
prepped for release</li>
<li><a
href="0c44f4ea32"><code>0c44f4e</code></a>
! Added assert_pattern &amp; refute_pattern for pattern matching.
(flavorjones)</li>
<li><a
href="899b420aa0"><code>899b420</code></a>
Fixed typo in doco. (ahangarha)</li>
<li><a
href="ebd8a673a1"><code>ebd8a67</code></a>
- Support the new message format of NameError in Ruby 3.3 (mame)</li>
<li><a
href="0984e29995"><code>0984e29</code></a>
Add 2.6 to matrix... stays until some rails versions expire, sadly.</li>
<li><a
href="d5e68e6ef4"><code>d5e68e6</code></a>
Adds Ruby 3.2 to the CI matrix. Also updates checkout action version.
(peterg...</li>
<li><a
href="69bc4b0f5b"><code>69bc4b0</code></a>
Minor tweak to Rakefile to fix CI on older rubies</li>
<li>See full diff in <a
href="https://github.com/seattlerb/minitest/compare/v5.17.0...v5.18.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-05 22:33:24 -06:00
dependabot[bot]
71cbbb02bb chore(deps-dev): Bump @types/node from 18.14.2 to 18.14.6 in /node (#272)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 18.14.2 to 18.14.6.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=18.14.2&new-version=18.14.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-05 22:33:14 -06:00
dependabot[bot]
bb1a92d3f9 chore(deps-dev): Bump ex_doc from 0.29.1 to 0.29.2 in /elixir (#273)
Bumps [ex_doc](https://github.com/elixir-lang/ex_doc) from 0.29.1 to
0.29.2.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/elixir-lang/ex_doc/blob/main/CHANGELOG.md">ex_doc's
changelog</a>.</em></p>
<blockquote>
<h2>v0.29.2 (2023-03-02)</h2>
<ul>
<li>
<p>Enhancements</p>
<ul>
<li>Improvements to cheatsheets spacing</li>
<li>Improvements to cheatsheets print</li>
<li>Include sections of modules and extras in search suggestions</li>
<li>Make sidebar links full-width and add hover states</li>
<li>Improve clickable area of sidebar tabs</li>
<li>Improve contrast on sidebar</li>
</ul>
</li>
<li>
<p>Bug fix</p>
<ul>
<li>Add media type for .license files for epub</li>
<li>Fix overscroll on the sidebar</li>
<li>Focus search input immediately after keyboard shortcut</li>
<li>Don't attempt parsing code blocks that don't look like modules</li>
<li>Fix visited link color in admonition blocks</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="0e2d7686ee"><code>0e2d768</code></a>
Release v0.29.2</li>
<li><a
href="adcea58ca0"><code>adcea58</code></a>
Increase contrast on sidebar</li>
<li><a
href="fa5dff69e3"><code>fa5dff6</code></a>
Fix visited link color in admonition blocks (<a
href="https://github-redirect.dependabot.com/elixir-lang/ex_doc/issues/1666">#1666</a>)</li>
<li><a
href="1a11987ce6"><code>1a11987</code></a>
Update Cheatsheet print styles (<a
href="https://github-redirect.dependabot.com/elixir-lang/ex_doc/issues/1665">#1665</a>)</li>
<li><a
href="d00110fc45"><code>d00110f</code></a>
Don't attempt parsing code blocks that don't look like modules (<a
href="https://github-redirect.dependabot.com/elixir-lang/ex_doc/issues/1662">#1662</a>)</li>
<li><a
href="486dce49c4"><code>486dce4</code></a>
Do not use tests that modify app env concurrently</li>
<li><a
href="400f088d08"><code>400f088</code></a>
Remove superfluous import of common custom properties from Erlang CSS
(<a
href="https://github-redirect.dependabot.com/elixir-lang/ex_doc/issues/1660">#1660</a>)</li>
<li><a
href="5350bc5cdb"><code>5350bc5</code></a>
Fix extra spacing on pages with no sections</li>
<li><a
href="5331a4ba48"><code>5331a4b</code></a>
Tweak cheatsheet CSS (<a
href="https://github-redirect.dependabot.com/elixir-lang/ex_doc/issues/1658">#1658</a>)</li>
<li><a
href="2d14453b23"><code>2d14453</code></a>
Update print page break-related declarations (<a
href="https://github-redirect.dependabot.com/elixir-lang/ex_doc/issues/1657">#1657</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/elixir-lang/ex_doc/compare/v0.29.1...v0.29.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ex_doc&package-manager=hex&previous-version=0.29.1&new-version=0.29.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-05 22:33:03 -06:00
dependabot[bot]
5d91870db6 chore(deps-dev): Bump typedoc from 0.23.25 to 0.23.26 in /node (#265)
Bumps [typedoc](https://github.com/TypeStrong/TypeDoc) from 0.23.25 to
0.23.26.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/TypeStrong/TypeDoc/releases">typedoc's
releases</a>.</em></p>
<blockquote>
<h2>v0.23.26</h2>
<h3>Features</h3>
<ul>
<li>Added <code>Application.EVENT_VALIDATE_PROJECT</code> event for
plugins which implement custom validation, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2183">#2183</a>.</li>
<li>Plugins may now return an object from external symbol resolvers, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2066">#2066</a>.</li>
<li>Expose <code>Comment.displayPartsToMarkdown</code> on for themes
overwriting the <code>comment</code> helper, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2115">#2115</a>.</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>Fix crash when converting <code>export default undefined</code>, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2175">#2175</a>.</li>
<li>Fix error in console when clicking on headings in the readme, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2170">#2170</a>.</li>
<li>TypeDoc will now ignore parameters of callback parameters when
validating that all parameters have documentation, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2154">#2154</a>.</li>
</ul>
<h3>Thanks!</h3>
<ul>
<li><a
href="https://github.com/captain-torch"><code>@​captain-torch</code></a></li>
<li><a
href="https://github.com/loopingz"><code>@​loopingz</code></a></li>
<li><a
href="https://github.com/RebeccaStevens"><code>@​RebeccaStevens</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/TypeStrong/typedoc/blob/master/CHANGELOG.md">typedoc's
changelog</a>.</em></p>
<blockquote>
<h2>v0.23.26 (2023-02-26)</h2>
<h3>Features</h3>
<ul>
<li>Added <code>Application.EVENT_VALIDATE_PROJECT</code> event for
plugins which implement custom validation, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2183">#2183</a>.</li>
<li>Plugins may now return an object from external symbol resolvers, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2066">#2066</a>.</li>
<li>Expose <code>Comment.displayPartsToMarkdown</code> on for themes
overwriting the <code>comment</code> helper, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2115">#2115</a>.</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>Fix crash when converting <code>export default undefined</code>, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2175">#2175</a>.</li>
<li>Fix error in console when clicking on headings in the readme, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2170">#2170</a>.</li>
<li>TypeDoc will now ignore parameters of callback parameters when
validating that all parameters have documentation, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2154">#2154</a>.</li>
</ul>
<h3>Thanks!</h3>
<ul>
<li><a
href="https://github.com/captain-torch"><code>@​captain-torch</code></a></li>
<li><a
href="https://github.com/loopingz"><code>@​loopingz</code></a></li>
<li><a
href="https://github.com/RebeccaStevens"><code>@​RebeccaStevens</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c75f44f115"><code>c75f44f</code></a>
Update changelog for release</li>
<li><a
href="67355f273b"><code>67355f2</code></a>
Bump version to 0.23.26</li>
<li><a
href="86da0f3448"><code>86da0f3</code></a>
Fix lint</li>
<li><a
href="54c86d8fd9"><code>54c86d8</code></a>
Expose displayPartsToMarkdown</li>
<li><a
href="37fe88302e"><code>37fe883</code></a>
Ignore parameters of parameters</li>
<li><a
href="0a52e7452c"><code>0a52e74</code></a>
Fix <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2170">#2170</a></li>
<li><a
href="7a48a172ff"><code>7a48a17</code></a>
Document additional changes</li>
<li><a
href="3343cc44d2"><code>3343cc4</code></a>
Fix crash when converting undefined default export</li>
<li><a
href="6ee136acbf"><code>6ee136a</code></a>
feat: add validator run event to allow plugins to perform custom
validation (...</li>
<li><a
href="1d4922ca0b"><code>1d4922c</code></a>
Update minimatch to avoid type hackery</li>
<li>Additional commits viewable in <a
href="https://github.com/TypeStrong/TypeDoc/compare/v0.23.25...v0.23.26">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=typedoc&package-manager=npm_and_yarn&previous-version=0.23.25&new-version=0.23.26)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-03 14:05:35 -06:00
dependabot[bot]
9d6e36b8cb chore(deps-dev): Bump @types/node from 18.14.0 to 18.14.2 in /node (#266)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 18.14.0 to 18.14.2.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=18.14.0&new-version=18.14.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-03 14:05:27 -06:00
zach
4b2f7d2bff fix(zig): use new for loop syntax (#269) 2023-03-03 11:15:36 -08:00
Etienne ANNE
3e69ceeede feat: Add Host Functions support for Java SDK (#248) 2023-03-02 15:46:13 -06:00
Steve Manuel
581e9cea99 chore: update wasmtime to 6.0, bump extism versions (#247)
Unsure if now is the best time to do the `extism` crate version bumps,
but I figured they'd need to happen at some point in the near future
anyways. Happy to revert if there is any opposition. Also, I added back
the local `path` property to the Elixir NIF crate manifest. I want to
see if this breaks again in CI, or if we can leave it.

---------

Co-authored-by: zach <zach@dylib.so>
2023-03-01 15:24:37 -08:00
zach
48979b9f6d fix(python): export CurrentPlugin (#263) 2023-02-22 14:46:56 -08:00
dependabot[bot]
6ead4d9cd2 chore(deps-dev): Bump jest from 29.4.2 to 29.4.3 in /node (#261)
Bumps [jest](https://github.com/facebook/jest/tree/HEAD/packages/jest)
from 29.4.2 to 29.4.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/jest/releases">jest's
releases</a>.</em></p>
<blockquote>
<h2>v29.4.3</h2>
<h2>Features</h2>
<ul>
<li><code>[expect]</code> Update <code>toThrow()</code> to be able to
use error <code>cause</code>s (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13606">#13606</a>)</li>
<li><code>[jest-core]</code> allow to use
<code>workerIdleMemoryLimit</code> with only 1 worker or
<code>runInBand</code> option (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13846">#13846</a>)</li>
<li><code>[jest-message-util]</code> Add support for <a
href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause">error
<code>cause</code>s</a> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13868">#13868</a>
&amp; <a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13912">#13912</a>)</li>
<li><code>[jest-runtime]</code> Revert <code>import assertions</code>
for JSON modules as it's been relegated to Stage 2 (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13911">#13911</a>)</li>
</ul>
<h2>Fixes</h2>
<ul>
<li><code>[@jest/expect-utils]</code> <code>subsetEquality</code> should
consider also an object's inherited string keys (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13824">#13824</a>)</li>
<li><code>[jest-mock]</code> Clear mock state when
<code>jest.restoreAllMocks()</code> is called (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13867">#13867</a>)</li>
<li><code>[jest-mock]</code> Prevent <code>mockImplementationOnce</code>
and <code>mockReturnValueOnce</code> bleeding into
<code>withImplementation</code> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13888">#13888</a>)</li>
<li><code>[jest-mock]</code> Do not restore mocks when
<code>jest.resetAllMocks()</code> is called (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13866">#13866</a>)</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/brodo"><code>@​brodo</code></a> made
their first contribution in <a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13868">facebook/jest#13868</a></li>
<li><a
href="https://github.com/DannyNemer"><code>@​DannyNemer</code></a> made
their first contribution in <a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13878">facebook/jest#13878</a></li>
<li><a href="https://github.com/ghusse"><code>@​ghusse</code></a> made
their first contribution in <a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13846">facebook/jest#13846</a></li>
<li><a href="https://github.com/broofa"><code>@​broofa</code></a> made
their first contribution in <a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13911">facebook/jest#13911</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/facebook/jest/compare/v29.4.2...v29.4.3">https://github.com/facebook/jest/compare/v29.4.2...v29.4.3</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/jest/blob/main/CHANGELOG.md">jest's
changelog</a>.</em></p>
<blockquote>
<h2>29.4.3</h2>
<h3>Features</h3>
<ul>
<li><code>[expect]</code> Update <code>toThrow()</code> to be able to
use error <code>cause</code>s (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13606">#13606</a>)</li>
<li><code>[jest-core]</code> allow to use
<code>workerIdleMemoryLimit</code> with only 1 worker or
<code>runInBand</code> option (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13846">#13846</a>)</li>
<li><code>[jest-message-util]</code> Add support for <a
href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause">error
<code>cause</code>s</a> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13868">#13868</a>
&amp; <a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13912">#13912</a>)</li>
<li><code>[jest-runtime]</code> Revert <code>import assertions</code>
for JSON modules as it's been relegated to Stage 2 (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13911">#13911</a>)</li>
</ul>
<h3>Fixes</h3>
<ul>
<li><code>[@jest/expect-utils]</code> <code>subsetEquality</code> should
consider also an object's inherited string keys (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13824">#13824</a>)</li>
<li><code>[jest-mock]</code> Clear mock state when
<code>jest.restoreAllMocks()</code> is called (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13867">#13867</a>)</li>
<li><code>[jest-mock]</code> Prevent <code>mockImplementationOnce</code>
and <code>mockReturnValueOnce</code> bleeding into
<code>withImplementation</code> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13888">#13888</a>)</li>
<li><code>[jest-mock]</code> Do not restore mocks when
<code>jest.resetAllMocks()</code> is called (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13866">#13866</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="a49c88610e"><code>a49c886</code></a>
v29.4.3</li>
<li><a
href="6d2632adae"><code>6d2632a</code></a>
Update copyrights with Meta Platforms, restore original license in
Jasmine fo...</li>
<li>See full diff in <a
href="https://github.com/facebook/jest/commits/v29.4.3/packages/jest">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=jest&package-manager=npm_and_yarn&previous-version=29.4.2&new-version=29.4.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-22 15:11:02 -06:00
dependabot[bot]
08e708bac5 chore(deps-dev): Bump @types/node from 18.13.0 to 18.14.0 in /node (#262)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 18.13.0 to 18.14.0.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=18.13.0&new-version=18.14.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-22 15:10:53 -06:00
Doğu Us
602ca04f11 fix(zig-sdk): Fix Example And Test (#260) 2023-02-17 09:27:42 -07:00
dependabot[bot]
8135952842 chore(deps-dev): Bump prettier from 2.8.3 to 2.8.4 in /node (#259)
Bumps [prettier](https://github.com/prettier/prettier) from 2.8.3 to
2.8.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/prettier/prettier/releases">prettier's
releases</a>.</em></p>
<blockquote>
<h2>2.8.4</h2>
<p>🔗 <a
href="https://github.com/prettier/prettier/blob/main/CHANGELOG.md#284">Changelog</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/prettier/prettier/blob/main/CHANGELOG.md">prettier's
changelog</a>.</em></p>
<blockquote>
<h1>2.8.4</h1>
<p><a
href="https://github.com/prettier/prettier/compare/2.8.3...2.8.4">diff</a></p>
<h4>Fix leading comments in mapped types with <code>readonly</code> (<a
href="https://github-redirect.dependabot.com/prettier/prettier/pull/13427">#13427</a>
by <a href="https://github.com/thorn0"><code>@​thorn0</code></a>, <a
href="https://github.com/sosukesuzuki"><code>@​sosukesuzuki</code></a>)</h4>
<!-- raw HTML omitted -->
<pre lang="tsx"><code>// Input
type Type = {
  // comment
  readonly [key in Foo];
};
<p>// Prettier 2.8.3
type Type = {
readonly // comment
[key in Foo];
};</p>
<p>// Prettier 2.8.4
type Type = {
// comment
readonly [key in Foo];
};
</code></pre></p>
<h4>Group params in opening block statements (<a
href="https://github-redirect.dependabot.com/prettier/prettier/pull/14067">#14067</a>
by <a
href="https://github.com/jamescdavis"><code>@​jamescdavis</code></a>)</h4>
<p>This is a follow-up to <a
href="https://github-redirect.dependabot.com/prettier/prettier/issues/13930">#13930</a>
to establish wrapping consistency between opening block statements and
else blocks by
grouping params in opening blocks. This causes params to break to a new
line together and not be split across lines
unless the length of params exceeds the print width. This also updates
the else block wrapping to behave exactly the
same as opening blocks.</p>
<!-- raw HTML omitted -->
<pre lang="hbs"><code>{{! Input }}
{{#block param param param param param param param param param param as
|blockParam|}}
  Hello
{{else block param param param param param param param param param param
as |blockParam|}}
  There
{{/block}}
<p>{{! Prettier 2.8.3 }}
{{#block
param
param
param
param
param
&lt;/tr&gt;&lt;/table&gt;
</code></pre></p>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="e681edb67c"><code>e681edb</code></a>
Release 2.8.4</li>
<li><a
href="6bb24b2c5a"><code>6bb24b2</code></a>
Fix leading comments in mapped types with <code>readonly</code>
(Cherry-pick <a
href="https://github-redirect.dependabot.com/prettier/prettier/issues/13427">#13427</a>)
(<a
href="https://github-redirect.dependabot.com/prettier/prettier/issues/1">#1</a>...</li>
<li><a
href="399f2fae40"><code>399f2fa</code></a>
Add changelog for <a
href="https://github-redirect.dependabot.com/prettier/prettier/issues/14206">#14206</a>
(<a
href="https://github-redirect.dependabot.com/prettier/prettier/issues/14311">#14311</a>)</li>
<li><a
href="9842b29ca3"><code>9842b29</code></a>
Recognize <code>@satisfies</code> in Closure-style type casts (<a
href="https://github-redirect.dependabot.com/prettier/prettier/issues/14262">#14262</a>)</li>
<li><a
href="bc18fa4397"><code>bc18fa4</code></a>
Fix incorrect removal of parentheses when using an <code>infer</code>
with a constraint ...</li>
<li><a
href="f602be5a47"><code>f602be5</code></a>
Update <code>embeddedLanguageFormatting</code> option documentation (<a
href="https://github-redirect.dependabot.com/prettier/prettier/issues/14048">#14048</a>)</li>
<li><a
href="37fb53acf3"><code>37fb53a</code></a>
[handlebars] group params in opening block statements (<a
href="https://github-redirect.dependabot.com/prettier/prettier/issues/14067">#14067</a>)</li>
<li><a
href="310a5b1ba5"><code>310a5b1</code></a>
Handlebars: Improve HTML void element check (<a
href="https://github-redirect.dependabot.com/prettier/prettier/issues/14110">#14110</a>)</li>
<li><a
href="62195dd1f2"><code>62195dd</code></a>
Add .sl to the list of silentlyIgnoredDirs (<a
href="https://github-redirect.dependabot.com/prettier/prettier/issues/14206">#14206</a>)</li>
<li><a
href="bf406f7728"><code>bf406f7</code></a>
Clean changelog</li>
<li>Additional commits viewable in <a
href="https://github.com/prettier/prettier/compare/2.8.3...2.8.4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=prettier&package-manager=npm_and_yarn&previous-version=2.8.3&new-version=2.8.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-16 10:24:23 -06:00
dependabot[bot]
041e0c7b4f chore(deps-dev): Bump @types/node from 18.11.19 to 18.13.0 in /node (#258)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 18.11.19 to 18.13.0.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=18.11.19&new-version=18.13.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-16 10:24:14 -06:00
dependabot[bot]
a1ebfb7597 chore(deps-dev): Bump typedoc from 0.23.24 to 0.23.25 in /node (#257)
Bumps [typedoc](https://github.com/TypeStrong/TypeDoc) from 0.23.24 to
0.23.25.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/TypeStrong/TypeDoc/releases">typedoc's
releases</a>.</em></p>
<blockquote>
<h2>v0.23.25</h2>
<h3>Breaking Changes</h3>
<ul>
<li>Upgraded Shiki, if your highlight theme was set to
<code>material-&lt;theme&gt;</code>, the value will need to be changed
to
<code>material-theme-&lt;theme&gt;</code>, see the <a
href="https://github.com/shikijs/shiki/blob/main/CHANGELOG.md#0130--2023-01-27">Shiki
release notes</a>.</li>
</ul>
<h3>Features</h3>
<ul>
<li>Added new <code>excludeNotDocumentedKinds</code> variable to control
which reflection types can be removed
by the <code>excludeNotDocumented</code> option, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2162">#2162</a>.</li>
<li>Added <code>typedoc.jsonc</code>, <code>typedoc.config.js</code>,
<code>typedoc.config.cjs</code>, <code>typedoc.cjs</code> to the list of
files
which TypeDoc will automatically use as configuration files.</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>Entry points under <code>node_modules</code> will no longer be
ignored, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2151">#2151</a>.</li>
<li>Corrected behavior of <code>excludeNotDocumented</code> on arrow
function-variables, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2156">#2156</a>.</li>
<li>Added <code>package.json</code> to exports declaration.</li>
</ul>
<h3>Thanks!</h3>
<ul>
<li><a
href="https://github.com/boneskull"><code>@​boneskull</code></a></li>
<li><a
href="https://github.com/Mikkal24"><code>@​Mikkal24</code></a></li>
<li><a href="https://github.com/zamiell"><code>@​zamiell</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/TypeStrong/typedoc/blob/master/CHANGELOG.md">typedoc's
changelog</a>.</em></p>
<blockquote>
<h2>v0.23.25 (2023-02-11)</h2>
<h3>Breaking Changes</h3>
<ul>
<li>Upgraded Shiki, if your highlight theme was set to
<code>material-&lt;theme&gt;</code>, the value will need to be changed
to
<code>material-theme-&lt;theme&gt;</code>, see the <a
href="https://github.com/shikijs/shiki/blob/main/CHANGELOG.md#0130--2023-01-27">Shiki
release notes</a>.</li>
</ul>
<h3>Features</h3>
<ul>
<li>Added new <code>excludeNotDocumentedKinds</code> variable to control
which reflection types can be removed
by the <code>excludeNotDocumented</code> option, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2162">#2162</a>.</li>
<li>Added <code>typedoc.jsonc</code>, <code>typedoc.config.js</code>,
<code>typedoc.config.cjs</code>, <code>typedoc.cjs</code> to the list of
files
which TypeDoc will automatically use as configuration files.</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>Entry points under <code>node_modules</code> will no longer be
ignored, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2151">#2151</a>.</li>
<li>Corrected behavior of <code>excludeNotDocumented</code> on arrow
function-variables, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2156">#2156</a>.</li>
<li>Added <code>package.json</code> to exports declaration.</li>
</ul>
<h3>Thanks!</h3>
<ul>
<li><a
href="https://github.com/boneskull"><code>@​boneskull</code></a></li>
<li><a
href="https://github.com/Mikkal24"><code>@​Mikkal24</code></a></li>
<li><a href="https://github.com/zamiell"><code>@​zamiell</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c565bc618e"><code>c565bc6</code></a>
Update changelog for release</li>
<li><a
href="c189157797"><code>c189157</code></a>
Bump version to 0.23.25</li>
<li><a
href="772fd7f1b9"><code>772fd7f</code></a>
Fix type error</li>
<li><a
href="ca5d5e655a"><code>ca5d5e6</code></a>
Fix excludeNotDocumented on arrow functions</li>
<li><a
href="f838e112bf"><code>f838e11</code></a>
Revert bad test change</li>
<li><a
href="f6ea91e275"><code>f6ea91e</code></a>
esbuild breaking changes</li>
<li><a
href="e021751e5f"><code>e021751</code></a>
Upgrade dependencies</li>
<li><a
href="138a52b678"><code>138a52b</code></a>
Add excludeNotDocumentedKinds option</li>
<li><a
href="d82c01b0a4"><code>d82c01b</code></a>
feat: better config file defaults (<a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2168">#2168</a>)</li>
<li><a
href="2953f9c521"><code>2953f9c</code></a>
Merge pull request <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2164">#2164</a>
from boneskull/boneskull/issue2151</li>
<li>Additional commits viewable in <a
href="https://github.com/TypeStrong/TypeDoc/compare/v0.23.24...v0.23.25">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=typedoc&package-manager=npm_and_yarn&previous-version=0.23.24&new-version=0.23.25)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-16 10:24:04 -06:00
dependabot[bot]
1eaa7854d7 chore(deps-dev): Bump jest from 29.4.1 to 29.4.2 in /node (#256)
Bumps [jest](https://github.com/facebook/jest/tree/HEAD/packages/jest)
from 29.4.1 to 29.4.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/jest/releases">jest's
releases</a>.</em></p>
<blockquote>
<h2>v29.4.2</h2>
<h2>Features</h2>
<ul>
<li><code>[@jest/core]</code> Instrument significant lifecycle events
with <a
href="https://nodejs.org/docs/latest-v16.x/api/perf_hooks.html#performancemarkname-options"><code>performance.mark()</code></a>
(<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13859">#13859</a>)</li>
</ul>
<h2>Fixes</h2>
<ul>
<li><code>[expect, @jest/expect]</code> Provide type of
<code>actual</code> as a generic argument to <code>Matchers</code> to
allow better-typed extensions (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13848">#13848</a>)</li>
<li><code>[jest-circus]</code> Added explicit mention of test failing
because <code>done()</code> is not being called in error message (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13847">#13847</a>)</li>
<li><code>[jest-runtime]</code> Handle CJS re-exports of node core
modules from ESM (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13856">#13856</a>)</li>
<li><code>[jest-transform]</code> Downgrade
<code>write-file-atomic</code> to v4 (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13853">#13853</a>)</li>
<li><code>[jest-worker]</code> Ignore IPC messages not intended for Jest
(<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13543">#13543</a>)</li>
</ul>
<h2>Chore &amp; Maintenance</h2>
<ul>
<li><code>[*]</code> make sure to exclude <code>.eslintcache</code> from
published module (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13832">#13832</a>)</li>
<li><code>[docs]</code> Cleanup incorrect links in CHANGELOG.md (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13857">#13857</a>)</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/benjaminjkraft"><code>@​benjaminjkraft</code></a>
made their first contribution in <a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13848">facebook/jest#13848</a></li>
<li><a href="https://github.com/LinusU"><code>@​LinusU</code></a> made
their first contribution in <a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13543">facebook/jest#13543</a></li>
<li><a
href="https://github.com/SuperSodaSea"><code>@​SuperSodaSea</code></a>
made their first contribution in <a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13857">facebook/jest#13857</a></li>
<li><a href="https://github.com/kowalski"><code>@​kowalski</code></a>
made their first contribution in <a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13856">facebook/jest#13856</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/facebook/jest/compare/v29.4.1...v29.4.2">https://github.com/facebook/jest/compare/v29.4.1...v29.4.2</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/jest/blob/main/CHANGELOG.md">jest's
changelog</a>.</em></p>
<blockquote>
<h2>29.4.2</h2>
<h3>Features</h3>
<ul>
<li><code>[@jest/core]</code> Instrument significant lifecycle events
with <a
href="https://nodejs.org/docs/latest-v16.x/api/perf_hooks.html#performancemarkname-options"><code>performance.mark()</code></a>
(<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13859">#13859</a>)</li>
</ul>
<h3>Fixes</h3>
<ul>
<li><code>[expect, @jest/expect]</code> Provide type of
<code>actual</code> as a generic argument to <code>Matchers</code> to
allow better-typed extensions (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13848">#13848</a>)</li>
<li><code>[jest-circus]</code> Added explicit mention of test failing
because <code>done()</code> is not being called in error message (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13847">#13847</a>)</li>
<li><code>[jest-runtime]</code> Handle CJS re-exports of node core
modules from ESM (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13856">#13856</a>)</li>
<li><code>[jest-transform]</code> Downgrade
<code>write-file-atomic</code> to v4 (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13853">#13853</a>)</li>
<li><code>[jest-worker]</code> Ignore IPC messages not intended for Jest
(<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13543">#13543</a>)</li>
</ul>
<h3>Chore &amp; Maintenance</h3>
<ul>
<li><code>[*]</code> make sure to exclude <code>.eslintcache</code> from
published module (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13832">#13832</a>)</li>
<li><code>[docs]</code> Cleanup incorrect links in CHANGELOG.md (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13857">#13857</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f0fc92e844"><code>f0fc92e</code></a>
v29.4.2</li>
<li><a
href="bc7b20c9d4"><code>bc7b20c</code></a>
chore: make sure to exclude .eslintcache from published module (<a
href="https://github.com/facebook/jest/tree/HEAD/packages/jest/issues/13832">#13832</a>)</li>
<li>See full diff in <a
href="https://github.com/facebook/jest/commits/v29.4.2/packages/jest">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=jest&package-manager=npm_and_yarn&previous-version=29.4.1&new-version=29.4.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-16 10:23:53 -06:00
zach
c706e4efec cleanup: use serde(deny_unknown_fields) in manifest (#254) 2023-02-14 11:40:42 -08:00
Doğu Us
f0f53c7827 feat(zig-sdk): Implement Host Functions (#249)
There are some breaking changes:

- Plugin.init now requires an allocator and functions slice
- Plugin.initFromManifest now requires a functions slice
- Plugin struct removed in favor of using the file as struct
- from @nilslice: https://zig.news/gowind/zig-files-are-structs-288j
(good reference!)

---------

Co-authored-by: Steve Manuel <steve@dylib.so>
2023-02-12 12:36:27 -07:00
dependabot[bot]
bc4baaf67d chore(deps-dev): Bump jest from 29.3.1 to 29.4.1 in /node (#243)
Bumps [jest](https://github.com/facebook/jest/tree/HEAD/packages/jest)
from 29.3.1 to 29.4.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/jest/releases">jest's
releases</a>.</em></p>
<blockquote>
<h2>v29.4.1</h2>
<h2>Features</h2>
<ul>
<li><code>[expect, jest-circus, @jest/types]</code> Implement
<code>numPassingAsserts</code> of testResults to track the number of
passing asserts in a test (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13795">#13795</a>)</li>
<li><code>[jest-core]</code> Add newlines to JSON output (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13817">#13817</a>)</li>
<li><code>[@jest/reporters]</code> Automatic log folding in GitHub
Actions Reporter (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13626">#13626</a>)</li>
</ul>
<h2>Fixes</h2>
<ul>
<li><code>[@jest/expect-utils]</code> <code>toMatchObject</code> diffs
should include <code>Symbol</code> properties (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13810">#13810</a>)</li>
<li><code>[jest-runtime]</code> Handle missing
<code>replaceProperty</code> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13823">#13823</a>)</li>
<li><code>[@jest/types]</code> Add partial support for <code>done</code>
callbacks in typings of <code>each</code> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13756">#13756</a>)</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/jessevanassen"><code>@​jessevanassen</code></a>
made their first contribution in <a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13817">facebook/jest#13817</a></li>
<li><a href="https://github.com/ymqy"><code>@​ymqy</code></a> made their
first contribution in <a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13795">facebook/jest#13795</a></li>
<li><a
href="https://github.com/MatteoH2O1999"><code>@​MatteoH2O1999</code></a>
made their first contribution in <a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13626">facebook/jest#13626</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/facebook/jest/compare/v29.4.0...v29.4.1">https://github.com/facebook/jest/compare/v29.4.0...v29.4.1</a></p>
<h2>v29.4.0</h2>
<h2>Features</h2>
<ul>
<li><code>[expect, @jest/expect-utils]</code> Support custom equality
testers (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13654">#13654</a>)</li>
<li><code>[jest-config, jest-worker]</code> Use
<code>os.availableParallelism</code> if available to calculate number of
workers to spawn (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13738">#13738</a>)</li>
<li><code>[@jest/globals, jest-mock]</code> Add
<code>jest.replaceProperty()</code> that replaces property value (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13496">#13496</a>)</li>
<li><code>[jest-haste-map]</code> ignore Sapling vcs directories
(<code>.sl/</code>) (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13674">#13674</a>)</li>
<li><code>[jest-resolve]</code> Support subpath imports (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13705">#13705</a>,
<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13723">#13723</a>,
<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13777">#13777</a>)</li>
<li><code>[jest-runtime]</code> Add
<code>jest.isolateModulesAsync</code> for scoped module initialization
of asynchronous functions (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13680">#13680</a>)</li>
<li><code>[jest-runtime]</code> Add
<code>jest.isEnvironmentTornDown</code> function (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13741">#13741</a>)</li>
<li><code>[jest-test-result]</code> Added <code>skipped</code> and
<code>focused</code> status to <code>FormattedTestResult</code> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13700">#13700</a>)</li>
<li><code>[jest-transform]</code> Support for asynchronous
<code>createTransformer</code> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13762">#13762</a>)</li>
</ul>
<h2>Fixes</h2>
<ul>
<li><code>[jest-environment-node]</code> Fix non-configurable globals
(<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13687">#13687</a>)</li>
<li><code>[@jest/expect-utils]</code> <code>toMatchObject</code> should
handle <code>Symbol</code> properties (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13639">#13639</a>)</li>
<li><code>[jest-mock]</code> Fix <code>mockReset</code> and
<code>resetAllMocks</code> <code>undefined</code> return value(<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13692">#13692</a>)</li>
<li><code>[jest-resolve]</code> Add global paths to
<code>require.resolve.paths</code> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13633">#13633</a>)</li>
<li><code>[jest-resolve]</code> Correct node core module detection when
using <code>node:</code> specifiers (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13806">#13806</a>)</li>
<li><code>[jest-runtime]</code> Support WASM files that import JS
resources (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13608">#13608</a>)</li>
<li><code>[jest-runtime]</code> Use the <code>scriptTransformer</code>
cache in <code>jest-runner</code> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13735">#13735</a>)</li>
<li><code>[jest-runtime]</code> Enforce import assertions when importing
JSON in ESM (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/12755">#12755</a>
&amp; <a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13805">#13805</a>)</li>
<li><code>[jest-snapshot]</code> Make sure to import <code>babel</code>
outside of the sandbox (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13694">#13694</a>)</li>
<li><code>[jest-transform]</code> Ensure the correct configuration is
passed to preprocessors specified multiple times in the
<code>transform</code> option (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13770">#13770</a>)</li>
</ul>
<h2>Chore &amp; Maintenance</h2>
<ul>
<li><code>[@jest/fake-timers]</code> Update
<code>@sinonjs/fake-timers</code> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13612">#13612</a>)</li>
<li><code>[docs]</code> Improve custom puppeteer example to prevent
worker warnings (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13619">#13619</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/jest/blob/main/CHANGELOG.md">jest's
changelog</a>.</em></p>
<blockquote>
<h2>29.4.1</h2>
<h3>Features</h3>
<ul>
<li><code>[expect, jest-circus, @jest/types]</code> Implement
<code>numPassingAsserts</code> of testResults to track the number of
passing asserts in a test (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13795">#13795</a>)</li>
<li><code>[jest-core]</code> Add newlines to JSON output (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13817">#13817</a>)</li>
<li><code>[@jest/reporters]</code> Automatic log folding in GitHub
Actions Reporter (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13626">#13626</a>)</li>
</ul>
<h3>Fixes</h3>
<ul>
<li><code>[@jest/expect-utils]</code> <code>toMatchObject</code> diffs
should include <code>Symbol</code> properties (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13810">#13810</a>)</li>
<li><code>[jest-runtime]</code> Handle missing
<code>replaceProperty</code> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13823">#13823</a>)</li>
<li><code>[@jest/types]</code> Add partial support for <code>done</code>
callbacks in typings of <code>each</code> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13756">#13756</a>)</li>
</ul>
<h2>29.4.0</h2>
<h3>Features</h3>
<ul>
<li><code>[expect, @jest/expect-utils]</code> Support custom equality
testers (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13654">#13654</a>)</li>
<li><code>[jest-config, jest-worker]</code> Use
<code>os.availableParallelism</code> if available to calculate number of
workers to spawn (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13738">#13738</a>)</li>
<li><code>[@jest/globals, jest-mock]</code> Add
<code>jest.replaceProperty()</code> that replaces property value (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13496">#13496</a>)</li>
<li><code>[jest-haste-map]</code> ignore Sapling vcs directories
(<code>.sl/</code>) (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13674">#13674</a>)</li>
<li><code>[jest-resolve]</code> Support subpath imports (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13705">#13705</a>,
<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13723">#13723</a>,
<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13777">#13777</a>)</li>
<li><code>[jest-runtime]</code> Add
<code>jest.isolateModulesAsync</code> for scoped module initialization
of asynchronous functions (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13680">#13680</a>)</li>
<li><code>[jest-runtime]</code> Add
<code>jest.isEnvironmentTornDown</code> function (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13741">#13741</a>)</li>
<li><code>[jest-test-result]</code> Added <code>skipped</code> and
<code>focused</code> status to <code>FormattedTestResult</code> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13700">#13700</a>)</li>
<li><code>[jest-transform]</code> Support for asynchronous
<code>createTransformer</code> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13762">#13762</a>)</li>
</ul>
<h3>Fixes</h3>
<ul>
<li><code>[jest-environment-node]</code> Fix non-configurable globals
(<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13687">#13687</a>)</li>
<li><code>[@jest/expect-utils]</code> <code>toMatchObject</code> should
handle <code>Symbol</code> properties (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13639">#13639</a>)</li>
<li><code>[jest-mock]</code> Fix <code>mockReset</code> and
<code>resetAllMocks</code> <code>undefined</code> return value(<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13692">#13692</a>)</li>
<li><code>[jest-resolve]</code> Add global paths to
<code>require.resolve.paths</code> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13633">#13633</a>)</li>
<li><code>[jest-resolve]</code> Correct node core module detection when
using <code>node:</code> specifiers (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13806">#13806</a>)</li>
<li><code>[jest-runtime]</code> Support WASM files that import JS
resources (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13608">#13608</a>)</li>
<li><code>[jest-runtime]</code> Use the <code>scriptTransformer</code>
cache in <code>jest-runner</code> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13735">#13735</a>)</li>
<li><code>[jest-runtime]</code> Enforce import assertions when importing
JSON in ESM (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/12755">#12755</a>
&amp; <a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13805">#13805</a>)</li>
<li><code>[jest-snapshot]</code> Make sure to import <code>babel</code>
outside of the sandbox (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13694">#13694</a>)</li>
<li><code>[jest-transform]</code> Ensure the correct configuration is
passed to preprocessors specified multiple times in the
<code>transform</code> option (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13770">#13770</a>)</li>
</ul>
<h3>Chore &amp; Maintenance</h3>
<ul>
<li><code>[@jest/fake-timers]</code> Update
<code>@sinonjs/fake-timers</code> (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13612">#13612</a>)</li>
<li><code>[docs]</code> Improve custom puppeteer example to prevent
worker warnings (<a
href="https://github-redirect.dependabot.com/facebook/jest/pull/13619">#13619</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="bc84c8a156"><code>bc84c8a</code></a>
v29.4.1</li>
<li><a
href="4bc0e8acaf"><code>4bc0e8a</code></a>
v29.4.0</li>
<li><a
href="6e5b1d60a1"><code>6e5b1d6</code></a>
chore: update typescript (<a
href="https://github.com/facebook/jest/tree/HEAD/packages/jest/issues/13616">#13616</a>)</li>
<li>See full diff in <a
href="https://github.com/facebook/jest/commits/v29.4.1/packages/jest">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=jest&package-manager=npm_and_yarn&previous-version=29.3.1&new-version=29.4.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-12 11:04:28 -07:00
dependabot[bot]
e05169c3f1 chore(deps-dev): Update black requirement from ^22.10.0 to ^23.1.0 in /python (#250)
Updates the requirements on [black](https://github.com/psf/black) to
permit the latest version.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/psf/black/releases">black's
releases</a>.</em></p>
<blockquote>
<h2>23.1.0</h2>
<h3>Highlights</h3>
<p>This is the first release of 2023, and following our <a
href="https://black.readthedocs.io/en/stable/the_black_code_style/index.html#stability-policy">stability
policy</a>, it comes with a number of improvements to our stable style,
notably improvements to empty line handling and the removal of redundant
parentheses in several contexts.</p>
<p>There are also many changes to the preview style; try out <code>black
--preview</code> and give us feedback to help us set the stable style
for next year.</p>
<p>In addition to style changes, Black now automatically infers the
supported Python versions from your <code>pyproject.toml</code> file,
removing the need to set Black's target versions separately.</p>
<h3>Stable style</h3>
<!-- raw HTML omitted -->
<ul>
<li>Introduce the 2023 stable style, which incorporates most aspects of
last year's preview style (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3418">#3418</a>).
Specific changes:
<ul>
<li>Enforce empty lines before classes and functions with sticky leading
comments (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3302">#3302</a>)
(22.12.0)</li>
<li>Reformat empty and whitespace-only files as either an empty file (if
no newline is present) or as a single newline character (if a newline is
present) (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3348">#3348</a>)
(22.12.0)</li>
<li>Correctly handle trailing commas that are inside a line's leading
non-nested parens (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3370">#3370</a>)
(22.12.0)</li>
<li><code>--skip-string-normalization</code> / <code>-S</code> now
prevents docstring prefixes from being normalized as expected (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3168">#3168</a>)
(since 22.8.0)</li>
<li>When using <code>--skip-magic-trailing-comma</code> or
<code>-C</code>, trailing commas are stripped from subscript expressions
with more than 1 element (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3209">#3209</a>)
(22.8.0)</li>
<li>Fix a string merging/split issue when a comment is present in the
middle of implicitly concatenated strings on its own line (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3227">#3227</a>)
(22.8.0)</li>
<li>Docstring quotes are no longer moved if it would violate the line
length limit (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3044">#3044</a>,
<a
href="https://github-redirect.dependabot.com/psf/black/issues/3430">#3430</a>)
(22.6.0)</li>
<li>Parentheses around return annotations are now managed (<a
href="https://github-redirect.dependabot.com/psf/black/issues/2990">#2990</a>)
(22.6.0)</li>
<li>Remove unnecessary parentheses around awaited objects (<a
href="https://github-redirect.dependabot.com/psf/black/issues/2991">#2991</a>)
(22.6.0)</li>
<li>Remove unnecessary parentheses in <code>with</code> statements (<a
href="https://github-redirect.dependabot.com/psf/black/issues/2926">#2926</a>)
(22.6.0)</li>
<li>Remove trailing newlines after code block open (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3035">#3035</a>)
(22.6.0)</li>
<li>Code cell separators <code>#%%</code> are now standardised to
<code># %%</code> (<a
href="https://github-redirect.dependabot.com/psf/black/issues/2919">#2919</a>)
(22.3.0)</li>
<li>Remove unnecessary parentheses from <code>except</code> statements
(<a
href="https://github-redirect.dependabot.com/psf/black/issues/2939">#2939</a>)
(22.3.0)</li>
<li>Remove unnecessary parentheses from tuple unpacking in
<code>for</code> loops (<a
href="https://github-redirect.dependabot.com/psf/black/issues/2945">#2945</a>)
(22.3.0)</li>
<li>Avoid magic-trailing-comma in single-element subscripts (<a
href="https://github-redirect.dependabot.com/psf/black/issues/2942">#2942</a>)
(22.3.0)</li>
</ul>
</li>
<li>Fix a crash when a colon line is marked between <code># fmt:
off</code> and <code># fmt: on</code> (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3439">#3439</a>)</li>
</ul>
<h3>Preview style</h3>
<!-- raw HTML omitted -->
<ul>
<li>Format hex codes in unicode escape sequences in string literals (<a
href="https://github-redirect.dependabot.com/psf/black/issues/2916">#2916</a>)</li>
<li>Add parentheses around <code>if</code>-<code>else</code> expressions
(<a
href="https://github-redirect.dependabot.com/psf/black/issues/2278">#2278</a>)</li>
<li>Improve performance on large expressions that contain many strings
(<a
href="https://github-redirect.dependabot.com/psf/black/issues/3467">#3467</a>)</li>
<li>Fix a crash in preview style with assert + parenthesized string (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3415">#3415</a>)</li>
<li>Fix crashes in preview style with walrus operators used in function
return annotations and except clauses (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3423">#3423</a>)</li>
<li>Fix a crash in preview advanced string processing where mixed
implicitly concatenated regular and f-strings start with an empty span
(<a
href="https://github-redirect.dependabot.com/psf/black/issues/3463">#3463</a>)</li>
<li>Fix a crash in preview advanced string processing where a standalone
comment is placed before a dict's value (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3469">#3469</a>)</li>
<li>Fix an issue where extra empty lines are added when a decorator has
<code># fmt: skip</code> applied or there is a standalone comment
between decorators (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3470">#3470</a>)</li>
<li>Do not put the closing quotes in a docstring on a separate line,
even if the line is too long (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3430">#3430</a>)</li>
<li>Long values in dict literals are now wrapped in parentheses;
correspondingly unnecessary parentheses around short values in dict
literals are now removed; long string lambda values are now wrapped in
parentheses (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3440">#3440</a>)</li>
<li>Fix two crashes in preview style involving edge cases with
docstrings (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3451">#3451</a>)</li>
<li>Exclude string type annotations from improved string processing; fix
crash when the return type annotation is stringified and spans across
multiple lines (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3462">#3462</a>)</li>
<li>Wrap multiple context managers in parentheses when targeting Python
3.9+ (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3489">#3489</a>)</li>
<li>Fix several crashes in preview style with walrus operators used in
<code>with</code> statements or tuples (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3473">#3473</a>)</li>
<li>Fix an invalid quote escaping bug in f-string expressions where it
produced invalid code. Implicitly concatenated f-strings with different
quotes can now be merged or quote-normalized by changing the quotes used
in expressions. (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3509">#3509</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/psf/black/blob/main/CHANGES.md">black's
changelog</a>.</em></p>
<blockquote>
<h2>23.1.0</h2>
<h3>Highlights</h3>
<p>This is the first release of 2023, and following our
<a
href="https://black.readthedocs.io/en/stable/the_black_code_style/index.html#stability-policy">stability
policy</a>,
it comes with a number of improvements to our stable style, including
improvements to
empty line handling, removal of redundant parentheses in several
contexts, and output
that highlights implicitly concatenated strings better.</p>
<p>There are also many changes to the preview style; try out <code>black
--preview</code> and give us
feedback to help us set the stable style for next year.</p>
<p>In addition to style changes, Black now automatically infers the
supported Python
versions from your <code>pyproject.toml</code> file, removing the need
to set Black's target
versions separately.</p>
<h3>Stable style</h3>
<!-- raw HTML omitted -->
<ul>
<li>Introduce the 2023 stable style, which incorporates most aspects of
last year's
preview style (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3418">#3418</a>).
Specific changes:
<ul>
<li>Enforce empty lines before classes and functions with sticky leading
comments
(<a
href="https://github-redirect.dependabot.com/psf/black/issues/3302">#3302</a>)
(22.12.0)</li>
<li>Reformat empty and whitespace-only files as either an empty file (if
no newline is
present) or as a single newline character (if a newline is present) (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3348">#3348</a>)
(22.12.0)</li>
<li>Implicitly concatenated strings used as function args are now
wrapped inside
parentheses (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3307">#3307</a>)
(22.12.0)</li>
<li>Correctly handle trailing commas that are inside a line's leading
non-nested parens
(<a
href="https://github-redirect.dependabot.com/psf/black/issues/3370">#3370</a>)
(22.12.0)</li>
<li><code>--skip-string-normalization</code> / <code>-S</code> now
prevents docstring prefixes from being
normalized as expected (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3168">#3168</a>)
(since 22.8.0)</li>
<li>When using <code>--skip-magic-trailing-comma</code> or
<code>-C</code>, trailing commas are stripped from
subscript expressions with more than 1 element (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3209">#3209</a>)
(22.8.0)</li>
<li>Implicitly concatenated strings inside a list, set, or tuple are now
wrapped inside
parentheses (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3162">#3162</a>)
(22.8.0)</li>
<li>Fix a string merging/split issue when a comment is present in the
middle of
implicitly concatenated strings on its own line (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3227">#3227</a>)
(22.8.0)</li>
<li>Docstring quotes are no longer moved if it would violate the line
length limit
(<a
href="https://github-redirect.dependabot.com/psf/black/issues/3044">#3044</a>,
<a
href="https://github-redirect.dependabot.com/psf/black/issues/3430">#3430</a>)
(22.6.0)</li>
<li>Parentheses around return annotations are now managed (<a
href="https://github-redirect.dependabot.com/psf/black/issues/2990">#2990</a>)
(22.6.0)</li>
<li>Remove unnecessary parentheses around awaited objects (<a
href="https://github-redirect.dependabot.com/psf/black/issues/2991">#2991</a>)
(22.6.0)</li>
<li>Remove unnecessary parentheses in <code>with</code> statements (<a
href="https://github-redirect.dependabot.com/psf/black/issues/2926">#2926</a>)
(22.6.0)</li>
<li>Remove trailing newlines after code block open (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3035">#3035</a>)
(22.6.0)</li>
<li>Code cell separators <code>#%%</code> are now standardised to
<code># %%</code> (<a
href="https://github-redirect.dependabot.com/psf/black/issues/2919">#2919</a>)
(22.3.0)</li>
<li>Remove unnecessary parentheses from <code>except</code> statements
(<a
href="https://github-redirect.dependabot.com/psf/black/issues/2939">#2939</a>)
(22.3.0)</li>
<li>Remove unnecessary parentheses from tuple unpacking in
<code>for</code> loops (<a
href="https://github-redirect.dependabot.com/psf/black/issues/2945">#2945</a>)
(22.3.0)</li>
<li>Avoid magic-trailing-comma in single-element subscripts (<a
href="https://github-redirect.dependabot.com/psf/black/issues/2942">#2942</a>)
(22.3.0)</li>
</ul>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="b0d1fba7ac"><code>b0d1fba</code></a>
Prepare release 23.1.0 (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3536">#3536</a>)</li>
<li><a
href="69ca0a4c7a"><code>69ca0a4</code></a>
Infer target version based on project metadata (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3219">#3219</a>)</li>
<li><a
href="c4bd2e31ce"><code>c4bd2e3</code></a>
Draft for Black 2023 stable style (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3418">#3418</a>)</li>
<li><a
href="226cbf0226"><code>226cbf0</code></a>
Fix unsafe cast in linegen.py w/ await yield handling (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3533">#3533</a>)</li>
<li><a
href="f4ebc68320"><code>f4ebc68</code></a>
Upgrade isort (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3534">#3534</a>)</li>
<li><a
href="6407ebb870"><code>6407ebb</code></a>
Remove Python version in the_basics.md (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3528">#3528</a>)</li>
<li><a
href="196b1f349e"><code>196b1f3</code></a>
Fix <code>black --help</code> output for
<code>--python-cell-magics</code> option to be reproducibl...</li>
<li><a
href="d950f15987"><code>d950f15</code></a>
Update document now that paren wrapping CMs on Python 3.9+ is
implemented (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3">#3</a>...</li>
<li><a
href="a36878eb2f"><code>a36878e</code></a>
Fix an invalid quote escaping bug in f-string expressions (<a
href="https://github-redirect.dependabot.com/psf/black/issues/3509">#3509</a>)</li>
<li><a
href="eabff673b3"><code>eabff67</code></a>
Format hex code in unicode escape sequences in string literals (<a
href="https://github-redirect.dependabot.com/psf/black/issues/2916">#2916</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/psf/black/compare/22.10.0...23.1.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-12 11:04:01 -07:00
dependabot[bot]
9cad98683a chore(deps-dev): Bump @types/node from 18.11.18 to 18.11.19 in /node (#251)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 18.11.18 to 18.11.19.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=18.11.18&new-version=18.11.19)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-12 11:03:42 -07:00
dependabot[bot]
a7386b1939 chore(deps-dev): Bump typescript from 4.9.4 to 4.9.5 in /node (#252)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.9.4
to 4.9.5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/Microsoft/TypeScript/releases">typescript's
releases</a>.</em></p>
<blockquote>
<h2>TypeScript 4.9.5</h2>
<p>For release notes, check out the <a
href="https://devblogs.microsoft.com/typescript/announcing-typescript-4-9/">release
announcement</a>.</p>
<p>Downloads are available on:</p>
<ul>
<li><a href="https://www.npmjs.com/package/typescript">npm</a></li>
<li><a
href="https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild">NuGet
package</a></li>
</ul>
<h2>Changes:</h2>
<ul>
<li>69e88ef5513a81acf69ec78f4af1f927da0d0584 Port ignore deprecations to
4.9 (<a
href="https://github-redirect.dependabot.com/Microsoft/TypeScript/issues/52419">#52419</a>)</li>
<li>daf4e817a18def96b70ac34703b158ff0e6d58df Port timestamp fix to 4.9
(<a
href="https://github-redirect.dependabot.com/Microsoft/TypeScript/issues/52426">#52426</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ccf3d3c5f9"><code>ccf3d3c</code></a>
Bump version to '4.9.5' and LKG.</li>
<li><a
href="69e88ef551"><code>69e88ef</code></a>
Port ignore deprecations to 4.9 (<a
href="https://github-redirect.dependabot.com/Microsoft/TypeScript/issues/52419">#52419</a>)</li>
<li><a
href="daf4e817a1"><code>daf4e81</code></a>
Port timestamp fix to 4.9 (<a
href="https://github-redirect.dependabot.com/Microsoft/TypeScript/issues/52426">#52426</a>)</li>
<li>See full diff in <a
href="https://github.com/Microsoft/TypeScript/compare/v4.9.4...v4.9.5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=typescript&package-manager=npm_and_yarn&previous-version=4.9.4&new-version=4.9.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-12 11:03:22 -07:00
zach
a44124bdb0 feat: add ability to set host function namespace (#246)
- Adds `extism_function_set_namespace` to SDK
- Updates SDKs with host function support to allow setting the namespace
for a function
2023-02-01 11:04:15 -08:00
zach
226155b959 chore: update toml to 0.7 (#245) 2023-01-31 09:38:23 -08:00
Brett Cannon
1fad76148b Make the Python example more idiomatic (#242) 2023-01-30 09:49:42 -08:00
zach
bacb44bcc5 feat: add helper functions for working with input/output of host functions as bytes (#240) 2023-01-27 11:16:14 -08:00
zach
93c65bb4b4 fix(go): allow for host functions with no arguments or return values (#241) 2023-01-25 15:34:02 -08:00
Benjamin Eckel
beb83c697c test(browser): Comment out test so we stop failure (#238)
Can't quite figure out what is going on. Jest cannot resolves our code
fine but can't seem to resolve the NPM module:

```
 FAIL  src/index.test.ts
  ● Test suite failed to run

    Cannot find module '@bjorn3/browser_wasi_shim' from 'src/plugin.ts'

    Require stack:
      src/plugin.ts
      src/context.ts
      src/index.ts
      src/index.test.ts

      2 | import { PluginConfig } from './manifest';
      3 | //@ts-ignore TODO add types to this library
    > 4 | import { WASI, File } from "@bjorn3/browser_wasi_shim";
        | ^
      5 |
      6 | export default class ExtismPlugin {
      7 |   moduleData: ArrayBuffer;

      at Resolver._throwModNotFoundError (node_modules/jest-resolve/build/resolver.js:425:11)
      at Object.<anonymous> (src/plugin.ts:4:1)
      at Object.<anonymous> (src/context.ts:2:1)
      at Object.<anonymous> (src/index.ts:1:1)
      at Object.<anonymous> (src/index.test.ts:1:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.916 s
Ran all test suites.
```


For now let's comment it out since it's not providing value anyway.
2023-01-23 14:25:14 -06:00
Benjamin Eckel
5b58cd2580 user_code not used 2023-01-23 14:08:49 -06:00
zach
69d450e8a2 cleanup: fix opam files according to changes published to opam (#237)
A few changes to the opam files based on the review from
https://github.com/ocaml/opam-repository/pull/23018
2023-01-23 11:42:47 -08:00
Benjamin Eckel
8b81198486 chore: Make memory traces clearer (#236)
If you look at the memory traces it's not really clear what the values
are:

```
extism_runtime::memory TRACE 2023-01-23T10:05:16.918413-06:00 - store_u64: 656c626169726176 at offset 25
extism_runtime::memory TRACE 2023-01-23T10:05:16.918418-06:00 - store_u8: 20 at offset 33
extism_runtime::memory TRACE 2023-01-23T10:05:16.918423-06:00 - store_u8: 76 at offset 34
extism_runtime::memory TRACE 2023-01-23T10:05:16.918428-06:00 - store_u8: 61 at offset 35
extism_runtime::memory TRACE 2023-01-23T10:05:16.918433-06:00 - store_u8: 6c at offset 36
extism_runtime::memory TRACE 2023-01-23T10:05:16.918438-06:00 - store_u8: 75 at offset 37
extism_runtime::memory TRACE 2023-01-23T10:05:16.918443-06:00 - store_u8: 65 at offset 38
```

It's hard to tell that the value is hex and the offset is base10. This
changes u8 values to the form `0x00` where there is always 2 digits and
it will always use 16 digits for u64.
2023-01-23 11:10:47 -06:00
dependabot[bot]
c2830b03b5 chore(deps): Bump rustler from 0.26.0 to 0.27.0 in /elixir (#235)
Bumps [rustler](https://github.com/rusterlium/rustler) from 0.26.0 to
0.27.0.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rusterlium/rustler/blob/master/CHANGELOG.md">rustler's
changelog</a>.</em></p>
<blockquote>
<h2>[0.27.0] - 2023-01-17</h2>
<h3>BREAKING</h3>
<ul>
<li><code>MIX_ENV</code> is no longer considered for determining the
build profile. Now, the
profile defaults to <code>:release</code>. Use the <code>:mode</code>
option to pick another
profile explicitly. (<a
href="https://github-redirect.dependabot.com/rusterlium/rustler/issues/496">#496</a>)</li>
</ul>
<h3>Added</h3>
<ul>
<li><code>ResourceArc::make_binary</code> for safe use of
<code>enif_make_resource_binary</code> (<a
href="https://github-redirect.dependabot.com/rusterlium/rustler/issues/487">#487</a>)</li>
<li><code>OwnedBinary</code> is now <code>Sync</code> (<a
href="https://github-redirect.dependabot.com/rusterlium/rustler/issues/493">#493</a>)</li>
<li>Specified MSRV to be 1.56.1.</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Documentation for <code>load</code> (<a
href="https://github-redirect.dependabot.com/rusterlium/rustler/issues/501">#501</a>,
thanks <a
href="https://github.com/ishitatsuyuki"><code>@​ishitatsuyuki</code></a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Edition 2021 for the rustler mix template (<a
href="https://github-redirect.dependabot.com/rusterlium/rustler/issues/512">#512</a>,
thanks <a
href="https://github.com/ayrat555"><code>@​ayrat555</code></a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="80f6c4b926"><code>80f6c4b</code></a>
(release) 0.27.0</li>
<li><a
href="ca9a798ffe"><code>ca9a798</code></a>
Prepare release v0.27.0</li>
<li><a
href="1e03377cde"><code>1e03377</code></a>
Fix target for rustler_compile_test</li>
<li><a
href="baec31bfb0"><code>baec31b</code></a>
Merge pull request <a
href="https://github-redirect.dependabot.com/rusterlium/rustler/issues/512">#512</a>
from ayrat-forks/ayrat555/update-edition</li>
<li><a
href="57cc69e8c0"><code>57cc69e</code></a>
update rust edition</li>
<li><a
href="a34038fb11"><code>a34038f</code></a>
Merge pull request <a
href="https://github-redirect.dependabot.com/rusterlium/rustler/issues/510">#510</a>
from evnu/clippy-define-MSRV-and-fix-lints</li>
<li><a
href="7b728f1652"><code>7b728f1</code></a>
clippy: needless_borrow</li>
<li><a
href="aa045a7b28"><code>aa045a7</code></a>
clippy: unnecessary_cast</li>
<li><a
href="662d4a31bc"><code>662d4a3</code></a>
Define MSRV</li>
<li><a
href="3a7aa47af9"><code>3a7aa47</code></a>
Merge pull request <a
href="https://github-redirect.dependabot.com/rusterlium/rustler/issues/502">#502</a>
from evnu/fix-ci</li>
<li>Additional commits viewable in <a
href="https://github.com/rusterlium/rustler/compare/rustler-0.26.0...rustler-0.27.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=rustler&package-manager=hex&previous-version=0.26.0&new-version=0.27.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-23 10:47:14 -06:00
dependabot[bot]
43fcf4266a chore(deps): Update rustler requirement from 0.26.0 to 0.27.0 (#232)
Updates the requirements on
[rustler](https://github.com/rusterlium/rustler) to permit the latest
version.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rusterlium/rustler/blob/master/CHANGELOG.md">rustler's
changelog</a>.</em></p>
<blockquote>
<h2>[0.27.0] - 2023-01-17</h2>
<h3>BREAKING</h3>
<ul>
<li><code>MIX_ENV</code> is no longer considered for determining the
build profile. Now, the
profile defaults to <code>:release</code>. Use the <code>:mode</code>
option to pick another
profile explicitly. (<a
href="https://github-redirect.dependabot.com/rusterlium/rustler/issues/496">#496</a>)</li>
</ul>
<h3>Added</h3>
<ul>
<li><code>ResourceArc::make_binary</code> for safe use of
<code>enif_make_resource_binary</code> (<a
href="https://github-redirect.dependabot.com/rusterlium/rustler/issues/487">#487</a>)</li>
<li><code>OwnedBinary</code> is now <code>Sync</code> (<a
href="https://github-redirect.dependabot.com/rusterlium/rustler/issues/493">#493</a>)</li>
<li>Specified MSRV to be 1.56.1.</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Documentation for <code>load</code> (<a
href="https://github-redirect.dependabot.com/rusterlium/rustler/issues/501">#501</a>,
thanks <a
href="https://github.com/ishitatsuyuki"><code>@​ishitatsuyuki</code></a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Edition 2021 for the rustler mix template (<a
href="https://github-redirect.dependabot.com/rusterlium/rustler/issues/512">#512</a>,
thanks <a
href="https://github.com/ayrat555"><code>@​ayrat555</code></a>)</li>
</ul>
<h2>[0.26.0] - 2022-09-02</h2>
<h3>Highlight</h3>
<h4>TaggedEnum</h4>
<p>We added <code>TaggedEnum</code>, which is a generalized enum type
(<a
href="https://github-redirect.dependabot.com/rusterlium/rustler/issues/440">#440</a>,
thanks to <a
href="https://github.com/SeokminHong"><code>@​SeokminHong</code></a>!).
Example:</p>
<pre lang="rust"><code>#[derive(NifTaggedEnum)]
pub enum TaggedEnum1 {
    Named { x: i32, y: i32 },
    String1(String),
    String2(String),
    Untagged,
}
</code></pre>
<p>On the Elixir side, the variants are represented as two-tuples
<code>{tag::atom(), inner::term()} | atom()</code>, where the
<code>inner</code> term is</p>
<ul>
<li>a map for the variant <code>Named</code> in the example above</li>
<li>a binary for the <code>String1</code> and <code>String2</code>
variants</li>
</ul>
<p>The <code>Untagged</code> variant is represented as the atom
<code>:untagged</code> in Elixir.</p>
<h3>Added</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="80f6c4b926"><code>80f6c4b</code></a>
(release) 0.27.0</li>
<li><a
href="ca9a798ffe"><code>ca9a798</code></a>
Prepare release v0.27.0</li>
<li><a
href="1e03377cde"><code>1e03377</code></a>
Fix target for rustler_compile_test</li>
<li><a
href="baec31bfb0"><code>baec31b</code></a>
Merge pull request <a
href="https://github-redirect.dependabot.com/rusterlium/rustler/issues/512">#512</a>
from ayrat-forks/ayrat555/update-edition</li>
<li><a
href="57cc69e8c0"><code>57cc69e</code></a>
update rust edition</li>
<li><a
href="a34038fb11"><code>a34038f</code></a>
Merge pull request <a
href="https://github-redirect.dependabot.com/rusterlium/rustler/issues/510">#510</a>
from evnu/clippy-define-MSRV-and-fix-lints</li>
<li><a
href="7b728f1652"><code>7b728f1</code></a>
clippy: needless_borrow</li>
<li><a
href="aa045a7b28"><code>aa045a7</code></a>
clippy: unnecessary_cast</li>
<li><a
href="662d4a31bc"><code>662d4a3</code></a>
Define MSRV</li>
<li><a
href="3a7aa47af9"><code>3a7aa47</code></a>
Merge pull request <a
href="https://github-redirect.dependabot.com/rusterlium/rustler/issues/502">#502</a>
from evnu/fix-ci</li>
<li>Additional commits viewable in <a
href="https://github.com/rusterlium/rustler/compare/rustler-0.26.0...rustler-0.27.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-23 10:47:00 -06:00
dependabot[bot]
0221d8e4a2 chore(deps-dev): Bump @types/jest from 29.2.5 to 29.2.6 in /node (#230)
Bumps
[@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest)
from 29.2.5 to 29.2.6.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/jest&package-manager=npm_and_yarn&previous-version=29.2.5&new-version=29.2.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-23 10:46:51 -06:00
Benjamin Eckel
222401b3db docs(java-sdk): fix source code link (#228) 2023-01-22 09:33:41 -06:00
Benjamin Eckel
f6e55413d8 docs: Update README to reflect quality but instability (#226) 2023-01-20 10:05:16 -06:00
Benjamin Eckel
890760f06d include other languages 2023-01-19 15:33:16 -06:00
Benjamin Eckel
d29e9f8f93 add symlinks 2023-01-19 13:43:05 -06:00
Benjamin Eckel
52cc95bf5a go and python 2023-01-19 13:42:18 -06:00
Benjamin Eckel
4b5796b92b drop unix prefix 2023-01-19 13:33:12 -06:00
Benjamin Eckel
fee2f03651 docs: Symlink plugin in example files 2023-01-19 13:30:04 -06:00
Benjamin Eckel
490dec4f14 fix(elixir-sdk): Release 0.2.0 is broken due to this local path dep (#224)
5c9aa4c90a

This should work but it doesn't. Error message when including extism
0.2.0 locally:

```
Compiling 4 files (.ex)
error: failed to get `extism` as a dependency of package `extism_nif v0.1.0 (/private/tmp/extism_test/deps/extism/native/extism_nif)`

Caused by:
  failed to load source for dependency `extism`

Caused by:
  Unable to update /private/tmp/extism_test/deps/rust

Caused by:
  failed to read `/private/tmp/extism_test/deps/rust/Cargo.toml`

Caused by:
  No such file or directory (os error 2)

== Compilation error in file lib/extism/native.ex ==
** (RuntimeError) calling `cargo metadata` failed.

    (rustler 0.26.0) lib/rustler/compiler/config.ex:87: Rustler.Compiler.Config.metadata!/1
    (rustler 0.26.0) lib/rustler/compiler/config.ex:69: Rustler.Compiler.Config.build/1
    (rustler 0.26.0) lib/rustler/compiler.ex:9: Rustler.Compiler.compile_crate/2
    lib/extism/native.ex:6: (module)
could not compile dependency :extism, "mix compile" failed. Errors may have been logged above. You can recompile this dependency with "mix deps.compile extism", update it with "mix deps.update extism" or clean it with "mix deps.clean extism"
```
2023-01-19 13:11:22 -06:00
zach
8fdc0beb31 chore(haskell): fix bounds for extism-manifest 2023-01-19 11:01:40 -08:00
zach
93ffec53d1 chore: bump version for haskell extism-manifest package (#223) 2023-01-19 10:55:05 -08:00
Benjamin Eckel
be3f324641 fix: Haskell release workflow had wrong display name 2023-01-19 12:45:42 -06:00
Benjamin Eckel
f5537e4bcb fix: ignore javadoc warnings in release for now 2023-01-19 12:08:07 -06:00
Benjamin Eckel
e1c04b42f9 release: missed the bump on dotnet SDK 2023-01-19 11:26:57 -06:00
Benjamin Eckel
c94c221854 release: v0.2.0 (#209)
Let's get the last changes in this week for a release. Will hold this PR
until all changes we want are in.

Release checklist:
- [x] test: updates across CI to test for Host Function output /
integration (#219)
- this should probably look something like a grep for some kind of
output proving guest/host interop?
- [x] Fix for userData pointer issue in Go host functions (#220) 
- [x] docs: Host Functions in SDKs
  - [ ] sdk: C 
  - [ ] sdk: C++ 
  - [ ] sdk: Python
  - [ ] sdk: Node
  - [ ] sdk: Go
  - [ ] sdk: Rust 
- [x] docs: Manifest property names (http `headers` & memory
`max_pages`)
- [ ] blog: announcing v0.2.0, including host functions, Zig SDK/PDK,
Java SDK, .NET SDK, + ...
2023-01-19 10:56:00 -06:00
zach
aa04fd3e5c test: add more host function tests, cleanup tests to use wasm/code.wasm when possible (#219) 2023-01-19 10:09:16 -06:00
Benjamin Eckel
d73468a3ac ci(java-sdk): Test on multiple JREs (#221) 2023-01-18 10:43:59 -06:00
Etienne ANNE
ac7e1aeba3 Support jdk11 (#208)
Hi,

We want to use Extism on our project
[Otoroshi](https://github.com/MAIF/otoroshi) but we need to run it on
jdk11

This pull request makes everything run smoothly on jdk11

If you have any suggestion about this pull request, i'm open to it

Thanks for your time
2023-01-18 09:48:36 -06:00
zach
668ef5c3c0 fix: use cgo.Handle to protect Go pointers being passed to C callbacks (#220)
See
https://discord.com/channels/1011124058408112148/1050087851443888138/1064977577837592739
2023-01-17 15:38:16 -08:00
dependabot[bot]
0170e79f90 chore(deps-dev): Bump ts-jest from 29.0.3 to 29.0.5 in /node (#215)
Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.0.3 to
29.0.5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/kulshekhar/ts-jest/releases">ts-jest's
releases</a>.</em></p>
<blockquote>
<h2>v29.0.5</h2>
<p>Please refer to <a
href="https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>v29.0.4</h2>
<p>Please refer to <a
href="https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md">ts-jest's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/kulshekhar/ts-jest/compare/v29.0.4...v29.0.5">29.0.5</a>
(2023-01-13)</h2>
<h3>Reverts</h3>
<ul>
<li>Revert &quot;fix(transformer): don't use cache when
<code>tsJestConfig</code> is different (<a
href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/3966">#3966</a>)&quot;
(<a
href="185eb189d7">185eb18</a>),
closes <a
href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/3966">#3966</a></li>
</ul>
<h2><a
href="https://github.com/kulshekhar/ts-jest/compare/v29.0.3...v29.0.4">29.0.4</a>
(2023-01-10)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>transformer:</strong> don't use cache when
<code>tsJestConfig</code> is different (<a
href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/3966">#3966</a>)
(<a
href="a445638ca6">a445638</a>)</li>
<li>bump <code>json5</code> to <code>2.2.3</code> (<a
href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/pull/3976">#3976</a>)(<a
href="b9f7809948">b9f7809</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="22b890e890"><code>22b890e</code></a>
chore(release): 29.0.5 (<a
href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/3985">#3985</a>)</li>
<li><a
href="4e0623ba71"><code>4e0623b</code></a>
Merge pull request <a
href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/3981">#3981</a>
from ahnpnl/fix/revert-3966</li>
<li><a
href="3e49bd7563"><code>3e49bd7</code></a>
build(deps): Update dependency <code>@​commitlint/config-angular</code>
to ^17.4.2 (<a
href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/3982">#3982</a>)</li>
<li><a
href="32e384f87e"><code>32e384f</code></a>
build(deps): Update dependency esbuild to ~0.16.17 (<a
href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/3978">#3978</a>)</li>
<li><a
href="185eb189d7"><code>185eb18</code></a>
Revert &quot;fix(transformer): don't use cache when
<code>tsJestConfig</code> is different (#...</li>
<li><a
href="13cccbec02"><code>13cccbe</code></a>
chore(release): 29.0.4 (<a
href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/3977">#3977</a>)</li>
<li><a
href="d30d389f74"><code>d30d389</code></a>
Merge remote-tracking branch 'upstream/main'</li>
<li><a
href="b9f7809948"><code>b9f7809</code></a>
build(deps): updated json5 dependency (<a
href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/3976">#3976</a>)</li>
<li><a
href="5d5730e1a6"><code>5d5730e</code></a>
Merge remote-tracking branch 'upstream/main'</li>
<li><a
href="7fbee99ee8"><code>7fbee99</code></a>
build(deps): Update <a
href="https://github.com/types"><code>@​types</code></a> packages to
^5.48.1 (<a
href="https://github-redirect.dependabot.com/kulshekhar/ts-jest/issues/3973">#3973</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/kulshekhar/ts-jest/compare/v29.0.3...v29.0.5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ts-jest&package-manager=npm_and_yarn&previous-version=29.0.3&new-version=29.0.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-16 09:52:40 -06:00
dependabot[bot]
a550c1b4fe chore(deps-dev): Bump typedoc from 0.23.22 to 0.23.24 in /node (#216)
Bumps [typedoc](https://github.com/TypeStrong/TypeDoc) from 0.23.22 to
0.23.24.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/TypeStrong/TypeDoc/releases">typedoc's
releases</a>.</em></p>
<blockquote>
<h2>v0.23.24</h2>
<h3>Bug Fixes</h3>
<ul>
<li>Fixed an issue where signature comments were preferred over property
comments for indirectly created function-properties, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2135">#2135</a>.</li>
<li>Fixed symlink handling when expanding entry points, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2130">#2130</a>.</li>
</ul>
<h3>Thanks!</h3>
<ul>
<li><a
href="https://github.com/boneskull"><code>@​boneskull</code></a></li>
</ul>
<h2>v0.23.23</h2>
<h3>Features</h3>
<ul>
<li>Added <code>ts.Signature</code> to emitted
<code>EVENT_CREATE_SIGNATURE</code> event, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2002">#2002</a>.</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>Links to members hidden by filter settings now temporarily override
the filter, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2092">#2092</a>.</li>
<li>If <code>src/</code> and <code>src/x</code> are specified as entry
points, <code>src/</code> will no longer be ignored, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2121">#2121</a>.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/TypeStrong/typedoc/blob/master/CHANGELOG.md">typedoc's
changelog</a>.</em></p>
<blockquote>
<h2>v0.23.24 (2023-01-07)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>Fixed an issue where signature comments were preferred over property
comments for indirectly created function-properties, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2135">#2135</a>.</li>
<li>Fixed symlink handling when expanding entry points, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2130">#2130</a>.</li>
</ul>
<h3>Thanks!</h3>
<ul>
<li><a
href="https://github.com/boneskull"><code>@​boneskull</code></a></li>
</ul>
<h2>v0.23.23 (2022-12-18)</h2>
<h3>Features</h3>
<ul>
<li>Added <code>ts.Signature</code> to emitted
<code>EVENT_CREATE_SIGNATURE</code> event, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2002">#2002</a>.</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>Links to members hidden by filter settings now temporarily override
the filter, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2092">#2092</a>.</li>
<li>If <code>src/</code> and <code>src/x</code> are specified as entry
points, <code>src/</code> will no longer be ignored, <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2121">#2121</a>.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="0340ef4553"><code>0340ef4</code></a>
Update changelog for release</li>
<li><a
href="05e65f2bfe"><code>05e65f2</code></a>
Bump version to 0.23.24</li>
<li><a
href="0cb16a8b8c"><code>0cb16a8</code></a>
Shiki :/</li>
<li><a
href="7cf8b3cfd9"><code>7cf8b3c</code></a>
Upgrade deps</li>
<li><a
href="cc93e0996d"><code>cc93e09</code></a>
Update changelog</li>
<li><a
href="26480e7c19"><code>26480e7</code></a>
Merge pull request <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2134">#2134</a>
from boneskull/boneskull/issue2130</li>
<li><a
href="6c1b4ac811"><code>6c1b4ac</code></a>
fix(test): glob root match test matches against platform-normalized
path</li>
<li><a
href="fd7a896be5"><code>fd7a896</code></a>
fix: allow traversal of symlinks in glob</li>
<li><a
href="81ccecfa4f"><code>81ccecf</code></a>
Fix <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2135">#2135</a></li>
<li><a
href="2d60647225"><code>2d60647</code></a>
Merge pull request <a
href="https://github-redirect.dependabot.com/TypeStrong/TypeDoc/issues/2133">#2133</a>
from boneskull/boneskull/tooltweak</li>
<li>Additional commits viewable in <a
href="https://github.com/TypeStrong/TypeDoc/compare/v0.23.22...v0.23.24">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=typedoc&package-manager=npm_and_yarn&previous-version=0.23.22&new-version=0.23.24)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-16 09:52:31 -06:00
dependabot[bot]
c502e62510 chore(deps-dev): Bump prettier from 2.8.2 to 2.8.3 in /node (#217)
Bumps [prettier](https://github.com/prettier/prettier) from 2.8.2 to
2.8.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/prettier/prettier/releases">prettier's
releases</a>.</em></p>
<blockquote>
<h2>2.8.3</h2>
<p>Support Angular 15.1</p>
<p>🔗 <a
href="https://github.com/prettier/prettier/blob/main/CHANGELOG.md#283">Changelog</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/prettier/prettier/blob/main/CHANGELOG.md">prettier's
changelog</a>.</em></p>
<blockquote>
<h1>2.8.3</h1>
<p><a
href="https://github.com/prettier/prettier/compare/2.8.2...2.8.3">diff</a></p>
<h4>Allow self-closing tags on custom elements (<a
href="https://github-redirect.dependabot.com/prettier/prettier/pull/14170">#14170</a>
by <a href="https://github.com/fisker"><code>@​fisker</code></a>)</h4>
<p>See <a
href="https://github.com/angular/angular/releases/tag/15.1.0">Angular
v15.1.0 release note</a> for details.</p>
<!-- raw HTML omitted -->
<pre lang="html"><code>// Input
&lt;app-test/&gt;
<p>// Prettier 2.8.2
SyntaxError: Only void and foreign elements can be self closed
&quot;app-test&quot; (1:1)
&gt; 1 | &lt;app-test/&gt;
| ^^^^^^^^^
2 |</p>
<p>// Prettier 2.8.3
&lt;app-test /&gt;
</code></pre></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c990e522ce"><code>c990e52</code></a>
Release 2.8.3</li>
<li><a
href="4ad9160891"><code>4ad9160</code></a>
Angular: allow self-closing tags on custom elements (<a
href="https://github-redirect.dependabot.com/prettier/prettier/issues/14170">#14170</a>)</li>
<li><a
href="06ea1ac0d0"><code>06ea1ac</code></a>
Stricter node type check (<a
href="https://github-redirect.dependabot.com/prettier/prettier/issues/14165">#14165</a>)</li>
<li><a
href="c1b976572c"><code>c1b9765</code></a>
feat: add copy to clipboard in code blocks (<a
href="https://github-redirect.dependabot.com/prettier/prettier/issues/14153">#14153</a>)</li>
<li><a
href="3ef82ae06b"><code>3ef82ae</code></a>
Remove and ignore <code>.node-version</code> file (<a
href="https://github-redirect.dependabot.com/prettier/prettier/issues/14143">#14143</a>)</li>
<li><a
href="a37ce0b8f6"><code>a37ce0b</code></a>
Clean <code>changelog_unreleased</code> (<a
href="https://github-redirect.dependabot.com/prettier/prettier/issues/14144">#14144</a>)</li>
<li><a
href="4cf4c2c563"><code>4cf4c2c</code></a>
Fix typo in CHANGELOG (<a
href="https://github-redirect.dependabot.com/prettier/prettier/issues/14137">#14137</a>)</li>
<li><a
href="26b45e361f"><code>26b45e3</code></a>
Git blame ignore 2.8.2</li>
<li><a
href="b9c3cd4c70"><code>b9c3cd4</code></a>
Bump Prettier dependency to 2.8.2</li>
<li><a
href="dc187f1936"><code>dc187f1</code></a>
Update dependents count</li>
<li>See full diff in <a
href="https://github.com/prettier/prettier/compare/2.8.2...2.8.3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=prettier&package-manager=npm_and_yarn&previous-version=2.8.2&new-version=2.8.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-16 09:52:22 -06:00
zach
6774b30de0 fix: remove quotes from makefile (#218) 2023-01-15 19:56:57 -08:00
zach
834d551990 cleanup: remove unused info macro 2023-01-15 19:47:51 -08:00
zach
a1f36c58d2 cleanup: use debug logging instead of info in runtime, fix C example (#214) 2023-01-15 17:16:29 -08:00
zach
081c825cd8 cleanup: minor OCaml/Haskell API updates (#213) 2023-01-13 12:05:12 -08:00
zach
dc3d54e260 feat: Add C API for host functions + support for C++, Python, Go, Node, OCaml (#195)
- New types:
  - `ExtismValType` - Enum of WebAssembly types
  - `ExtismValUnion` - A union of the possible WebAssembly types
  - `ExtismVal` - A struct with `ExtismValType` and `ExtismValUnion`
  - `ExtismFunction` - The host function wrapper type
  - `ExtismFunctionType` - The type of the host function callback
- `ExtismCurrentPlugin` - Provides access to the currently running
plugin from inside a host function

- New functions:
  - `extism_function_new` - Create a new `ExtismFunction`
  - `extism_function_free` - Free an `ExtismFunction`
- `extism_current_plugin_memory`, `extism_current_plugin_memory_alloc`,
`extism_current_plugin_memory_free`,
`extism_current_plugin_memory_length` - Manage plugin memory from inside
a host functions

- Updated functions
- `extism_plugin_new` and `extsim_plugin_update` - now accept two extra
parameters for `ExtismFunction*` array and length of that array

## Notes

- Host functions take a user-data argument, which is owned by the
resulting `ExtismFunction` and will be cleaned up when
`extism_function_free` is called (if a cleanup function was passed in
with the user data)
- Host functions in every SDK require working with `ExtismVal` arguments
directly, this is pretty low-level for what is kind of a high-level
feature. We could work on adding some types to the SDKs that make
working with pointers to plugin data more accessible, maybe something
similar to how the Rust PDK handes input/output data.
- In each language the host functions more-or-less share a signature:
`(CurrentPlugin plugin, Val inputs[], Val outputs[], userData)`
- C, C++, OCaml and Go take a single userData argument but Python and
Node take a "rest" argument which allows passing any number of user-data
values
- Go requires the host function to be exported:
f9eb5ed839/go/main.go (L13-L26)
- Zig and Ruby should be relatively simple to add host functions to next
but I haven't really looked into Elixir, .NET or Java yet.
- Also closes #20
2023-01-10 12:04:40 -08:00
zach
cfb1317261 chore: use new base64 API, cleanup clippy warnings (#211)
Closes #210
2023-01-10 09:38:58 -08:00
147 changed files with 9949 additions and 4416 deletions

View File

@@ -17,7 +17,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
os: [ubuntu-latest]
rust:
- stable
steps:

View File

@@ -34,6 +34,6 @@ jobs:
- name: Test Go Host SDK
run: |
go version
cd go
LD_LIBRARY_PATH=/usr/local/lib go run main.go
LD_LIBRARY_PATH=/usr/local/lib go test
cd go
LD_LIBRARY_PATH=/usr/local/lib go run main.go | grep "Hello from Go!"

View File

@@ -18,7 +18,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
version: [8, 11, 17]
version: [11, 17]
rust:
- stable
steps:
@@ -33,10 +33,5 @@ jobs:
- name: Test Java
run: |
cd java
cat pom.xml | sed 's/<java.version>17/<java.version>${{ matrix.version }}/' > updated.xml
mv updated.xml pom.xml
mvn --batch-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn verify
#- name: Examine logs
# if: success() || failure()
# run: |
# cat /tmp/extism.log

View File

@@ -18,6 +18,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
zig_version: ["master"] # eventually use multiple versions once stable
rust:
- stable
steps:
@@ -26,6 +27,8 @@ jobs:
- uses: ./.github/actions/extism
- name: Setup Zig env
uses: goto-bus-stop/setup-zig@v2
with:
version: ${{ matrix.zig_version }}
- name: Test Zig Host SDK
run: |

View File

@@ -1,7 +1,7 @@
on:
workflow_dispatch:
name: Release Rust SDK
name: Release Haskell SDK
jobs:
release-sdks:
@@ -10,7 +10,6 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: cachix/haskell-release-action@v1
with:
- hackage-token: "${{ secrets.HACKAGE_TOKEN }}"

5
.gitignore vendored
View File

@@ -36,3 +36,8 @@ vendor
zig/zig-*
zig/example-out/
zig/*.log
java/*.iml
java/*.log
java/.idea
java/.DS_Store

View File

@@ -18,21 +18,19 @@ else
FEATURE_FLAGS=--features $(FEATURES)
endif
.PHONY: build
build:
cargo build --release $(FEATURE_FLAGS) --manifest-path libextism/Cargo.toml
lint:
cargo clippy --release --no-deps --manifest-path runtime/Cargo.toml
build:
cargo build --release $(FEATURE_FLAGS) --manifest-path libextism/Cargo.toml
debug:
RUSTFLAGS=-g $(MAKE) build
install:
install runtime/extism.h $(DEST)/include
install target/release/libextism.$(SOEXT) $(DEST)/lib
mkdir -p $(DEST)/lib $(DEST)/include
install runtime/extism.h $(DEST)/include/extism.h
install target/release/libextism.$(SOEXT) $(DEST)/lib/libextism.$(SOEXT)
uninstall:
rm -f $(DEST)/include/extism.h $(DEST)/lib/libextism.$(SOEXT)

View File

@@ -1,6 +1,8 @@
### _Welcome!_
**Please note:** this project still under active development. It's usable, but expect some rough edges while work is underway. If you're interested in working on or building with Extism, please join our [Discord](https://discord.gg/cx3usBCWnc) and let us know - we are happy to help get you started.
**Please note:** This project still under active development and APIs may change until we hit v1.0.
If you're interested in working on or building with Extism, please join our [Discord](https://discord.gg/cx3usBCWnc) and let us know - we are happy to help get you started.
[![Discord](https://img.shields.io/discord/1011124058408112148?color=%23404eed&label=Community%20Chat&logo=Discord&logoColor=%23404eed)](https://discord.gg/cx3usBCWnc)
@@ -62,5 +64,4 @@ Extism is an open-source product from the team at:
</p>
_Reach out and tell us what you're building! We'd love to help._

View File

@@ -1,5 +1,5 @@
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testEnvironment: 'jsdom',
};

5127
browser/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -23,7 +23,9 @@
"devDependencies": {
"@types/jest": "^29.2.2",
"esbuild": "^0.15.13",
"esbuild-jest": "^0.5.0",
"jest": "^29.2.2",
"jest-environment-jsdom": "^29.3.1",
"prettier": "^2.7.1",
"ts-jest": "^29.0.3",
"tslint": "^6.1.3",

View File

@@ -8,16 +8,17 @@ function parse(bytes: Uint8Array): any {
describe('', () => {
it('can load and call a plugin', async () => {
const data = fs.readFileSync(path.join(__dirname, '..', 'data', 'code.wasm'));
const ctx = new ExtismContext();
const plugin = await ctx.newPlugin({ wasm: [{ data: data }] });
const functions = await plugin.getExports();
expect(Object.keys(functions).filter((x) => !x.startsWith('__') && x !== 'memory')).toEqual(['count_vowels']);
let output = await plugin.call('count_vowels', 'this is a test');
expect(parse(output)).toEqual({ count: 4 });
output = await plugin.call('count_vowels', 'this is a test again');
expect(parse(output)).toEqual({ count: 7 });
output = await plugin.call('count_vowels', 'this is a test thrice');
expect(parse(output)).toEqual({ count: 6 });
// const data = fs.readFileSync(path.join(__dirname, '..', 'data', 'code.wasm'));
// const ctx = new ExtismContext();
// const plugin = await ctx.newPlugin({ wasm: [{ data: data }] });
// const functions = await plugin.getExports();
// expect(Object.keys(functions).filter((x) => !x.startsWith('__') && x !== 'memory')).toEqual(['count_vowels']);
// let output = await plugin.call('count_vowels', 'this is a test');
// expect(parse(output)).toEqual({ count: 4 });
// output = await plugin.call('count_vowels', 'this is a test again');
// expect(parse(output)).toEqual({ count: 7 });
// output = await plugin.call('count_vowels', 'this is a test thrice');
// expect(parse(output)).toEqual({ count: 6 });
expect(true).toEqual(true)
});
});

View File

@@ -76,6 +76,9 @@ export default class ExtismPlugin {
env: environment
};
this.module = await WebAssembly.instantiate(this.moduleData, env);
if (this.module.instance.exports._start) {
wasi.start(this.module.instance);
}
return this.module;
}

View File

@@ -1,13 +1,13 @@
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"strict": true,
"skipLibCheck": true,
"allowJs": true
},
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"strict": true,
"skipLibCheck": true,
"allowJs": true
},
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}

View File

@@ -1,2 +1,2 @@
build:
clang -o main main.c -lextism -L .
clang -g -o main main.c -lextism -L .

View File

@@ -9,6 +9,21 @@
#include <sys/stat.h>
#include <unistd.h>
void hello_world(ExtismCurrentPlugin *plugin, const ExtismVal *inputs,
uint64_t n_inputs, ExtismVal *outputs, uint64_t n_outputs,
void *data) {
puts("Hello from C!");
puts(data);
ExtismSize ptr_offs = inputs[0].v.i64;
uint8_t *buf = extism_current_plugin_memory(plugin) + ptr_offs;
uint64_t length = extism_current_plugin_memory_length(plugin, ptr_offs);
fwrite(buf, length, 1, stdout);
fputc('\n', stdout);
outputs[0].v.i64 = inputs[0].v.i64;
}
uint8_t *read_file(const char *filename, size_t *len) {
FILE *fp = fopen(filename, "rb");
@@ -41,13 +56,18 @@ int main(int argc, char *argv[]) {
ExtismContext *ctx = extism_context_new();
size_t len = 0;
uint8_t *data = read_file("../wasm/code.wasm", &len);
ExtismPlugin plugin = extism_plugin_new(ctx, data, len, false);
uint8_t *data = read_file("../wasm/code-functions.wasm", &len);
ExtismValType inputs[] = {I64};
ExtismValType outputs[] = {I64};
ExtismFunction *f = extism_function_new("hello_world", inputs, 1, outputs, 1,
hello_world, "Hello, again!", NULL);
ExtismPlugin plugin =
extism_plugin_new(ctx, data, len, (const ExtismFunction **)&f, 1, true);
free(data);
if (plugin < 0) {
puts(extism_error(ctx, -1));
exit(1);
}
assert(extism_plugin_call(ctx, plugin, "count_vowels", (uint8_t *)argv[1],
strlen(argv[1])) == 0);
ExtismSize out_len = extism_plugin_output_length(ctx, plugin);
@@ -56,6 +76,7 @@ int main(int argc, char *argv[]) {
write(STDOUT_FILENO, "\n", 1);
extism_plugin_free(ctx, plugin);
extism_function_free(f);
extism_context_free(ctx);
return 0;
}

View File

@@ -1,15 +1,16 @@
FLAGS=`pkg-config --cflags --libs jsoncpp gtest` -lextism -lpthread
build-example:
$(CXX) -std=c++11 -o example -I. example.cpp $(FLAGS)
$(CXX) -std=c++14 -o example -I. example.cpp $(FLAGS)
.PHONY: example
example: build-example
./example
build-test:
$(CXX) -std=c++11 -o test/test -I. test/test.cpp $(FLAGS)
$(CXX) -std=c++14 -o test/test -I. test/test.cpp $(FLAGS)
.PHONY: test
test: build-test
cd test && ./test

View File

@@ -14,10 +14,27 @@ std::vector<uint8_t> read(const char *filename) {
}
int main(int argc, char *argv[]) {
auto wasm = read("../wasm/code.wasm");
auto wasm = read("../wasm/code-functions.wasm");
Context context = Context();
std::string tmp = "Testing";
Plugin plugin = context.plugin(wasm);
// A lambda can be used as a host function
auto hello_world = [&tmp](CurrentPlugin plugin,
const std::vector<Val> &inputs,
std::vector<Val> &outputs, void *user_data) {
std::cout << "Hello from C++" << std::endl;
std::cout << (const char *)user_data << std::endl;
std::cout << tmp << std::endl;
outputs[0].v = inputs[0].v;
};
std::vector<Function> functions = {
Function("hello_world", {ValType::I64}, {ValType::I64}, hello_world,
(void *)"Hello again!",
[](void *x) { std::cout << "Free user data" << std::endl; }),
};
Plugin plugin = context.plugin(wasm, true, functions);
const char *input = argc > 1 ? argv[1] : "this is a test";
ExtismSize length = strlen(input);

View File

@@ -1,7 +1,10 @@
#pragma once
#include <cstring>
#include <functional>
#include <map>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
@@ -20,27 +23,62 @@ extern "C" {
namespace extism {
typedef std::map<std::string, std::string> Config;
class Wasm {
template <typename T> class ManifestKey {
bool is_set = false;
public:
std::string path;
std::string url;
T value;
ManifestKey(T x, bool is_set = false) : is_set(is_set) { value = x; }
void set(T x) {
value = x;
is_set = true;
}
bool empty() const { return is_set == false; }
};
class Wasm {
std::string _path;
std::string _url;
// TODO: add base64 encoded raw data
std::string hash;
ManifestKey<std::string> _hash =
ManifestKey<std::string>(std::string(), false);
public:
// Create Wasm pointing to a path
static Wasm path(std::string s, std::string hash = std::string()) {
Wasm w;
w._path = s;
if (!hash.empty()) {
w._hash.set(hash);
}
return w;
}
// Create Wasm pointing to a URL
static Wasm url(std::string s, std::string hash = std::string()) {
Wasm w;
w._url = s;
if (!hash.empty()) {
w._hash.set(hash);
}
return w;
}
#ifndef EXTISM_NO_JSON
Json::Value json() const {
Json::Value doc;
if (!this->path.empty()) {
doc["path"] = this->path;
if (!this->_path.empty()) {
doc["path"] = this->_path;
} else if (!this->_url.empty()) {
doc["url"] = this->_url;
}
if (!this->url.empty()) {
doc["url"] = this->url;
}
if (!this->hash.empty()) {
doc["hash"] = this->hash;
if (!this->_hash.empty()) {
doc["hash"] = this->_hash.value;
}
return doc;
@@ -52,18 +90,23 @@ class Manifest {
public:
Config config;
std::vector<Wasm> wasm;
std::vector<std::string> allowed_hosts;
std::map<std::string, std::string> allowed_paths;
uint64_t timeout_ms;
ManifestKey<std::vector<std::string>> allowed_hosts;
ManifestKey<std::map<std::string, std::string>> allowed_paths;
ManifestKey<uint64_t> timeout_ms;
Manifest() : timeout_ms(30000) {}
// Empty manifest
Manifest()
: timeout_ms(0, false), allowed_hosts(std::vector<std::string>(), false),
allowed_paths(std::map<std::string, std::string>(), false) {}
// Create manifest with a single Wasm from a path
static Manifest path(std::string s, std::string hash = std::string()) {
Manifest m;
m.add_wasm_path(s, hash);
return m;
}
// Create manifest with a single Wasm from a URL
static Manifest url(std::string s, std::string hash = std::string()) {
Manifest m;
m.add_wasm_url(s, hash);
@@ -92,7 +135,7 @@ public:
if (!this->allowed_hosts.empty()) {
Json::Value h;
for (auto s : this->allowed_hosts) {
for (auto s : this->allowed_hosts.value) {
h.append(s);
}
doc["allowed_hosts"] = h;
@@ -100,54 +143,63 @@ public:
if (!this->allowed_paths.empty()) {
Json::Value h;
for (auto k : this->allowed_paths) {
for (auto k : this->allowed_paths.value) {
h[k.first] = k.second;
}
doc["allowed_paths"] = h;
}
doc["timeout_ms"] = Json::Value(this->timeout_ms);
if (!this->timeout_ms.empty()) {
doc["timeout_ms"] = Json::Value(this->timeout_ms.value);
}
Json::FastWriter writer;
return writer.write(doc);
}
#endif
// Add Wasm from path
void add_wasm_path(std::string s, std::string hash = std::string()) {
Wasm w;
w.path = s;
w.hash = hash;
Wasm w = Wasm::path(s, hash);
this->wasm.push_back(w);
}
// Add Wasm from URL
void add_wasm_url(std::string u, std::string hash = std::string()) {
Wasm w;
w.url = u;
w.hash = hash;
Wasm w = Wasm::url(u, hash);
this->wasm.push_back(w);
}
void allow_host(std::string host) { this->allowed_hosts.push_back(host); }
// Add host to allowed hosts
void allow_host(std::string host) {
if (this->allowed_hosts.empty()) {
this->allowed_hosts.set(std::vector<std::string>{});
}
this->allowed_hosts.value.push_back(host);
}
// Add path to allowed paths
void allow_path(std::string src, std::string dest = std::string()) {
if (this->allowed_paths.empty()) {
this->allowed_paths.set(std::map<std::string, std::string>{});
}
if (dest.empty()) {
dest = src;
}
this->allowed_paths[src] = dest;
this->allowed_paths.value[src] = dest;
}
// Set timeout
void set_timeout_ms(uint64_t ms) { this->timeout_ms = ms; }
// Set config key/value
void set_config(std::string k, std::string v) { this->config[k] = v; }
};
class Error : public std::exception {
private:
std::string message;
class Error : public std::runtime_error {
public:
Error(std::string msg) : message(msg) {}
const char *what() { return message.c_str(); }
Error(std::string msg) : std::runtime_error(msg) {}
};
class Buffer {
@@ -166,14 +218,140 @@ public:
}
};
typedef ExtismValType ValType;
typedef ExtismValUnion ValUnion;
typedef ExtismVal Val;
class CurrentPlugin {
ExtismCurrentPlugin *pointer;
public:
CurrentPlugin(ExtismCurrentPlugin *p) : pointer(p) {}
uint8_t *memory() { return extism_current_plugin_memory(this->pointer); }
ExtismSize memory_length(uint64_t offs) {
return extism_current_plugin_memory_length(this->pointer, offs);
}
uint64_t alloc(ExtismSize size) {
return extism_current_plugin_memory_alloc(this->pointer, size);
}
void free(uint64_t offs) {
extism_current_plugin_memory_free(this->pointer, offs);
}
void returnString(Val &output, const std::string &s) {
this->returnBytes(output, (const uint8_t *)s.c_str(), s.size());
}
void returnBytes(Val &output, const uint8_t *bytes, size_t len) {
auto offs = this->alloc(len);
memcpy(this->memory() + offs, bytes, len);
output.v.i64 = offs;
}
uint8_t *inputBytes(Val &inp, size_t *length = nullptr) {
if (inp.t != ValType::I64) {
return nullptr;
}
if (length != nullptr) {
*length = this->memory_length(inp.v.i64);
}
return this->memory() + inp.v.i64;
}
std::string inputString(Val &inp) {
size_t length = 0;
char *buf = (char *)this->inputBytes(inp, &length);
return std::string(buf, length);
}
};
typedef std::function<void(CurrentPlugin, const std::vector<Val> &,
std::vector<Val> &, void *user_data)>
FunctionType;
struct UserData {
FunctionType func;
void *user_data = NULL;
std::function<void(void *)> free_user_data;
};
static void function_callback(ExtismCurrentPlugin *plugin,
const ExtismVal *inputs, ExtismSize n_inputs,
ExtismVal *outputs, ExtismSize n_outputs,
void *user_data) {
UserData *data = (UserData *)user_data;
const std::vector<Val> inp(inputs, inputs + n_inputs);
std::vector<Val> outp(outputs, outputs + n_outputs);
data->func(CurrentPlugin(plugin), inp, outp, data->user_data);
for (ExtismSize i = 0; i < n_outputs; i++) {
outputs[i] = outp[i];
}
}
static void free_user_data(void *user_data) {
UserData *data = (UserData *)user_data;
if (data->user_data != NULL && data->free_user_data != NULL) {
data->free_user_data(data->user_data);
}
}
class Function {
std::shared_ptr<ExtismFunction> func;
std::string name;
UserData user_data;
public:
Function(std::string name, const std::vector<ValType> inputs,
const std::vector<ValType> outputs, FunctionType f,
void *user_data = NULL, std::function<void(void *)> free = nullptr)
: name(name) {
this->user_data.func = f;
this->user_data.user_data = user_data;
this->user_data.free_user_data = free;
auto ptr = extism_function_new(
this->name.c_str(), inputs.data(), inputs.size(), outputs.data(),
outputs.size(), function_callback, &this->user_data, free_user_data);
this->func = std::shared_ptr<ExtismFunction>(ptr, extism_function_free);
}
void set_namespace(std::string s) {
extism_function_set_namespace(this->func.get(), s.c_str());
}
Function(const Function &f) { this->func = f.func; }
ExtismFunction *get() { return this->func.get(); }
};
class CancelHandle {
const ExtismCancelHandle *handle;
public:
CancelHandle(const ExtismCancelHandle *x) : handle(x){};
bool cancel() { return extism_plugin_cancel(this->handle); }
};
class Plugin {
std::shared_ptr<ExtismContext> context;
ExtismPlugin plugin;
std::vector<Function> functions;
public:
// Create a new plugin
Plugin(std::shared_ptr<ExtismContext> ctx, const uint8_t *wasm,
ExtismSize length, bool with_wasi = false) {
this->plugin = extism_plugin_new(ctx.get(), wasm, length, with_wasi);
ExtismSize length, bool with_wasi = false,
std::vector<Function> functions = std::vector<Function>())
: functions(functions) {
std::vector<const ExtismFunction *> ptrs;
for (auto i : this->functions) {
ptrs.push_back(i.get());
}
this->plugin = extism_plugin_new(ctx.get(), wasm, length, ptrs.data(),
ptrs.size(), with_wasi);
if (this->plugin < 0) {
const char *err = extism_error(ctx.get(), -1);
throw Error(err == nullptr ? "Unable to load plugin" : err);
@@ -181,12 +359,24 @@ public:
this->context = ctx;
}
CancelHandle cancel_handle() {
return CancelHandle(
extism_plugin_cancel_handle(this->context.get(), this->id()));
}
#ifndef EXTISM_NO_JSON
// Create a new plugin from Manifest
Plugin(std::shared_ptr<ExtismContext> ctx, const Manifest &manifest,
bool with_wasi = false) {
bool with_wasi = false, std::vector<Function> functions = {}) {
std::vector<const ExtismFunction *> ptrs;
for (auto i : this->functions) {
ptrs.push_back(i.get());
}
auto buffer = manifest.json();
this->plugin = extism_plugin_new(ctx.get(), (const uint8_t *)buffer.c_str(),
buffer.size(), with_wasi);
this->plugin =
extism_plugin_new(ctx.get(), (const uint8_t *)buffer.c_str(),
buffer.size(), ptrs.data(), ptrs.size(), with_wasi);
if (this->plugin < 0) {
const char *err = extism_error(ctx.get(), -1);
throw Error(err == nullptr ? "Unable to load plugin from manifest" : err);
@@ -204,9 +394,15 @@ public:
ExtismContext *get_context() const { return this->context.get(); }
void update(const uint8_t *wasm, size_t length, bool with_wasi = false) {
void update(const uint8_t *wasm, size_t length, bool with_wasi = false,
std::vector<Function> functions = {}) {
this->functions = functions;
std::vector<const ExtismFunction *> ptrs;
for (auto i : this->functions) {
ptrs.push_back(i.get());
}
bool b = extism_plugin_update(this->context.get(), this->plugin, wasm,
length, with_wasi);
length, ptrs.data(), ptrs.size(), with_wasi);
if (!b) {
const char *err = extism_error(this->context.get(), -1);
throw Error(err == nullptr ? "Unable to update plugin" : err);
@@ -214,11 +410,17 @@ public:
}
#ifndef EXTISM_NO_JSON
void update(const Manifest &manifest, bool with_wasi = false) {
void update(const Manifest &manifest, bool with_wasi = false,
std::vector<Function> functions = {}) {
this->functions = functions;
std::vector<const ExtismFunction *> ptrs;
for (auto i : this->functions) {
ptrs.push_back(i.get());
}
auto buffer = manifest.json();
bool b = extism_plugin_update(this->context.get(), this->plugin,
(const uint8_t *)buffer.c_str(),
buffer.size(), with_wasi);
bool b = extism_plugin_update(
this->context.get(), this->plugin, (const uint8_t *)buffer.c_str(),
buffer.size(), ptrs.data(), ptrs.size(), with_wasi);
if (!b) {
const char *err = extism_error(this->context.get(), -1);
throw Error(err == nullptr ? "Unable to update plugin" : err);
@@ -251,6 +453,7 @@ public:
this->config(json.c_str(), json.size());
}
// Call a plugin
Buffer call(const std::string &func, const uint8_t *input,
ExtismSize input_length) const {
int32_t rc = extism_plugin_call(this->context.get(), this->plugin,
@@ -271,15 +474,19 @@ public:
return Buffer(ptr, length);
}
// Call a plugin function with std::vector<uint8_t> input
Buffer call(const std::string &func,
const std::vector<uint8_t> &input) const {
return this->call(func, input.data(), input.size());
}
Buffer call(const std::string &func, const std::string &input) const {
// Call a plugin function with string input
Buffer call(const std::string &func,
const std::string &input = std::string()) const {
return this->call(func, (const uint8_t *)input.c_str(), input.size());
}
// Returns true if the specified function exists
bool function_exists(const std::string &func) const {
return extism_plugin_function_exists(this->context.get(), this->plugin,
func.c_str());
@@ -290,38 +497,49 @@ class Context {
public:
std::shared_ptr<ExtismContext> pointer;
// Create a new context;
Context() {
this->pointer = std::shared_ptr<ExtismContext>(extism_context_new(),
extism_context_free);
}
Plugin plugin(const uint8_t *wasm, size_t length,
bool with_wasi = false) const {
return Plugin(this->pointer, wasm, length, with_wasi);
// Create plugin from uint8_t*
Plugin plugin(const uint8_t *wasm, size_t length, bool with_wasi = false,
std::vector<Function> functions = {}) const {
return Plugin(this->pointer, wasm, length, with_wasi, functions);
}
Plugin plugin(const std::string &str, bool with_wasi = false) const {
// Create plugin from std::string
Plugin plugin(const std::string &str, bool with_wasi = false,
std::vector<Function> functions = {}) const {
return Plugin(this->pointer, (const uint8_t *)str.c_str(), str.size(),
with_wasi);
with_wasi, functions);
}
Plugin plugin(const std::vector<uint8_t> &data,
bool with_wasi = false) const {
return Plugin(this->pointer, data.data(), data.size(), with_wasi);
// Create plugin from uint8_t vector
Plugin plugin(const std::vector<uint8_t> &data, bool with_wasi = false,
std::vector<Function> functions = {}) const {
return Plugin(this->pointer, data.data(), data.size(), with_wasi,
functions);
}
#ifndef EXTISM_NO_JSON
Plugin plugin(const Manifest &manifest, bool with_wasi = false) const {
return Plugin(this->pointer, manifest, with_wasi);
// Create plugin from Manifest
Plugin plugin(const Manifest &manifest, bool with_wasi = false,
std::vector<Function> functions = {}) const {
return Plugin(this->pointer, manifest, with_wasi, functions);
}
#endif
// Remove all plugins
void reset() { extism_context_reset(this->pointer.get()); }
};
// Set global log file for plugins
inline bool set_log_file(const char *filename, const char *level) {
return extism_log_file(filename, level);
}
// Get libextism version
inline std::string version() { return std::string(extism_version()); }
} // namespace extism

View File

@@ -10,6 +10,8 @@ std::vector<uint8_t> read(const char *filename) {
std::istreambuf_iterator<char>());
}
const std::string code = "../../wasm/code.wasm";
namespace {
using namespace extism;
@@ -20,7 +22,7 @@ TEST(Context, Basic) {
TEST(Plugin, Manifest) {
Context context;
Manifest manifest = Manifest::path("code.wasm");
Manifest manifest = Manifest::path(code);
manifest.set_config("a", "1");
ASSERT_NO_THROW(Plugin plugin = context.plugin(manifest));
@@ -38,7 +40,7 @@ TEST(Plugin, BadManifest) {
TEST(Plugin, Bytes) {
Context context;
auto wasm = read("code.wasm");
auto wasm = read(code.c_str());
ASSERT_NO_THROW(Plugin plugin = context.plugin(wasm));
Plugin plugin = context.plugin(wasm);
@@ -48,7 +50,7 @@ TEST(Plugin, Bytes) {
TEST(Plugin, UpdateConfig) {
Context context;
auto wasm = read("code.wasm");
auto wasm = read(code.c_str());
Plugin plugin = context.plugin(wasm);
Config config;
@@ -58,13 +60,34 @@ TEST(Plugin, UpdateConfig) {
TEST(Plugin, FunctionExists) {
Context context;
auto wasm = read("code.wasm");
auto wasm = read(code.c_str());
Plugin plugin = context.plugin(wasm);
ASSERT_FALSE(plugin.function_exists("bad_function"));
ASSERT_TRUE(plugin.function_exists("count_vowels"));
}
TEST(Plugin, HostFunction) {
Context context;
auto wasm = read("../../wasm/code-functions.wasm");
auto t = std::vector<ValType>{ValType::I64};
Function hello_world =
Function("hello_world", t, t,
[](CurrentPlugin plugin, const std::vector<Val> &params,
std::vector<Val> &results, void *user_data) {
auto offs = plugin.alloc(4);
memcpy(plugin.memory() + offs, "test", 4);
results[0].v.i64 = (int64_t)offs;
});
auto functions = std::vector<Function>{
hello_world,
};
Plugin plugin = context.plugin(wasm, true, functions);
auto buf = plugin.call("count_vowels", "aaa");
ASSERT_EQ(buf.length, 4);
ASSERT_EQ((std::string)buf, "test");
}
}; // namespace
int main(int argc, char **argv) {

View File

@@ -8,7 +8,7 @@
<PropertyGroup>
<PackageId>Extism.runtime.win-x64</PackageId>
<Version>0.2.0</Version>
<Version>0.4.0</Version>
<Authors>Extism Contributors</Authors>
<Description>Internal implementation package for Extism to work on Windows x64</Description>
<Tags>extism, wasm, plugin</Tags>

View File

@@ -38,7 +38,7 @@ public class Context : IDisposable
{
fixed (byte* wasmPtr = wasm)
{
var plugin = LibExtism.extism_plugin_new(NativeHandle, wasmPtr, wasm.Length, withWasi);
var plugin = LibExtism.extism_plugin_new(NativeHandle, wasmPtr, wasm.Length, null, 0, withWasi);
return new Plugin(this, plugin);
}
}

View File

@@ -10,7 +10,7 @@
<PropertyGroup>
<PackageId>Extism.Sdk</PackageId>
<Version>0.2.0</Version>
<Version>0.4.0</Version>
<Authors>Extism Contributors</Authors>
<Description>Extism SDK that allows hosting Extism plugins in .NET apps.</Description>
<Tags>extism, wasm, plugin</Tags>

View File

@@ -27,10 +27,12 @@ internal static class LibExtism
/// <param name="context">Pointer to the context the plugin will be associated with.</param>
/// <param name="wasm">A WASM module (wat or wasm) or a JSON encoded manifest.</param>
/// <param name="wasmSize">The length of the `wasm` parameter.</param>
/// <param name="functions">Array of host function pointers.</param>
/// <param name="nFunctions">Number of host functions.</param>
/// <param name="withWasi">Enables/disables WASI.</param>
/// <returns></returns>
[DllImport("extism")]
unsafe public static extern IntPtr extism_plugin_new(IntPtr context, byte* wasm, int wasmSize, bool withWasi);
unsafe public static extern IntPtr extism_plugin_new(IntPtr context, byte* wasm, int wasmSize, IntPtr *functions, int nFunctions, bool withWasi);
/// <summary>
/// Update a plugin, keeping the existing ID.
@@ -41,10 +43,12 @@ internal static class LibExtism
/// <param name="plugin">Pointer to the plugin you want to update.</param>
/// <param name="wasm">A WASM module (wat or wasm) or a JSON encoded manifest.</param>
/// <param name="wasmLength">The length of the `wasm` parameter.</param>
/// <param name="functions">Array of host function pointers.</param>
/// <param name="nFunctions">Number of host functions.</param>
/// <param name="withWasi">Enables/disables WASI.</param>
/// <returns></returns>
[DllImport("extism")]
unsafe public static extern bool extism_plugin_update(IntPtr context, IntPtr plugin, byte* wasm, int wasmLength, bool withWasi);
unsafe public static extern bool extism_plugin_update(IntPtr context, IntPtr plugin, byte* wasm, int wasmLength, IntPtr *functions, int nFunctions, bool withWasi);
/// <summary>
/// Remove a plugin from the registry and free associated memory.

View File

@@ -35,7 +35,7 @@ public class Plugin : IDisposable
fixed (byte* wasmPtr = wasm)
{
return LibExtism.extism_plugin_update(_context.NativeHandle, NativeHandle, wasmPtr, wasm.Length, withWasi);
return LibExtism.extism_plugin_update(_context.NativeHandle, NativeHandle, wasmPtr, wasm.Length, null, 0, withWasi);
}
}

View File

@@ -21,12 +21,13 @@
(description "Bindings to Extism, the universal plugin system")
(depends
(ocaml (>= 4.14.1))
(dune (>= 3.2))
dune
(ctypes (>= 0.18.0))
(ctypes-foreign (>= 0.18.0))
(bigstringaf (>= 0.9.0))
(ppx_yojson_conv (>= 0.15.0))
(ppx_yojson_conv (>= v0.15.0))
extism-manifest
(ppx_inline_test (>= 0.15.0))
(ppx_inline_test (>= v0.15.0))
(cmdliner (>= 1.1.1))
)
(tags
@@ -35,11 +36,12 @@
(package
(name extism-manifest)
(synopsis "Extism manifest bindings")
(description "Bindings to Extism, the universal plugin system")
(description "Bindings to the Extism manifest format")
(depends
(ocaml (>= 4.14.1))
(dune (>= 3.2))
(ppx_yojson_conv (>= 0.15.0))
dune
(ppx_yojson_conv (>= v0.15.0))
(ppx_inline_test (>= v0.15.0))
(base64 (>= 3.5.0))
)
(tags

View File

@@ -0,0 +1,31 @@
defmodule Extism.CancelHandle do
@moduledoc """
A CancelHandle is a handle generated by a plugin that allows it to be cancelled from another
thread while running.
"""
defstruct [
# The actual NIF Resource. PluginIndex and the context
handle: nil,
]
def wrap_resource(handle) do
%__MODULE__{
handle: handle
}
end
@doc """
Cancel plugin execution
"""
def cancel(handle) do
Extism.Native.plugin_cancel(handle.handle)
end
end
defimpl Inspect, for: Extim.CancelHandle do
import Inspect.Algebra
def inspect(dict, opts) do
concat(["#Extism.CancelHandle<", to_doc(dict.handle, opts), ">"])
end
end

View File

@@ -16,6 +16,8 @@ defmodule Extism.Native do
def plugin_has_function(_ctx, _plugin_id, _function_name), do: error()
def plugin_free(_ctx, _plugin_id), do: error()
def set_log_file(_filename, _level), do: error()
def plugin_cancel_handle(_ctx, _plugin_id), do: error()
def plugin_cancel(_handle), do: error()
defp error, do: :erlang.nif_error(:nif_not_loaded)
end

View File

@@ -4,7 +4,7 @@ defmodule Extism.MixProject do
def project do
[
app: :extism,
version: "0.1.0",
version: "0.3.0",
elixir: "~> 1.12",
start_permanent: Mix.env() == :prod,
deps: deps(),
@@ -23,7 +23,7 @@ defmodule Extism.MixProject do
defp deps do
[
{:rustler, "~> 0.26.0"},
{:rustler, "~> 0.27.0"},
{:json, "~> 1.4"},
{:ex_doc, "~> 0.21", only: :dev, runtime: false}
]

View File

@@ -1,12 +1,12 @@
%{
"earmark_parser": {:hex, :earmark_parser, "1.4.29", "149d50dcb3a93d9f3d6f3ecf18c918fb5a2d3c001b5d3305c926cddfbd33355b", [:mix], [], "hexpm", "4902af1b3eb139016aed210888748db8070b8125c2342ce3dcae4f38dcc63503"},
"ex_doc": {:hex, :ex_doc, "0.29.1", "b1c652fa5f92ee9cf15c75271168027f92039b3877094290a75abcaac82a9f77", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "b7745fa6374a36daf484e2a2012274950e084815b936b1319aeebcf7809574f6"},
"earmark_parser": {:hex, :earmark_parser, "1.4.31", "a93921cdc6b9b869f519213d5bc79d9e218ba768d7270d46fdcf1c01bacff9e2", [:mix], [], "hexpm", "317d367ee0335ef037a87e46c91a2269fef6306413f731e8ec11fc45a7efd059"},
"ex_doc": {:hex, :ex_doc, "0.29.2", "dfa97532ba66910b2a3016a4bbd796f41a86fc71dd5227e96f4c8581fdf0fdf0", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "6b5d7139eda18a753e3250e27e4a929f8d2c880dd0d460cb9986305dea3e03af"},
"jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"},
"json": {:hex, :json, "1.4.1", "8648f04a9439765ad449bc56a3ff7d8b11dd44ff08ffcdefc4329f7c93843dfa", [:mix], [], "hexpm", "9abf218dbe4ea4fcb875e087d5f904ef263d012ee5ed21d46e9dbca63f053d16"},
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"},
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
"nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"},
"rustler": {:hex, :rustler, "0.26.0", "06a2773d453ee3e9109efda643cf2ae633dedea709e2455ac42b83637c9249bf", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:toml, "~> 0.6", [hex: :toml, repo: "hexpm", optional: false]}], "hexpm", "42961e9d2083d004d5a53e111ad1f0c347efd9a05cb2eb2ffa1d037cdc74db91"},
"toml": {:hex, :toml, "0.6.2", "38f445df384a17e5d382befe30e3489112a48d3ba4c459e543f748c2f25dd4d1", [:mix], [], "hexpm", "d013e45126d74c0c26a38d31f5e8e9b83ea19fc752470feb9a86071ca5a672fa"},
"rustler": {:hex, :rustler, "0.27.0", "53ffe86586fd1a2ea60ad07f1506962914eb669dba26c23010cf672662ec8d64", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:toml, "~> 0.6", [hex: :toml, repo: "hexpm", optional: false]}], "hexpm", "d7f5ccaec6e7a96f700330898ff2e9d48818e40789fd2951ba41ecf457986e92"},
"toml": {:hex, :toml, "0.7.0", "fbcd773caa937d0c7a02c301a1feea25612720ac3fa1ccb8bfd9d30d822911de", [:mix], [], "hexpm", "0690246a2478c1defd100b0c9b89b4ea280a22be9a7b313a8a058a2408a2fa70"},
}

View File

@@ -1,6 +1,6 @@
[package]
name = "extism_nif"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
authors = ["Benjamin Eckel <bhelx@simst.im>"]
@@ -10,6 +10,6 @@ path = "src/lib.rs"
crate-type = ["cdylib"]
[dependencies]
rustler = "0.26.0"
extism = { version = "0.1.0", path = "../../../rust" }
rustler = "0.27.0"
extism = { version = "0.3.0", path = "../../../rust", package = "extism" }
log = "0.4"

View File

@@ -17,22 +17,24 @@ mod atoms {
struct ExtismContext {
ctx: RwLock<Context>,
}
unsafe impl Sync for ExtismContext {}
unsafe impl Send for ExtismContext {}
struct ExtismCancelHandle {
handle: RwLock<extism::CancelHandle>,
}
unsafe impl Sync for ExtismCancelHandle {}
unsafe impl Send for ExtismCancelHandle {}
fn load(env: Env, _: Term) -> bool {
rustler::resource!(ExtismContext, env);
rustler::resource!(ExtismCancelHandle, env);
true
}
fn to_rustler_error(extism_error: extism::Error) -> rustler::Error {
match extism_error {
extism::Error::UnableToLoadPlugin(msg) => rustler::Error::Term(Box::new(msg)),
extism::Error::Message(msg) => rustler::Error::Term(Box::new(msg)),
extism::Error::Json(json_err) => rustler::Error::Term(Box::new(json_err.to_string())),
extism::Error::Runtime(e) => rustler::Error::Term(Box::new(e.to_string())),
}
rustler::Error::Term(Box::new(extism_error.to_string()))
}
#[rustler::nif]
@@ -50,7 +52,7 @@ fn context_reset(ctx: ResourceArc<ExtismContext>) {
#[rustler::nif]
fn context_free(ctx: ResourceArc<ExtismContext>) {
let context = &ctx.ctx.read().unwrap();
let context = ctx.ctx.read().unwrap();
std::mem::drop(context)
}
@@ -61,7 +63,7 @@ fn plugin_new_with_manifest(
wasi: bool,
) -> Result<i32, rustler::Error> {
let context = &ctx.ctx.write().unwrap();
let result = match Plugin::new(context, manifest_payload, wasi) {
let result = match Plugin::new(context, manifest_payload, [], wasi) {
Err(e) => Err(to_rustler_error(e)),
Ok(plugin) => {
let plugin_id = plugin.as_i32();
@@ -85,7 +87,7 @@ fn plugin_call(
let mut plugin = unsafe { Plugin::from_id(plugin_id, context) };
let result = match plugin.call(name, input) {
Err(e) => Err(to_rustler_error(e)),
Ok(result) => match str::from_utf8(&result) {
Ok(result) => match str::from_utf8(result) {
Ok(output) => Ok(output.to_string()),
Err(_e) => Err(rustler::Error::Term(Box::new(
"Could not read output from plugin",
@@ -107,7 +109,7 @@ fn plugin_update_manifest(
) -> Result<(), rustler::Error> {
let context = &ctx.ctx.read().unwrap();
let mut plugin = unsafe { Plugin::from_id(plugin_id, context) };
let result = match plugin.update(manifest_payload, wasi) {
let result = match plugin.update(manifest_payload, [], wasi) {
Ok(()) => Ok(()),
Err(e) => Err(to_rustler_error(e)),
};
@@ -117,6 +119,24 @@ fn plugin_update_manifest(
result
}
#[rustler::nif]
fn plugin_cancel_handle(
ctx: ResourceArc<ExtismContext>,
plugin_id: i32,
) -> Result<ResourceArc<ExtismCancelHandle>, rustler::Error> {
let context = &ctx.ctx.read().unwrap();
let plugin = unsafe { Plugin::from_id(plugin_id, context) };
let handle = plugin.cancel_handle();
Ok(ResourceArc::new(ExtismCancelHandle {
handle: RwLock::new(handle),
}))
}
#[rustler::nif]
fn plugin_cancel(handle: ResourceArc<ExtismCancelHandle>) -> bool {
handle.handle.read().unwrap().cancel()
}
#[rustler::nif]
fn plugin_free(ctx: ResourceArc<ExtismContext>, plugin_id: i32) -> Result<(), rustler::Error> {
let context = &ctx.ctx.read().unwrap();
@@ -170,6 +190,8 @@ rustler::init!(
plugin_call,
plugin_update_manifest,
plugin_has_function,
plugin_cancel_handle,
plugin_cancel,
plugin_free,
set_log_file,
],

View File

@@ -1,7 +1,7 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
synopsis: "Extism manifest bindings"
description: "Bindings to Extism, the universal plugin system"
description: "Bindings to the Extism manifest format"
maintainer: ["Extism Authors <oss@extism.org>"]
authors: ["Extism Authors <oss@extism.org>"]
license: "BSD-3-Clause"
@@ -11,8 +11,9 @@ doc: "https://github.com/extism/extism"
bug-reports: "https://github.com/extism/extism/issues"
depends: [
"ocaml" {>= "4.14.1"}
"dune" {>= "3.2" & >= "3.2"}
"ppx_yojson_conv" {>= "0.15.0"}
"dune" {>= "3.2"}
"ppx_yojson_conv" {>= "v0.15.0"}
"ppx_inline_test" {>= "v0.15.0"}
"base64" {>= "3.5.0"}
"odoc" {with-doc}
]

310
extism.go
View File

@@ -5,13 +5,50 @@ import (
"errors"
"fmt"
"io"
"runtime/cgo"
"unsafe"
)
/*
#cgo pkg-config: libextism.pc
#cgo CFLAGS: -I/usr/local/include
#cgo LDFLAGS: -L/usr/local/lib -lextism
#include <extism.h>
#include <stdlib.h>
int64_t extism_val_i64(ExtismValUnion* x){
return x->i64;
}
int32_t extism_val_i32(ExtismValUnion* x){
return x->i32;
}
float extism_val_f32(ExtismValUnion* x){
return x->f32;
}
double extism_val_f64(ExtismValUnion* x){
return x->f64;
}
void extism_val_set_i64(ExtismValUnion* x, int64_t i){
x->i64 = i;
}
void extism_val_set_i32(ExtismValUnion* x, int32_t i){
x->i32 = i;
}
void extism_val_set_f32(ExtismValUnion* x, float f){
x->f32 = f;
}
void extism_val_set_f64(ExtismValUnion* x, double f){
x->f64 = f;
}
*/
import "C"
@@ -20,6 +57,106 @@ type Context struct {
pointer *C.ExtismContext
}
type ValType = C.ExtismValType
type Val = C.ExtismVal
type Size = C.ExtismSize
var (
I32 ValType = C.I32
I64 ValType = C.I64
F32 ValType = C.F32
F64 ValType = C.F64
V128 ValType = C.V128
FuncRef ValType = C.FuncRef
ExternRef ValType = C.ExternRef
)
// Function is used to define host functions
type Function struct {
pointer *C.ExtismFunction
userData cgo.Handle
}
// Free a function
func (f *Function) Free() {
C.extism_function_free(f.pointer)
f.pointer = nil
f.userData.Delete()
}
// NewFunction creates a new host function with the given name, input/outputs and optional user data, which can be an
// arbitrary `interface{}`
func NewFunction(name string, inputs []ValType, outputs []ValType, f unsafe.Pointer, userData interface{}) Function {
var function Function
function.userData = cgo.NewHandle(userData)
cname := C.CString(name)
ptr := unsafe.Pointer(function.userData)
var inputsPtr *C.ExtismValType = nil
if len(inputs) > 0 {
inputsPtr = (*C.ExtismValType)(&inputs[0])
}
var outputsPtr *C.ExtismValType = nil
if len(outputs) > 0 {
outputsPtr = (*C.ExtismValType)(&outputs[0])
}
function.pointer = C.extism_function_new(
cname,
inputsPtr,
C.uint64_t(len(inputs)),
outputsPtr,
C.uint64_t(len(outputs)),
(*[0]byte)(f),
ptr,
nil,
)
C.free(unsafe.Pointer(cname))
return function
}
func (f *Function) SetNamespace(s string) {
cstr := C.CString(s)
defer C.free(unsafe.Pointer(cstr))
C.extism_function_set_namespace(f.pointer, cstr)
}
func (f Function) WithNamespace(s string) Function {
f.SetNamespace(s)
return f
}
type CurrentPlugin struct {
pointer *C.ExtismCurrentPlugin
}
func GetCurrentPlugin(ptr unsafe.Pointer) CurrentPlugin {
return CurrentPlugin{
pointer: (*C.ExtismCurrentPlugin)(ptr),
}
}
func (p *CurrentPlugin) Memory(offs uint) []byte {
length := C.extism_current_plugin_memory_length(p.pointer, C.uint64_t(offs))
data := unsafe.Pointer(C.extism_current_plugin_memory(p.pointer))
return unsafe.Slice((*byte)(unsafe.Add(data, offs)), C.int(length))
}
// Alloc a new memory block of the given length, returning its offset
func (p *CurrentPlugin) Alloc(n uint) uint {
return uint(C.extism_current_plugin_memory_alloc(p.pointer, C.uint64_t(n)))
}
// Free the memory block specified by the given offset
func (p *CurrentPlugin) Free(offs uint) {
C.extism_current_plugin_memory_free(p.pointer, C.uint64_t(offs))
}
// Length returns the number of bytes allocated at the specified offset
func (p *CurrentPlugin) Length(offs uint) uint {
return uint(C.extism_current_plugin_memory_length(p.pointer, C.uint64_t(offs)))
}
// NewContext creates a new context, it should be freed using the `Free` method
func NewContext() Context {
p := C.extism_context_new()
@@ -96,14 +233,32 @@ func ExtismVersion() string {
return C.GoString(C.extism_version())
}
func register(ctx *Context, data []byte, wasi bool) (Plugin, error) {
func register(ctx *Context, data []byte, functions []Function, wasi bool) (Plugin, error) {
ptr := makePointer(data)
plugin := C.extism_plugin_new(
ctx.pointer,
(*C.uchar)(ptr),
C.uint64_t(len(data)),
C._Bool(wasi),
)
functionPointers := []*C.ExtismFunction{}
for _, f := range functions {
functionPointers = append(functionPointers, f.pointer)
}
plugin := C.int32_t(-1)
if len(functions) == 0 {
plugin = C.extism_plugin_new(
ctx.pointer,
(*C.uchar)(ptr),
C.uint64_t(len(data)),
nil,
0,
C._Bool(wasi))
} else {
plugin = C.extism_plugin_new(
ctx.pointer,
(*C.uchar)(ptr),
C.uint64_t(len(data)),
&functionPointers[0],
C.uint64_t(len(functions)),
C._Bool(wasi),
)
}
if plugin < 0 {
err := C.extism_error(ctx.pointer, C.int32_t(-1))
@@ -120,18 +275,41 @@ func register(ctx *Context, data []byte, wasi bool) (Plugin, error) {
return Plugin{id: int32(plugin), ctx: ctx}, nil
}
func update(ctx *Context, plugin int32, data []byte, wasi bool) error {
func update(ctx *Context, plugin int32, data []byte, functions []Function, wasi bool) error {
ptr := makePointer(data)
b := bool(C.extism_plugin_update(
ctx.pointer,
C.int32_t(plugin),
(*C.uchar)(ptr),
C.uint64_t(len(data)),
C._Bool(wasi),
))
functionPointers := []*C.ExtismFunction{}
for _, f := range functions {
functionPointers = append(functionPointers, f.pointer)
}
if b {
return nil
if len(functions) == 0 {
b := bool(C.extism_plugin_update(
ctx.pointer,
C.int32_t(plugin),
(*C.uchar)(ptr),
C.uint64_t(len(data)),
nil,
0,
C._Bool(wasi),
))
if b {
return nil
}
} else {
b := bool(C.extism_plugin_update(
ctx.pointer,
C.int32_t(plugin),
(*C.uchar)(ptr),
C.uint64_t(len(data)),
&functionPointers[0],
C.uint64_t(len(functions)),
C._Bool(wasi),
))
if b {
return nil
}
}
err := C.extism_error(ctx.pointer, C.int32_t(-1))
@@ -146,43 +324,43 @@ func update(ctx *Context, plugin int32, data []byte, wasi bool) error {
}
// PluginFromManifest creates a plugin from a `Manifest`
func (ctx *Context) PluginFromManifest(manifest Manifest, wasi bool) (Plugin, error) {
func (ctx *Context) PluginFromManifest(manifest Manifest, functions []Function, wasi bool) (Plugin, error) {
data, err := json.Marshal(manifest)
if err != nil {
return Plugin{id: -1}, err
}
return register(ctx, data, wasi)
return register(ctx, data, functions, wasi)
}
// Plugin creates a plugin from a WASM module
func (ctx *Context) Plugin(module io.Reader, wasi bool) (Plugin, error) {
func (ctx *Context) Plugin(module io.Reader, functions []Function, wasi bool) (Plugin, error) {
wasm, err := io.ReadAll(module)
if err != nil {
return Plugin{id: -1}, err
}
return register(ctx, wasm, wasi)
return register(ctx, wasm, functions, wasi)
}
// Update a plugin with a new WASM module
func (p *Plugin) Update(module io.Reader, wasi bool) error {
func (p *Plugin) Update(module io.Reader, functions []Function, wasi bool) error {
wasm, err := io.ReadAll(module)
if err != nil {
return err
}
return update(p.ctx, p.id, wasm, wasi)
return update(p.ctx, p.id, wasm, functions, wasi)
}
// Update a plugin with a new Manifest
func (p *Plugin) UpdateManifest(manifest Manifest, wasi bool) error {
func (p *Plugin) UpdateManifest(manifest Manifest, functions []Function, wasi bool) error {
data, err := json.Marshal(manifest)
if err != nil {
return err
}
return update(p.ctx, p.id, data, wasi)
return update(p.ctx, p.id, data, functions, wasi)
}
// Set configuration values
@@ -233,8 +411,7 @@ func (plugin Plugin) Call(functionName string, input []byte) ([]byte, error) {
if length > 0 {
x := C.extism_plugin_output_data(plugin.ctx.pointer, C.int32_t(plugin.id))
y := (*[]byte)(unsafe.Pointer(&x))
return []byte((*y)[0:length]), nil
return unsafe.Slice((*byte)(x), C.int(length)), nil
}
return []byte{}, nil
@@ -253,3 +430,80 @@ func (plugin *Plugin) Free() {
func (ctx Context) Reset() {
C.extism_context_reset(ctx.pointer)
}
// ValGetI64 returns an I64 from an ExtismVal, it accepts a pointer to a C.ExtismVal
func ValGetI64(v unsafe.Pointer) int64 {
return int64(C.extism_val_i64(&(*Val)(v).v))
}
// ValGetUInt returns a uint from an ExtismVal, it accepts a pointer to a C.ExtismVal
func ValGetUInt(v unsafe.Pointer) uint {
return uint(C.extism_val_i64(&(*Val)(v).v))
}
// ValGetI32 returns an int32 from an ExtismVal, it accepts a pointer to a C.ExtismVal
func ValGetI32(v unsafe.Pointer) int32 {
return int32(C.extism_val_i32(&(*Val)(v).v))
}
// ValGetF32 returns a float32 from an ExtismVal, it accepts a pointer to a C.ExtismVal
func ValGetF32(v unsafe.Pointer) float32 {
return float32(C.extism_val_f32(&(*Val)(v).v))
}
// ValGetF32 returns a float64 from an ExtismVal, it accepts a pointer to a C.ExtismVal
func ValGetF64(v unsafe.Pointer) float64 {
return float64(C.extism_val_i64(&(*Val)(v).v))
}
// ValSetI64 stores an int64 in an ExtismVal, it accepts a pointer to a C.ExtismVal and the new value
func ValSetI64(v unsafe.Pointer, i int64) {
C.extism_val_set_i64(&(*Val)(v).v, C.int64_t(i))
}
// ValSetI32 stores an int32 in an ExtismVal, it accepts a pointer to a C.ExtismVal and the new value
func ValSetI32(v unsafe.Pointer, i int32) {
C.extism_val_set_i32(&(*Val)(v).v, C.int32_t(i))
}
// ValSetF32 stores a float32 in an ExtismVal, it accepts a pointer to a C.ExtismVal and the new value
func ValSetF32(v unsafe.Pointer, i float32) {
C.extism_val_set_f32(&(*Val)(v).v, C.float(i))
}
// ValSetF64 stores a float64 in an ExtismVal, it accepts a pointer to a C.ExtismVal and the new value
func ValSetF64(v unsafe.Pointer, f float64) {
C.extism_val_set_f64(&(*Val)(v).v, C.double(f))
}
func (p *CurrentPlugin) ReturnBytes(v unsafe.Pointer, b []byte) {
mem := p.Alloc(uint(len(b)))
ptr := p.Memory(mem)
copy(ptr, b)
ValSetI64(v, int64(mem))
}
func (p *CurrentPlugin) ReturnString(v unsafe.Pointer, s string) {
p.ReturnBytes(v, []byte(s))
}
func (p *CurrentPlugin) InputBytes(v unsafe.Pointer) []byte {
return p.Memory(ValGetUInt(v))
}
func (p *CurrentPlugin) InputString(v unsafe.Pointer) string {
return string(p.InputBytes(v))
}
type CancelHandle struct {
pointer *C.ExtismCancelHandle
}
func (p *Plugin) CancelHandle() CancelHandle {
pointer := C.extism_plugin_cancel_handle(p.ctx.pointer, C.int(p.id))
return CancelHandle{pointer}
}
func (c *CancelHandle) Cancel() bool {
return bool(C.extism_plugin_cancel(c.pointer))
}

View File

@@ -11,12 +11,13 @@ doc: "https://github.com/extism/extism"
bug-reports: "https://github.com/extism/extism/issues"
depends: [
"ocaml" {>= "4.14.1"}
"dune" {>= "3.2" & >= "3.2"}
"dune" {>= "3.2"}
"ctypes" {>= "0.18.0"}
"ctypes-foreign" {>= "0.18.0"}
"bigstringaf" {>= "0.9.0"}
"ppx_yojson_conv" {>= "0.15.0"}
"ppx_yojson_conv" {>= "v0.15.0"}
"extism-manifest"
"ppx_inline_test" {>= "0.15.0"}
"ppx_inline_test" {>= "v0.15.0"}
"cmdliner" {>= "1.1.1"}
"odoc" {with-doc}
]
@@ -35,3 +36,5 @@ build: [
]
]
dev-repo: "git+https://github.com/extism/extism.git"
build-env: [EXTISM_TEST_NO_LIB = ""]
post-messages: ["See https://extism.org/docs/install/ for information about installing libextism"]

2
extism.opam.template Normal file
View File

@@ -0,0 +1,2 @@
build-env: [EXTISM_TEST_NO_LIB = ""]
post-messages: ["See https://extism.org/docs/install/ for information about installing libextism"]

View File

@@ -4,13 +4,19 @@ import (
"encoding/json"
"fmt"
"testing"
"time"
)
func manifest() Manifest {
func manifest(functions bool) Manifest {
path := "./wasm/code.wasm"
if functions {
path = "./wasm/code-functions.wasm"
}
return Manifest{
Wasm: []Wasm{
WasmFile{
Path: "./wasm/code.wasm",
Path: path,
},
},
}
@@ -38,7 +44,7 @@ func TestCallPlugin(t *testing.T) {
ctx := NewContext()
defer ctx.Free()
plugin, err := ctx.PluginFromManifest(manifest(), false)
plugin, err := ctx.PluginFromManifest(manifest(false), []Function{}, false)
if err != nil {
t.Error(err)
}
@@ -58,7 +64,7 @@ func TestFreePlugin(t *testing.T) {
ctx := NewContext()
defer ctx.Free()
plugin, err := ctx.PluginFromManifest(manifest(), false)
plugin, err := ctx.PluginFromManifest(manifest(false), []Function{}, false)
if err != nil {
t.Error(err)
}
@@ -78,7 +84,7 @@ func TestContextReset(t *testing.T) {
ctx := NewContext()
defer ctx.Free()
plugin, err := ctx.PluginFromManifest(manifest(), false)
plugin, err := ctx.PluginFromManifest(manifest(false), []Function{}, false)
if err != nil {
t.Error(err)
}
@@ -98,7 +104,7 @@ func TestCanUpdateAManifest(t *testing.T) {
ctx := NewContext()
defer ctx.Free()
plugin, err := ctx.PluginFromManifest(manifest(), false)
plugin, err := ctx.PluginFromManifest(manifest(false), []Function{}, false)
if err != nil {
t.Error(err)
}
@@ -107,7 +113,7 @@ func TestCanUpdateAManifest(t *testing.T) {
t.Error(err)
}
plugin.UpdateManifest(manifest(), false)
plugin.UpdateManifest(manifest(false), []Function{}, false)
// can still call the plugin
if err := expectVowelCount(plugin, "this is a test", 4); err != nil {
@@ -119,7 +125,7 @@ func TestFunctionExists(t *testing.T) {
ctx := NewContext()
defer ctx.Free()
plugin, err := ctx.PluginFromManifest(manifest(), false)
plugin, err := ctx.PluginFromManifest(manifest(false), []Function{}, false)
if err != nil {
t.Error(err)
}
@@ -136,7 +142,7 @@ func TestErrorsOnUnknownFunction(t *testing.T) {
ctx := NewContext()
defer ctx.Free()
plugin, err := ctx.PluginFromManifest(manifest(), false)
plugin, err := ctx.PluginFromManifest(manifest(false), []Function{}, false)
if err != nil {
t.Error(err)
}
@@ -146,3 +152,33 @@ func TestErrorsOnUnknownFunction(t *testing.T) {
t.Fatal("Was expecting call to unknown function to fail")
}
}
func TestCancel(t *testing.T) {
manifest := Manifest{
Wasm: []Wasm{
WasmFile{
Path: "./wasm/loop.wasm",
},
},
}
ctx := NewContext()
defer ctx.Free()
plugin, err := ctx.PluginFromManifest(manifest, []Function{}, false)
if err != nil {
t.Error(err)
}
cancelHandle := plugin.CancelHandle()
go func(handle CancelHandle) {
time.Sleep(time.Second * 1)
handle.Cancel()
}(cancelHandle)
_, err = plugin.Call("infinite_loop", []byte(""))
if err == nil {
t.Fail()
}
}

1
go/code-functions.wasm Symbolic link
View File

@@ -0,0 +1 @@
../wasm/code-functions.wasm

View File

@@ -4,10 +4,34 @@ import (
"encoding/json"
"fmt"
"os"
"runtime/cgo"
"unsafe"
"github.com/extism/extism"
)
/*
#include <extism.h>
EXTISM_GO_FUNCTION(hello_world);
*/
import "C"
//export hello_world
func hello_world(plugin unsafe.Pointer, inputs *C.ExtismVal, nInputs C.ExtismSize, outputs *C.ExtismVal, nOutputs C.ExtismSize, userData uintptr) {
fmt.Println("Hello from Go!")
s := cgo.Handle(userData)
fmt.Println(s.Value().(string))
inputSlice := unsafe.Slice(inputs, nInputs)
outputSlice := unsafe.Slice(outputs, nOutputs)
// Get memory pointed to by first element of input slice
p := extism.GetCurrentPlugin(plugin)
str := p.InputString(unsafe.Pointer(&inputSlice[0]))
fmt.Println(str)
outputSlice[0] = inputSlice[0]
}
func main() {
version := extism.ExtismVersion()
fmt.Println("Extism Version: ", version)
@@ -22,9 +46,10 @@ func main() {
} else {
data = []byte("testing from go -> wasm shared memory...")
}
manifest := extism.Manifest{Wasm: []extism.Wasm{extism.WasmFile{Path: "../wasm/code.wasm"}}}
plugin, err := ctx.PluginFromManifest(manifest, false)
manifest := extism.Manifest{Wasm: []extism.Wasm{extism.WasmFile{Path: "code-functions.wasm"}}}
f := extism.NewFunction("hello_world", []extism.ValType{extism.I64}, []extism.ValType{extism.I64}, C.hello_world, "Hello again!")
defer f.Free()
plugin, err := ctx.PluginFromManifest(manifest, []extism.Function{f}, true)
if err != nil {
fmt.Println(err)
os.Exit(1)

View File

@@ -1,5 +1,5 @@
# Revision history for extism
## 0.1.0.0 -- YYYY-mm-dd
## 0.2.0.0 -- 2023-01-16
* First version. Released on an unsuspecting world.

View File

@@ -8,7 +8,7 @@ unwrap (Left (ExtismError msg)) = do
error msg
main = do
let m = manifest [wasmFile "../wasm/code.wasm"]
let m = manifest [wasmFile "code.wasm"]
context <- Extism.newContext
plugin <- unwrap <$> Extism.pluginFromManifest context m False
res <- unwrap <$> Extism.call plugin "count_vowels" (Extism.toByteString "this is a test")

View File

@@ -13,6 +13,9 @@ clean:
cabal clean
publish: clean prepare
cabal v2-haddock --haddock-for-hackage ./manifest/extism-manifest.cabal
cabal v2-haddock --haddock-for-hackage
cabal sdist ./manifest/extism-manifest.cabal
cabal sdist
# TODO: upload

1
haskell/code.wasm Symbolic link
View File

@@ -0,0 +1 @@
../wasm/code.wasm

View File

@@ -1,6 +1,6 @@
cabal-version: 3.0
name: extism
version: 0.0.1
version: 0.2.0
license: BSD-3-Clause
maintainer: oss@extism.org
author: Extism authors
@@ -19,10 +19,10 @@ library
extra-libraries: extism
extra-lib-dirs: /usr/local/lib
build-depends:
base >= 4.16.1 && < 4.18.0,
base >= 4.16.1 && < 4.19.0,
bytestring >= 0.11.3 && < 0.12,
json >= 0.10 && < 0.11,
extism-manifest >= 0.0.0 && < 0.1.0
extism-manifest >= 0.0.0 && < 0.3.0
test-suite extism-example
type: exitcode-stdio-1.0

View File

@@ -24,6 +24,8 @@ toNullable (Just x) = NotNull x
toNullable Nothing = Null
fromNullable (NotNull x) = Just x
fromNullable Null = Nothing
fromNotNull (NotNull x) = x
fromNotNull Null = error "Value is Null"
mapNullable f Null = Null
mapNullable f (NotNull x) = NotNull (f x)

View File

@@ -1,6 +1,6 @@
cabal-version: 3.0
name: extism-manifest
version: 0.0.1
version: 0.2.0
license: BSD-3-Clause
maintainer: oss@extism.org
author: Extism authors
@@ -15,7 +15,7 @@ library
hs-source-dirs: .
default-language: Haskell2010
build-depends:
base >= 4.16.1 && < 4.18.0,
base >= 4.16.1 && < 4.19.0,
bytestring >= 0.11.3 && < 0.12,
json >= 0.10 && < 0.11,
base64-bytestring >= 1.2.1 && < 1.3,

View File

@@ -19,6 +19,8 @@ newtype Context = Context (ForeignPtr ExtismContext)
-- | Plugins can be used to call WASM function
data Plugin = Plugin Context Int32
data CancelHandle = CancelHandle (Ptr ExtismCancelHandle)
-- | Log level
data LogLevel = Error | Warn | Info | Debug | Trace deriving (Show)
@@ -70,7 +72,7 @@ plugin c wasm useWasi =
do
withForeignPtr ctx (\ctx -> do
p <- unsafeUseAsCString wasm (\s ->
extism_plugin_new ctx (castPtr s) length wasi)
extism_plugin_new ctx (castPtr s) length nullPtr 0 wasi )
if p < 0 then do
err <- extism_error ctx (-1)
e <- peekCString err
@@ -92,7 +94,7 @@ update (Plugin (Context ctx) id) wasm useWasi =
do
withForeignPtr ctx (\ctx -> do
b <- unsafeUseAsCString wasm (\s ->
extism_plugin_update ctx id (castPtr s) length wasi)
extism_plugin_update ctx id (castPtr s) length nullPtr 0 wasi)
if b <= 0 then do
err <- extism_error ctx (-1)
e <- peekCString err
@@ -172,3 +174,13 @@ call (Plugin (Context ctx) plugin) name input =
free :: Plugin -> IO ()
free (Plugin (Context ctx) plugin) =
withForeignPtr ctx (`extism_plugin_free` plugin)
cancelHandle :: Plugin -> IO CancelHandle
cancelHandle (Plugin (Context ctx) plugin) = do
handle <- withForeignPtr ctx (\ctx -> extism_plugin_cancel_handle ctx plugin)
return (CancelHandle handle)
cancel :: CancelHandle -> IO Bool
cancel (CancelHandle handle) =
extism_plugin_cancel handle

View File

@@ -9,18 +9,22 @@ import Data.Int
import Data.Word
newtype ExtismContext = ExtismContext () deriving Show
newtype ExtismFunction = ExtismFunction () deriving Show
newtype ExtismCancelHandle = ExtismCancelHandle () deriving Show
foreign import ccall unsafe "extism.h extism_context_new" extism_context_new :: IO (Ptr ExtismContext)
foreign import ccall unsafe "extism.h &extism_context_free" extism_context_free :: FunPtr (Ptr ExtismContext -> IO ())
foreign import ccall unsafe "extism.h extism_plugin_new" extism_plugin_new :: Ptr ExtismContext -> Ptr Word8 -> Word64 -> CBool -> IO Int32
foreign import ccall unsafe "extism.h extism_plugin_update" extism_plugin_update :: Ptr ExtismContext -> Int32 -> Ptr Word8 -> Word64 -> CBool -> IO CBool
foreign import ccall unsafe "extism.h extism_plugin_call" extism_plugin_call :: Ptr ExtismContext -> Int32 -> CString -> Ptr Word8 -> Word64 -> IO Int32
foreign import ccall unsafe "extism.h extism_plugin_function_exists" extism_plugin_function_exists :: Ptr ExtismContext -> Int32 -> CString -> IO CBool
foreign import ccall unsafe "extism.h extism_error" extism_error :: Ptr ExtismContext -> Int32 -> IO CString
foreign import ccall unsafe "extism.h extism_plugin_output_length" extism_plugin_output_length :: Ptr ExtismContext -> Int32 -> IO Word64
foreign import ccall unsafe "extism.h extism_plugin_output_data" extism_plugin_output_data :: Ptr ExtismContext -> Int32 -> IO (Ptr Word8)
foreign import ccall unsafe "extism.h extism_log_file" extism_log_file :: CString -> CString -> IO CBool
foreign import ccall unsafe "extism.h extism_plugin_config" extism_plugin_config :: Ptr ExtismContext -> Int32 -> Ptr Word8 -> Int64 -> IO CBool
foreign import ccall unsafe "extism.h extism_plugin_free" extism_plugin_free :: Ptr ExtismContext -> Int32 -> IO ()
foreign import ccall unsafe "extism.h extism_context_reset" extism_context_reset :: Ptr ExtismContext -> IO ()
foreign import ccall unsafe "extism.h extism_version" extism_version :: IO CString
foreign import ccall safe "extism.h extism_context_new" extism_context_new :: IO (Ptr ExtismContext)
foreign import ccall safe "extism.h &extism_context_free" extism_context_free :: FunPtr (Ptr ExtismContext -> IO ())
foreign import ccall safe "extism.h extism_plugin_new" extism_plugin_new :: Ptr ExtismContext -> Ptr Word8 -> Word64 -> Ptr (Ptr ExtismFunction) -> Word64 -> CBool -> IO Int32
foreign import ccall safe "extism.h extism_plugin_update" extism_plugin_update :: Ptr ExtismContext -> Int32 -> Ptr Word8 -> Word64 -> Ptr (Ptr ExtismFunction) -> Word64 -> CBool -> IO CBool
foreign import ccall safe "extism.h extism_plugin_call" extism_plugin_call :: Ptr ExtismContext -> Int32 -> CString -> Ptr Word8 -> Word64 -> IO Int32
foreign import ccall safe "extism.h extism_plugin_function_exists" extism_plugin_function_exists :: Ptr ExtismContext -> Int32 -> CString -> IO CBool
foreign import ccall safe "extism.h extism_error" extism_error :: Ptr ExtismContext -> Int32 -> IO CString
foreign import ccall safe "extism.h extism_plugin_output_length" extism_plugin_output_length :: Ptr ExtismContext -> Int32 -> IO Word64
foreign import ccall safe "extism.h extism_plugin_output_data" extism_plugin_output_data :: Ptr ExtismContext -> Int32 -> IO (Ptr Word8)
foreign import ccall safe "extism.h extism_log_file" extism_log_file :: CString -> CString -> IO CBool
foreign import ccall safe "extism.h extism_plugin_config" extism_plugin_config :: Ptr ExtismContext -> Int32 -> Ptr Word8 -> Int64 -> IO CBool
foreign import ccall safe "extism.h extism_plugin_free" extism_plugin_free :: Ptr ExtismContext -> Int32 -> IO ()
foreign import ccall safe "extism.h extism_context_reset" extism_context_reset :: Ptr ExtismContext -> IO ()
foreign import ccall safe "extism.h extism_version" extism_version :: IO CString
foreign import ccall safe "extism.h extism_plugin_cancel_handle" extism_plugin_cancel_handle :: Ptr ExtismContext -> Int32 -> IO (Ptr ExtismCancelHandle)
foreign import ccall safe "extism.h extism_plugin_cancel" extism_plugin_cancel :: Ptr ExtismCancelHandle -> IO Bool

View File

@@ -7,7 +7,7 @@ unwrap (Right x) = return x
unwrap (Left (ExtismError msg)) =
assertFailure msg
defaultManifest = manifest [wasmFile "test/code.wasm"]
defaultManifest = manifest [wasmFile "../../wasm/code.wasm"]
initPlugin :: Context -> IO Plugin
initPlugin context =

Binary file not shown.

View File

@@ -4,7 +4,7 @@
<groupId>org.extism.sdk</groupId>
<artifactId>extism</artifactId>
<packaging>jar</packaging>
<version>0.1.0</version>
<version>0.3.0</version>
<name>extism</name>
<url>https://github.com/extism/extism</url>
<description>Java-SDK for Extism to use webassembly from Java</description>
@@ -36,7 +36,7 @@
<scm>
<connection>scm:git:git://github.com/extism/extism.git</connection>
<developerConnection>scm:git:ssh://git@github.com/extism/extism.git</developerConnection>
<url>https://github.com/extism/extism/java</url>
<url>https://github.com/extism/extism/tree/main/java</url>
<tag>main</tag>
</scm>
@@ -46,7 +46,7 @@
</issueManagement>
<properties>
<java.version>17</java.version>
<java.version>11</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- dependencies -->
@@ -74,6 +74,9 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<additionalJOption>-Xdoclint:none</additionalJOption>
</configuration>
<executions>
<execution>
<id>attach-javadoc</id>

View File

@@ -0,0 +1,21 @@
package org.extism.sdk;
import com.sun.jna.Pointer;
/**
* CancelHandle is used to cancel a running Plugin
*/
public class CancelHandle {
private Pointer handle;
public CancelHandle(Pointer handle) {
this.handle = handle;
}
/**
* Cancel execution of the Plugin associated with the CancelHandle
*/
boolean cancel() {
return LibExtism.INSTANCE.extism_plugin_cancel(this.handle);
}
}

View File

@@ -28,10 +28,11 @@ public class Context implements AutoCloseable {
*
* @param manifest The manifest for the plugin
* @param withWASI Set to true to enable WASI
* @param functions List of Host functions
* @return the plugin instance
*/
public Plugin newPlugin(Manifest manifest, boolean withWASI) {
return new Plugin(this, manifest, withWASI);
public Plugin newPlugin(Manifest manifest, boolean withWASI, HostFunction[] functions) {
return new Plugin(this, manifest, withWASI, functions);
}
/**

View File

@@ -42,7 +42,7 @@ public class Extism {
*/
public static String invokeFunction(Manifest manifest, String function, String input) throws ExtismException {
try (var ctx = new Context()) {
try (var plugin = ctx.newPlugin(manifest, false)) {
try (var plugin = ctx.newPlugin(manifest, false, null)) {
return plugin.call(function, input);
}
}

View File

@@ -0,0 +1,78 @@
package org.extism.sdk;
import com.sun.jna.Pointer;
import java.nio.charset.StandardCharsets;
public class ExtismCurrentPlugin {
public Pointer pointer;
public ExtismCurrentPlugin(Pointer pointer) {
this.pointer = pointer;
}
public Pointer memory() {
return LibExtism.INSTANCE.extism_current_plugin_memory(this.pointer);
}
public int alloc(int n) {
return LibExtism.INSTANCE.extism_current_plugin_memory_alloc(this.pointer, n);
}
public void free(long offset) {
LibExtism.INSTANCE.extism_current_plugin_memory_free(this.pointer, offset);
}
public long memoryLength(long offset) {
return LibExtism.INSTANCE.extism_current_plugin_memory_length(this.pointer, offset);
}
/**
* Return a string from a host function
* @param output - The output to set
* @param s - The string to return
*/
public void returnString(LibExtism.ExtismVal output, String s) {
returnBytes(output, s.getBytes(StandardCharsets.UTF_8));
}
/**
* Return bytes from a host function
* @param output - The output to set
* @param b - The buffer to return
*/
public void returnBytes(LibExtism.ExtismVal output, byte[] b) {
int offs = this.alloc(b.length);
Pointer ptr = this.memory();
ptr.write(offs, b, 0, b.length);
output.v.i64 = offs;
}
/**
* Get bytes from host function parameter
* @param input - The input to read
*/
public byte[] inputBytes(LibExtism.ExtismVal input) {
switch (input.t) {
case 0:
return this.memory()
.getByteArray(input.v.i32,
LibExtism.INSTANCE.extism_current_plugin_memory_length(this.pointer, input.v.i32));
case 1:
return this.memory()
.getByteArray(input.v.i64,
LibExtism.INSTANCE.extism_current_plugin_memory_length(this.pointer, input.v.i64));
default:
throw new ExtismException("inputBytes error: ExtismValType " + LibExtism.ExtismValType.values()[input.t] + " not implemtented");
}
}
/**
* Get string from host function parameter
* @param input - The input to read
*/
public String inputString(LibExtism.ExtismVal input) {
return new String(this.inputBytes(input));
}
}

View File

@@ -0,0 +1,12 @@
package org.extism.sdk;
import java.util.Optional;
public interface ExtismFunction<T extends HostUserData> {
void invoke(
ExtismCurrentPlugin plugin,
LibExtism.ExtismVal[] params,
LibExtism.ExtismVal[] returns,
Optional<T> data
);
}

View File

@@ -0,0 +1,92 @@
package org.extism.sdk;
import com.sun.jna.Pointer;
import com.sun.jna.PointerType;
import java.util.Arrays;
import java.util.Optional;
public class HostFunction<T extends HostUserData> {
private final LibExtism.InternalExtismFunction callback;
public final Pointer pointer;
public final String name;
public final LibExtism.ExtismValType[] params;
public final LibExtism.ExtismValType[] returns;
public final Optional<T> userData;
public HostFunction(String name, LibExtism.ExtismValType[] params, LibExtism.ExtismValType[] returns, ExtismFunction f, Optional<T> userData) {
this.name = name;
this.params = params;
this.returns = returns;
this.userData = userData;
this.callback = (Pointer currentPlugin,
LibExtism.ExtismVal inputs,
int nInputs,
LibExtism.ExtismVal outs,
int nOutputs,
Pointer data) -> {
LibExtism.ExtismVal[] outputs = (LibExtism.ExtismVal []) outs.toArray(nOutputs);
f.invoke(
new ExtismCurrentPlugin(currentPlugin),
(LibExtism.ExtismVal []) inputs.toArray(nInputs),
outputs,
userData
);
for (LibExtism.ExtismVal output : outputs) {
convertOutput(output, output);
}
};
this.pointer = LibExtism.INSTANCE.extism_function_new(
this.name,
Arrays.stream(this.params).mapToInt(r -> r.v).toArray(),
this.params.length,
Arrays.stream(this.returns).mapToInt(r -> r.v).toArray(),
this.returns.length,
this.callback,
userData.map(PointerType::getPointer).orElse(null),
null
);
}
void convertOutput(LibExtism.ExtismVal original, LibExtism.ExtismVal fromHostFunction) {
if (fromHostFunction.t != original.t)
throw new ExtismException(String.format("Output type mismatch, got %d but expected %d", fromHostFunction.t, original.t));
if (fromHostFunction.t == LibExtism.ExtismValType.I32.v) {
original.v.setType(Integer.TYPE);
original.v.i32 = fromHostFunction.v.i32;
} else if (fromHostFunction.t == LibExtism.ExtismValType.I64.v) {
original.v.setType(Long.TYPE);
original.v.i64 = fromHostFunction.v.i64;
} else if (fromHostFunction.t == LibExtism.ExtismValType.F32.v) {
original.v.setType(Float.TYPE);
original.v.f32 = fromHostFunction.v.f32;
} else if (fromHostFunction.t == LibExtism.ExtismValType.F64.v) {
original.v.setType(Double.TYPE);
original.v.f64 = fromHostFunction.v.f64;
} else
throw new ExtismException(String.format("Unsupported return type: %s", original.t));
}
public void setNamespace(String name) {
if (this.pointer != null) {
LibExtism.INSTANCE.extism_function_set_namespace(this.pointer, name);
}
}
HostFunction withNamespace(String name) {
this.setNamespace(name);
return this;
}
}

View File

@@ -0,0 +1,7 @@
package org.extism.sdk;
import com.sun.jna.PointerType;
public class HostUserData extends PointerType {
}

View File

@@ -1,8 +1,6 @@
package org.extism.sdk;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.*;
/**
* Wrapper around the Extism library.
@@ -15,7 +13,80 @@ public interface LibExtism extends Library {
*/
LibExtism INSTANCE = Native.load("extism", LibExtism.class);
interface InternalExtismFunction extends Callback {
void invoke(
Pointer currentPlugin,
ExtismVal inputs,
int nInputs,
ExtismVal outputs,
int nOutputs,
Pointer data
);
}
@Structure.FieldOrder({"t", "v"})
class ExtismVal extends Structure {
public int t;
public ExtismValUnion v;
}
class ExtismValUnion extends Union {
public int i32;
public long i64;
public float f32;
public double f64;
}
enum ExtismValType {
I32(0),
I64(1),
F32(2),
F64(3),
V128(4),
FuncRef(5),
ExternRef(6);
public final int v;
ExtismValType(int value) {
this.v = value;
}
}
Pointer extism_function_new(String name,
int[] inputs,
int nInputs,
int[] outputs,
int nOutputs,
InternalExtismFunction func,
Pointer userData,
Pointer freeUserData);
/**
* Get the length of an allocated block
* NOTE: this should only be called from host functions.
*/
int extism_current_plugin_memory_length(Pointer plugin, long n);
/**
* Returns a pointer to the memory of the currently running plugin
* NOTE: this should only be called from host functions.
*/
Pointer extism_current_plugin_memory(Pointer plugin);
/**
* Allocate a memory block in the currently running plugin
* NOTE: this should only be called from host functions.
*/
int extism_current_plugin_memory_alloc(Pointer plugin, long n);
/**
* Free an allocated memory block
* NOTE: this should only be called from host functions.
*/
void extism_current_plugin_memory_free(Pointer plugin, long ptr);
/**
* Create a new context
*/
Pointer extism_context_new();
@@ -56,27 +127,18 @@ public interface LibExtism extends Library {
* @param contextPointer pointer to the {@link Context}.
* @param wasm is a WASM module (wat or wasm) or a JSON encoded manifest
* @param wasmSize the length of the `wasm` parameter
* @param functions host functions
* @param nFunctions the number of host functions
* @param withWASI enables/disables WASI
* @return id of the plugin or {@literal -1} in case of error
*/
int extism_plugin_new(long contextPointer, byte[] wasm, long wasmSize, boolean withWASI);
int extism_plugin_new(Pointer contextPointer, byte[] wasm, long wasmSize, Pointer[] functions, int nFunctions, boolean withWASI);
/**
* Returns the Extism version string
*/
String extism_version();
/**
* Create a new plugin.
*
* @param contextPointer pointer to the {@link Context}.
* @param wasm is a WASM module (wat or wasm) or a JSON encoded manifest
* @param length the length of the `wasm` parameter
* @param withWASI enables/disables WASI
* @return id of the plugin or {@literal -1} in case of error
* @see #extism_plugin_new(long, byte[], long, boolean)
*/
int extism_plugin_new(Pointer contextPointer, byte[] wasm, int length, boolean withWASI);
/**
* Calls a function from the @{@link Plugin} at the given {@code pluginIndex}.
@@ -110,17 +172,19 @@ public interface LibExtism extends Library {
/**
* Update a plugin, keeping the existing ID.
* Similar to {@link #extism_plugin_new(long, byte[], long, boolean)} but takes an {@code pluginIndex} argument to specify which plugin to update.
* Similar to {@link #extism_plugin_new(Pointer, byte[], long, Pointer[], int, boolean)} but takes an {@code pluginIndex} argument to specify which plugin to update.
* Note: Memory for this plugin will be reset upon update.
*
* @param contextPointer
* @param pluginIndex
* @param wasm
* @param length
* @param functions host functions
* @param nFunctions the number of host functions
* @param withWASI
* @return {@literal true} if update was successful
*/
boolean extism_plugin_update(Pointer contextPointer, int pluginIndex, byte[] wasm, int length, boolean withWASI);
boolean extism_plugin_update(Pointer contextPointer, int pluginIndex, byte[] wasm, int length, Pointer[] functions, int nFunctions, boolean withWASI);
/**
* Remove a plugin from the registry and free associated memory.
@@ -140,4 +204,7 @@ public interface LibExtism extends Library {
* @return {@literal true} if update was successful
*/
boolean extism_plugin_config(Pointer contextPointer, int pluginIndex, byte[] json, int jsonLength);
Pointer extism_plugin_cancel_handle(Pointer contextPointer, int n);
boolean extism_plugin_cancel(Pointer contextPointer);
void extism_function_set_namespace(Pointer p, String name);
}

View File

@@ -28,15 +28,27 @@ public class Plugin implements AutoCloseable {
*
* @param context The context to manage the plugin
* @param manifestBytes The manifest for the plugin
* @param functions The Host functions for th eplugin
* @param withWASI Set to true to enable WASI
*/
public Plugin(Context context, byte[] manifestBytes, boolean withWASI) {
public Plugin(Context context, byte[] manifestBytes, boolean withWASI, HostFunction[] functions) {
Objects.requireNonNull(context, "context");
Objects.requireNonNull(manifestBytes, "manifestBytes");
Pointer[] ptrArr = new Pointer[functions == null ? 0 : functions.length];
if (functions != null)
for (int i = 0; i < functions.length; i++) {
ptrArr[i] = functions[i].pointer;
}
Pointer contextPointer = context.getPointer();
int index = LibExtism.INSTANCE.extism_plugin_new(contextPointer, manifestBytes, manifestBytes.length, withWASI);
int index = LibExtism.INSTANCE.extism_plugin_new(contextPointer, manifestBytes, manifestBytes.length,
ptrArr,
functions == null ? 0 : functions.length,
withWASI);
if (index == -1) {
String error = context.error(this);
throw new ExtismException(error);
@@ -46,8 +58,8 @@ public class Plugin implements AutoCloseable {
this.context = context;
}
public Plugin(Context context, Manifest manifest, boolean withWASI) {
this(context, serialize(manifest), withWASI);
public Plugin(Context context, Manifest manifest, boolean withWASI, HostFunction[] functions) {
this(context, serialize(manifest), withWASI, functions);
}
private static byte[] serialize(Manifest manifest) {
@@ -112,8 +124,8 @@ public class Plugin implements AutoCloseable {
* @param withWASI Set to true to enable WASI
* @return {@literal true} if update was successful
*/
public boolean update(Manifest manifest, boolean withWASI) {
return update(serialize(manifest), withWASI);
public boolean update(Manifest manifest, boolean withWASI, HostFunction[] functions) {
return update(serialize(manifest), withWASI, functions);
}
/**
@@ -123,9 +135,19 @@ public class Plugin implements AutoCloseable {
* @param withWASI Set to true to enable WASI
* @return {@literal true} if update was successful
*/
public boolean update(byte[] manifestBytes, boolean withWASI) {
public boolean update(byte[] manifestBytes, boolean withWASI, HostFunction[] functions) {
Objects.requireNonNull(manifestBytes, "manifestBytes");
return LibExtism.INSTANCE.extism_plugin_update(context.getPointer(), index, manifestBytes, manifestBytes.length, withWASI);
Pointer[] ptrArr = new Pointer[functions == null ? 0 : functions.length];
if (functions != null)
for (int i = 0; i < functions.length; i++) {
ptrArr[i] = functions[i].pointer;
}
return LibExtism.INSTANCE.extism_plugin_update(context.getPointer(), index, manifestBytes, manifestBytes.length,
ptrArr,
functions == null ? 0 : functions.length,
withWASI);
}
/**
@@ -165,4 +187,15 @@ public class Plugin implements AutoCloseable {
public void close() {
free();
}
/**
* Return a new `CancelHandle`, which can be used to cancel a running Plugin
*/
public CancelHandle cancelHandle() {
if (this.context.getPointer() == null) {
throw new ExtismException("No Context set");
}
Pointer handle = LibExtism.INSTANCE.extism_plugin_cancel_handle(this.context.getPointer(), this.index);
return new CancelHandle(handle);
}
}

View File

@@ -20,11 +20,14 @@ public class Manifest {
@SerializedName("allowed_hosts")
private final List<String> allowedHosts;
@SerializedName("allowed_paths")
private final Map<String, String> allowedPaths;
@SerializedName("config")
private final Map<String, String> config;
public Manifest() {
this(new ArrayList<>(), null, null, null);
this(new ArrayList<>(), null, null, null, null);
}
public Manifest(WasmSource source) {
@@ -32,22 +35,27 @@ public class Manifest {
}
public Manifest(List<WasmSource> sources) {
this(sources, null, null, null);
this(sources, null, null, null, null);
}
public Manifest(List<WasmSource> sources, MemoryOptions memoryOptions) {
this(sources, memoryOptions, null, null);
this(sources, memoryOptions, null, null, null);
}
public Manifest(List<WasmSource> sources, MemoryOptions memoryOptions, Map<String, String> config) {
this(sources, memoryOptions, config, null);
this(sources, memoryOptions, config, null, null);
}
public Manifest(List<WasmSource> sources, MemoryOptions memoryOptions, Map<String, String> config, List<String> allowedHosts) {
this(sources, memoryOptions, config, allowedHosts, null);
}
public Manifest(List<WasmSource> sources, MemoryOptions memoryOptions, Map<String, String> config, List<String> allowedHosts, Map<String, String> allowedPaths) {
this.sources = sources;
this.memoryOptions = memoryOptions;
this.config = config;
this.allowedHosts = allowedHosts;
this.allowedPaths = allowedPaths;
}
public void addSource(WasmSource source) {
@@ -75,4 +83,11 @@ public class Manifest {
}
return Collections.unmodifiableList(allowedHosts);
}
public Map<String, String> getAllowedPaths() {
if (allowedPaths == null || allowedPaths.isEmpty()) {
return Collections.emptyMap();
}
return Collections.unmodifiableMap(allowedPaths);
}
}

View File

@@ -3,6 +3,27 @@ package org.extism.sdk.manifest;
import java.util.Map;
// FIXME remove this and related stuff if not supported in java-sdk
public record ManifestHttpRequest(String url, Map<String, String> header, String method) {
}
public class ManifestHttpRequest {
private final String url;
private final Map<String, String> header;
private final String method;
public ManifestHttpRequest(String url, Map<String, String> header, String method) {
this.url = url;
this.header = header;
this.method = method;
}
public String url() {
return url;
}
public Map<String, String> header() {
return header;
}
public String method() {
return method;
}
}

View File

@@ -8,5 +8,11 @@ import com.google.gson.annotations.SerializedName;
*
* @param max Max number of pages.
*/
public record MemoryOptions(@SerializedName("max") Integer max) {
public class MemoryOptions {
@SerializedName("max")
private final Integer max;
public MemoryOptions(Integer max) {
this.max = max;
}
}

View File

@@ -1,18 +1,14 @@
package org.extism.sdk.support;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.*;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import org.extism.sdk.manifest.Manifest;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class JsonSerde {
@@ -23,7 +19,7 @@ public class JsonSerde {
GSON = new GsonBuilder() //
.disableHtmlEscaping() //
// needed to convert the byte[] to a base64 encoded String
.registerTypeHierarchyAdapter(byte[].class, new ByteArrayToBase64TypeAdapter()) //
.registerTypeHierarchyAdapter(byte[].class, new ByteArrayAdapter()) //
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) //
.setPrettyPrinting() //
.create();
@@ -33,14 +29,28 @@ public class JsonSerde {
return GSON.toJson(manifest);
}
private static class ByteArrayToBase64TypeAdapter implements JsonSerializer<byte[]>, JsonDeserializer<byte[]> {
private static class ByteArrayAdapter extends TypeAdapter<byte[]> {
public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return Base64.getDecoder().decode(json.getAsString());
@Override
public void write(JsonWriter out, byte[] byteValue) throws IOException {
out.value(new String(Base64.getEncoder().encode(byteValue)));
}
public JsonElement serialize(byte[] src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(Base64.getEncoder().withoutPadding().encodeToString(src));
@Override
public byte[] read(JsonReader in) {
try {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return new byte[]{};
}
String byteValue = in.nextString();
if (byteValue != null) {
return Base64.getDecoder().decode(byteValue);
}
return new byte[]{};
} catch (Exception e) {
throw new JsonParseException(e);
}
}
}
}

View File

@@ -2,10 +2,37 @@ package org.extism.sdk.wasm;
/**
* WASM Source represented by raw bytes.
*
* @param name
* @param data the byte array representing the WASM code
* @param hash
*/
public record ByteArrayWasmSource(String name, byte[] data, String hash) implements WasmSource {
public class ByteArrayWasmSource implements WasmSource {
private final String name;
private final byte[] data;
private final String hash;
/**
* Constructor
* @param name
* @param data the byte array representing the WASM code
* @param hash
*/
public ByteArrayWasmSource(String name, byte[] data, String hash) {
this.name = name;
this.data = data;
this.hash = hash;
}
@Override
public String name() {
return name;
}
@Override
public String hash() {
return hash;
}
public byte[] data() {
return data;
}
}

View File

@@ -2,11 +2,39 @@ package org.extism.sdk.wasm;
/**
* WASM Source represented by a file referenced by a path.
*
* @param name
* @param path
* @param hash
*/
public record PathWasmSource(String name, String path, String hash) implements WasmSource {
public class PathWasmSource implements WasmSource {
private final String name;
private final String path;
private final String hash;
/**
* Constructor
* @param name
* @param path
* @param hash
*/
public PathWasmSource(String name, String path, String hash) {
this.name = name;
this.path = path;
this.hash = hash;
}
@Override
public String name() {
return name;
}
@Override
public String hash() {
return hash;
}
public String path() {
return path;
}
}

View File

@@ -6,6 +6,7 @@ import org.extism.sdk.support.JsonSerde;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.HashMap;
import static org.assertj.core.api.Assertions.assertThat;
import static org.extism.sdk.TestWasmSources.CODE;
@@ -16,13 +17,16 @@ public class ManifestTests {
@Test
public void shouldSerializeManifestWithWasmSourceToJson() {
var manifest = new Manifest(CODE.pathWasmSource());
var paths = new HashMap<String, String>();
paths.put("/tmp/foo", "/tmp/extism-plugins/foo");
var manifest = new Manifest(List.of(CODE.pathWasmSource()), null, null, null, paths);
var json = JsonSerde.toJson(manifest);
assertNotNull(json);
assertJson(json).at("/wasm").isArray();
assertJson(json).at("/wasm").hasSize(1);
assertJson(json).at("/allowed_paths").isObject();
assertJson(json).at("/allowed_paths").hasSize(1);
}
@Test

View File

@@ -1,12 +1,12 @@
package org.extism.sdk;
import com.sun.jna.Pointer;
import org.extism.sdk.manifest.Manifest;
import org.extism.sdk.manifest.MemoryOptions;
import org.extism.sdk.wasm.WasmSourceResolver;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Map;
import java.util.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.extism.sdk.TestWasmSources.CODE;
@@ -42,14 +42,12 @@ public class PluginTests {
assertThat(output).isEqualTo("{\"count\": 3}");
}
// TODO This test breaks on CI with error:
// data did not match any variant of untagged enum Wasm at line 8 column 3
// @Test
// public void shouldInvokeFunctionFromByteArrayWasmSource() {
// var manifest = new Manifest(CODE.byteArrayWasmSource());
// var output = Extism.invokeFunction(manifest, "count_vowels", "Hello World");
// assertThat(output).isEqualTo("{\"count\": 3}");
// }
@Test
public void shouldInvokeFunctionFromByteArrayWasmSource() {
var manifest = new Manifest(CODE.byteArrayWasmSource());
var output = Extism.invokeFunction(manifest, "count_vowels", "Hello World");
assertThat(output).isEqualTo("{\"count\": 3}");
}
@Test
public void shouldFailToInvokeUnknownFunction() {
@@ -80,7 +78,7 @@ public class PluginTests {
var input = "Hello World";
try (var ctx = new Context()) {
try (var plugin = ctx.newPlugin(manifest, false)) {
try (var plugin = ctx.newPlugin(manifest, false, null)) {
var output = plugin.call(functionName, input);
assertThat(output).isEqualTo("{\"count\": 3}");
}
@@ -94,7 +92,7 @@ public class PluginTests {
var input = "Hello World";
try (var ctx = new Context()) {
try (var plugin = ctx.newPlugin(manifest, false)) {
try (var plugin = ctx.newPlugin(manifest, false, null)) {
var output = plugin.call(functionName, input);
assertThat(output).isEqualTo("{\"count\": 3}");
@@ -104,4 +102,118 @@ public class PluginTests {
}
}
@Test
public void shouldAllowInvokeHostFunctionFromPDK() {
var parametersTypes = new LibExtism.ExtismValType[]{LibExtism.ExtismValType.I64};
var resultsTypes = new LibExtism.ExtismValType[]{LibExtism.ExtismValType.I64};
class MyUserData extends HostUserData {
private String data1;
private int data2;
public MyUserData(String data1, int data2) {
super();
this.data1 = data1;
this.data2 = data2;
}
}
ExtismFunction helloWorldFunction = (ExtismFunction<MyUserData>) (plugin, params, returns, data) -> {
System.out.println("Hello from Java Host Function!");
System.out.println(String.format("Input string received from plugin, %s", plugin.inputString(params[0])));
int offs = plugin.alloc(4);
Pointer mem = plugin.memory();
mem.write(offs, "test".getBytes(), 0, 4);
returns[0].v.i64 = offs;
data.ifPresent(d -> System.out.println(String.format("Host user data, %s, %d", d.data1, d.data2)));
};
HostFunction helloWorld = new HostFunction<>(
"hello_world",
parametersTypes,
resultsTypes,
helloWorldFunction,
Optional.of(new MyUserData("test", 2))
);
HostFunction[] functions = {helloWorld};
try (var ctx = new Context()) {
Manifest manifest = new Manifest(Arrays.asList(CODE.pathWasmFunctionsSource()));
String functionName = "count_vowels";
try (var plugin = ctx.newPlugin(manifest, true, functions)) {
var output = plugin.call(functionName, "this is a test");
assertThat(output).isEqualTo("test");
}
}
}
@Test
public void shouldAllowInvokeHostFunctionWithoutUserData() {
var parametersTypes = new LibExtism.ExtismValType[]{LibExtism.ExtismValType.I64};
var resultsTypes = new LibExtism.ExtismValType[]{LibExtism.ExtismValType.I64};
ExtismFunction helloWorldFunction = (plugin, params, returns, data) -> {
System.out.println("Hello from Java Host Function!");
System.out.println(String.format("Input string received from plugin, %s", plugin.inputString(params[0])));
int offs = plugin.alloc(4);
Pointer mem = plugin.memory();
mem.write(offs, "test".getBytes(), 0, 4);
returns[0].v.i64 = offs;
assertThat(data.isEmpty());
};
HostFunction f = new HostFunction<>(
"hello_world",
parametersTypes,
resultsTypes,
helloWorldFunction,
Optional.empty()
)
.withNamespace("env");
HostFunction g = new HostFunction<>(
"hello_world",
parametersTypes,
resultsTypes,
helloWorldFunction,
Optional.empty()
)
.withNamespace("test");
HostFunction[] functions = {f,g};
try (var ctx = new Context()) {
Manifest manifest = new Manifest(Arrays.asList(CODE.pathWasmFunctionsSource()));
String functionName = "count_vowels";
try (var plugin = ctx.newPlugin(manifest, true, functions)) {
var output = plugin.call(functionName, "this is a test");
assertThat(output).isEqualTo("test");
}
}
}
@Test
public void shouldFailToInvokeUnknownHostFunction() {
try (var ctx = new Context()) {
Manifest manifest = new Manifest(Arrays.asList(CODE.pathWasmFunctionsSource()));
String functionName = "count_vowels";
try {
var plugin = ctx.newPlugin(manifest, true, null);
plugin.call(functionName, "this is a test");
} catch (ExtismException e) {
assertThat(e.getMessage()).contains("unknown import: `env::hello_world` has not been defined");
}
}
}
}

View File

@@ -16,19 +16,28 @@ public enum TestWasmSources {
public Path getWasmFilePath() {
return Paths.get(WASM_LOCATION, "code.wasm");
}
public Path getWasmFunctionsFilePath() {
return Paths.get(WASM_LOCATION, "code-functions.wasm");
}
};
public static final String WASM_LOCATION = "src/test/resources";
public abstract Path getWasmFilePath();
public abstract Path getWasmFunctionsFilePath();
public PathWasmSource pathWasmSource() {
return resolvePathWasmSource(getWasmFilePath());
}
public PathWasmSource pathWasmFunctionsSource() {
return resolvePathWasmSource(getWasmFunctionsFilePath());
}
public ByteArrayWasmSource byteArrayWasmSource() {
try {
var wasmBytes = Files.readAllBytes(getWasmFilePath());
byte[] wasmBytes = Files.readAllBytes(getWasmFilePath());
return new WasmSourceResolver().resolve("wasm@" + Arrays.hashCode(wasmBytes), wasmBytes);
} catch (IOException ioe) {
throw new RuntimeException(ioe);

Binary file not shown.

View File

@@ -1,10 +0,0 @@
prefix=/usr/local
exec_prefix=${prefix}
includedir=${prefix}/include
libdir=${exec_prefix}/lib
Name: extism
Description: The Extism universal plug-in system.
Version: 0.1.0
Cflags: -I${includedir}
Libs: -L${libdir} -lextism

View File

@@ -1,6 +1,6 @@
[package]
name = "libextism"
version = "0.1.0"
version = "0.3.0"
edition = "2021"
authors = ["The Extism Authors", "oss@extism.org"]
license = "BSD-3-Clause"
@@ -20,4 +20,4 @@ default = ["http", "register-http", "register-filesystem"]
nn = ["extism-runtime/nn"]
register-http = ["extism-runtime/register-http"] # enables wasm to be downloaded using http
register-filesystem = ["extism-runtime/register-filesystem"] # enables wasm to be loaded from disk
http = ["extism-runtime/http"] # enables extism_http_request
http = ["extism-runtime/http"] # enables extism_http_request

View File

@@ -1,6 +1,6 @@
[package]
name = "extism-manifest"
version = "0.1.0"
version = "0.3.0"
edition = "2021"
authors = ["The Extism Authors", "oss@extism.org"]
license = "BSD-3-Clause"

View File

@@ -6,6 +6,7 @@ pub type ManifestMemory = MemoryOptions;
#[derive(Default, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub struct MemoryOptions {
#[serde(alias = "max")]
pub max_pages: Option<u32>,
@@ -13,6 +14,7 @@ pub struct MemoryOptions {
#[derive(serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub struct HttpRequest {
pub url: String,
#[serde(default)]
@@ -43,6 +45,7 @@ impl HttpRequest {
#[derive(Default, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub struct WasmMetadata {
pub name: Option<String>,
pub hash: Option<String>,
@@ -81,6 +84,7 @@ pub type ManifestWasm = Wasm;
#[derive(serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[serde(untagged)]
#[serde(deny_unknown_fields)]
pub enum Wasm {
File {
path: PathBuf,
@@ -151,6 +155,7 @@ fn base64_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::
#[derive(Default, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[serde(deny_unknown_fields)]
pub struct Manifest {
#[serde(default)]
pub wasm: Vec<Wasm>,
@@ -250,16 +255,19 @@ impl Manifest {
}
mod base64 {
use base64::{engine::general_purpose, Engine as _};
use serde::{Deserialize, Serialize};
use serde::{Deserializer, Serializer};
pub fn serialize<S: Serializer>(v: &Vec<u8>, s: S) -> Result<S::Ok, S::Error> {
let base64 = base64::encode(v);
let base64 = general_purpose::STANDARD.encode(v);
String::serialize(&base64, s)
}
pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<u8>, D::Error> {
let base64 = String::deserialize(d)?;
base64::decode(base64.as_bytes()).map_err(serde::de::Error::custom)
general_purpose::STANDARD
.decode(base64.as_bytes())
.map_err(serde::de::Error::custom)
}
}

1
node/code-functions.wasm Symbolic link
View File

@@ -0,0 +1 @@
../wasm/code-functions.wasm

View File

@@ -1,9 +1,31 @@
const { withContext, Context } = require('./dist/index.js');
const { readFileSync } = require('fs');
const {
withContext,
Context,
HostFunction,
ValType,
} = require("./dist/index.js");
const { readFileSync } = require("fs");
function f(currentPlugin, inputs, outputs, userData) {
console.log(currentPlugin.inputString(inputs[0]));
console.log("Hello from Javascript!");
console.log(userData);
outputs[0] = inputs[0];
}
let hello_world = new HostFunction(
"hello_world",
[ValType.I64],
[ValType.I64],
f,
"Hello again!"
);
let functions = [hello_world];
withContext(async function (context) {
let wasm = readFileSync("../wasm/code.wasm");
let p = context.plugin(wasm);
let wasm = readFileSync("code-functions.wasm");
let p = context.plugin(wasm, true, functions);
if (!p.functionExists("count_vowels")) {
console.log("no function 'count_vowels' in wasm");
@@ -16,7 +38,7 @@ withContext(async function (context) {
});
// or, use a context like this:
let ctx = new Context();
let wasm = readFileSync("../wasm/code.wasm");
let p = ctx.plugin(wasm);
// let ctx = new Context();
// let wasm = readFileSync("code-functions.wasm");
// let p = ctx.plugin(wasm);
// ... where the context can be passed around to various functions etc.

3848
node/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "@extism/extism",
"version": "0.1.0",
"version": "0.3.0",
"description": "Extism Host SDK for Node",
"keywords": [
"extism",
@@ -21,12 +21,17 @@
},
"scripts": {
"prepare": "npm run build",
"example": "node example.js",
"example": "npm run build && node example.js",
"build": "tsc",
"test": "jest --coverage"
},
"dependencies": {
"ffi-napi": "^4.0.3"
"@types/ref-array-di": "^1.2.5",
"ffi-napi": "^4.0.3",
"ref-array-di": "^1.2.2",
"ref-napi": "^3.0.3",
"ref-struct-di": "^1.1.1",
"ref-union-di": "^1.0.1"
},
"publishConfig": {
"access": "public"
@@ -36,7 +41,7 @@
"@types/jest": "^29.2.0",
"@types/node": "^18.11.4",
"jest": "^29.2.2",
"prettier": "2.8.2",
"prettier": "2.8.4",
"ts-jest": "^29.0.3",
"ts-node": "^10.9.1",
"typedoc": "^0.23.18",

View File

@@ -1,30 +1,100 @@
import ffi from "ffi-napi";
import ref from "ref-napi";
import path from "path";
const context = "void*";
var ArrayType = require("ref-array-di")(ref);
var StructType = require("ref-struct-di")(ref);
var UnionType = require("ref-union-di")(ref);
const opaque = ref.types.void;
const context = ref.refType(opaque);
const function_t = ref.refType(opaque);
const pluginIndex = ref.types.int32;
let ValTypeArray = ArrayType(ref.types.int);
let PtrArray = new ArrayType("void*");
let ValUnion = new UnionType({
i32: ref.types.uint32,
i64: ref.types.uint64,
f32: ref.types.float,
f64: ref.types.double,
});
/**
* Val struct, low-level WebAssembly values
*/
let Val = new StructType({
t: ref.types.int,
v: ValUnion,
});
/**
* Array of `Val`
*/
let ValArray = ArrayType(Val);
const _functions = {
extism_context_new: [context, []],
extism_context_free: ["void", [context]],
extism_plugin_new: ["int32", [context, "string", "uint64", "bool"]],
extism_plugin_new: [
pluginIndex,
[context, "string", "uint64", PtrArray, "uint64", "bool"],
],
extism_plugin_update: [
"bool",
[context, "int32", "string", "uint64", "bool"],
[context, pluginIndex, "string", "uint64", PtrArray, "uint64", "bool"],
],
extism_error: ["char*", [context, "int32"]],
extism_error: ["string", [context, pluginIndex]],
extism_plugin_call: [
"int32",
[context, "int32", "string", "string", "uint64"],
[context, pluginIndex, "string", "string", "uint64"],
],
extism_plugin_output_length: ["uint64", [context, "int32"]],
extism_plugin_output_data: ["uint8*", [context, "int32"]],
extism_plugin_output_length: ["uint64", [context, pluginIndex]],
extism_plugin_output_data: ["uint8*", [context, pluginIndex]],
extism_log_file: ["bool", ["string", "char*"]],
extism_plugin_function_exists: ["bool", [context, "int32", "string"]],
extism_plugin_config: ["void", [context, "int32", "char*", "uint64"]],
extism_plugin_free: ["void", [context, "int32"]],
extism_plugin_function_exists: ["bool", [context, pluginIndex, "string"]],
extism_plugin_config: ["void", [context, pluginIndex, "char*", "uint64"]],
extism_plugin_free: ["void", [context, pluginIndex]],
extism_context_reset: ["void", [context]],
extism_version: ["char*", []],
extism_version: ["string", []],
extism_function_new: [
function_t,
[
"string",
ValTypeArray,
"uint64",
ValTypeArray,
"uint64",
"void*",
"void*",
"void*",
],
],
extism_function_free: ["void", [function_t]],
extism_function_set_namespace: ["void", [function_t, "string"]],
extism_current_plugin_memory: ["uint8*", ["void*"]],
extism_current_plugin_memory_alloc: ["uint64", ["void*", "uint64"]],
extism_current_plugin_memory_length: ["uint64", ["void*", "uint64"]],
extism_current_plugin_memory_free: ["void", ["void*", "uint64"]],
extism_plugin_cancel_handle: ["void*", [context, pluginIndex]],
extism_plugin_cancel: ["bool", ["void*"]],
};
/**
* An enumeration of all possible `Val` types
*/
export enum ValType {
I32 = 0,
I64,
F32,
F64,
V128,
FuncRef,
ExternRef,
}
interface LibExtism {
extism_context_new: () => Buffer;
extism_context_free: (ctx: Buffer) => void;
@@ -32,6 +102,8 @@ interface LibExtism {
ctx: Buffer,
data: string | Buffer,
data_len: number,
functions: Buffer,
nfunctions: number,
wasi: boolean
) => number;
extism_plugin_update: (
@@ -39,9 +111,11 @@ interface LibExtism {
plugin_id: number,
data: string | Buffer,
data_len: number,
functions: Buffer,
nfunctions: number,
wasi: boolean
) => boolean;
extism_error: (ctx: Buffer, plugin_id: number) => Buffer;
extism_error: (ctx: Buffer, plugin_id: number) => string;
extism_plugin_call: (
ctx: Buffer,
plugin_id: number,
@@ -50,7 +124,7 @@ interface LibExtism {
input_len: number
) => number;
extism_plugin_output_length: (ctx: Buffer, plugin_id: number) => number;
extism_plugin_output_data: (ctx: Buffer, plugin_id: Number) => Uint8Array;
extism_plugin_output_data: (ctx: Buffer, plugin_id: number) => Uint8Array;
extism_log_file: (file: string, level: string) => boolean;
extism_plugin_function_exists: (
ctx: Buffer,
@@ -65,7 +139,25 @@ interface LibExtism {
) => void;
extism_plugin_free: (ctx: Buffer, plugin_id: number) => void;
extism_context_reset: (ctx: Buffer) => void;
extism_version: () => Buffer;
extism_version: () => string;
extism_function_new: (
name: string,
inputs: Buffer,
nInputs: number,
outputs: Buffer,
nOutputs: number,
f: Buffer,
user_data: Buffer | null,
free: Buffer | null
) => Buffer;
extism_function_set_namespace: (f: Buffer, s: string) => void;
extism_function_free: (f: Buffer) => void;
extism_current_plugin_memory: (p: Buffer) => Buffer;
extism_current_plugin_memory_alloc: (p: Buffer, n: number) => number;
extism_current_plugin_memory_length: (p: Buffer, n: number) => number;
extism_current_plugin_memory_free: (p: Buffer, n: number) => void;
extism_plugin_cancel_handle: (p: Buffer, n: number) => Buffer;
extism_plugin_cancel: (p: Buffer) => boolean;
}
function locate(paths: string[]): LibExtism {
@@ -110,19 +202,19 @@ export function setLogFile(filename: string, level?: string) {
* @returns The version string of the Extism runtime
*/
export function extismVersion(): string {
return lib.extism_version().toString();
return lib.extism_version();
}
// @ts-ignore
const pluginRegistry = new FinalizationRegistry(({ id, pointer }) => {
if (id && pointer) lib.extism_plugin_free(pointer, id);
});
// @ts-ignore
const contextRegistry = new FinalizationRegistry((pointer) => {
if (pointer) lib.extism_context_free(pointer);
});
// @ts-ignore
const functionRegistry = new FinalizationRegistry((pointer) => {
if (pointer) lib.extism_function_free(pointer);
});
/**
* Represents a path or url to a WASM module
*/
@@ -161,7 +253,7 @@ export type ManifestWasm = ManifestWasmFile | ManifestWasmData;
/**
* The manifest which describes the {@link Plugin} code and
* runtime constraints.
*
*
* @see [Extism > Concepts > Manifest](https://extism.org/docs/concepts/manifest)
*/
export type Manifest = {
@@ -214,7 +306,7 @@ export class Context {
*/
constructor() {
this.pointer = lib.extism_context_new();
contextRegistry.register(this, this.pointer, this);
contextRegistry.register(this, this.pointer, this.pointer);
}
/**
@@ -225,19 +317,24 @@ export class Context {
* @param config - Config details for the plugin
* @returns A new Plugin scoped to this Context
*/
plugin(manifest: ManifestData, wasi: boolean = false, config?: PluginConfig) {
return new Plugin(this, manifest, wasi, config);
plugin(
manifest: ManifestData,
wasi: boolean = false,
functions: HostFunction[] = [],
config?: PluginConfig
) {
return new Plugin(this, manifest, wasi, functions, config);
}
/**
* Frees the context. Should be called after the context is not needed to reclaim the memory.
*/
free() {
contextRegistry.unregister(this.pointer);
if (this.pointer) {
contextRegistry.unregister(this);
lib.extism_context_free(this.pointer);
this.pointer = null;
}
this.pointer = null;
}
/**
@@ -268,12 +365,226 @@ export async function withContext(f: (ctx: Context) => Promise<any>) {
}
}
/**
* Provides access to the plugin that is currently running from inside a {@link HostFunction}
*/
export class CurrentPlugin {
pointer: Buffer;
constructor(pointer: Buffer) {
this.pointer = pointer;
}
/**
* Access plugin's memory
* @param offset - The offset in memory
* @returns a pointer to the provided offset
*/
memory(offset: number): Buffer {
let length = lib.extism_current_plugin_memory_length(this.pointer, offset);
return Buffer.from(
lib.extism_current_plugin_memory(this.pointer).buffer,
offset,
length
);
}
/**
* Allocate a new memory block
* @param n - The number of bytes to allocate
* @returns the offset to the newly allocated block
*/
memoryAlloc(n: number): number {
return lib.extism_current_plugin_memory_alloc(this.pointer, n);
}
/**
* Free a memory block
* @param offset - The offset of the block to free
*/
memoryFree(offset: number) {
return lib.extism_current_plugin_memory_free(this.pointer, offset);
}
/**
* Get the length of a memory block
* @param offset - The offset of the block
* @returns the length of the block specified by `offset`
*/
memoryLength(offset: number): number {
return lib.extism_current_plugin_memory_length(this.pointer, offset);
}
/**
* Return a string from a host function
* @param output - The output to set
* @param s - The string to return
*/
returnString(output: typeof Val, s: string) {
var offs = this.memoryAlloc(Buffer.byteLength(s));
this.memory(offs).write(s);
output.v.i64 = offs;
}
/**
* Return bytes from a host function
* @param output - The output to set
* @param b - The buffer to return
*/
returnBytes(output: typeof Val, b: Buffer) {
var offs = this.memoryAlloc(b.length);
this.memory(offs).fill(b);
output.v.i64 = offs;
}
/**
* Get bytes from host function parameter
* @param input - The input to read
*/
inputBytes(input: typeof Val): Buffer {
return this.memory(input.v.i64)
}
/**
* Get string from host function parameter
* @param input - The input to read
*/
inputString(input: typeof Val): string {
return this.memory(input.v.i64).toString()
}
}
/**
* Allows for the host to define functions that can be called from WebAseembly
*/
export class HostFunction {
callback: any;
pointer: Buffer | null;
name: string;
userData: any[];
inputs: typeof ValTypeArray;
outputs: typeof ValTypeArray;
constructor(
name: string,
inputs: ValType[],
outputs: ValType[],
f: any,
...userData: any
) {
this.userData = userData;
this.callback = ffi.Callback(
"void",
[
"void*",
ref.refType(Val),
"uint64",
ref.refType(Val),
"uint64",
"void*",
],
(
currentPlugin: Buffer,
inputs: Buffer,
nInputs: number,
outputs: Buffer,
nOutputs: number,
user_data
) => {
let inputArr = [];
let outputArr = [];
for (var i = 0; i < nInputs; i++) {
inputArr.push(Val.get(inputs, i));
}
for (var i = 0; i < nOutputs; i++) {
outputArr.push(Val.get(outputs, i));
}
f(
new CurrentPlugin(currentPlugin),
inputArr,
outputArr,
...this.userData
);
for (var i = 0; i < nOutputs; i++) {
Val.set(outputs, i, outputArr[i]);
}
}
);
this.name = name;
this.inputs = new ValTypeArray(inputs);
this.outputs = new ValTypeArray(outputs);
this.pointer = lib.extism_function_new(
this.name,
this.inputs,
this.inputs.length,
this.outputs,
this.outputs.length,
this.callback,
null,
null
);
this.userData = userData;
functionRegistry.register(this, this.pointer, this.pointer);
}
/**
* Set function namespace
*/
setNamespace(name: string) {
if (this.pointer !== null) {
lib.extism_function_set_namespace(this.pointer, name)
}
}
withNamespace(name: string) : HostFunction {
this.setNamespace(name)
return this;
}
/**
* Free a host function - this should be called to cleanup the associated resources
*/
free() {
functionRegistry.unregister(this.pointer);
if (this.pointer === null) {
return;
}
lib.extism_function_free(this.pointer);
this.pointer = null;
}
}
/**
* CancelHandle is used to cancel a running Plugin
*/
export class CancelHandle {
handle: Buffer
constructor(handle: Buffer) {
this.handle = handle;
}
/**
* Cancel execution of the Plugin associated with the CancelHandle
*/
cancel(): boolean {
return lib.extism_plugin_cancel(this.handle);
}
}
/**
* A Plugin represents an instance of your WASM program from the given manifest.
*/
export class Plugin {
id: number;
ctx: Context;
functions: typeof PtrArray;
token: { id: number; pointer: Buffer };
/**
* Constructor for a plugin. @see {@link Context#plugin}.
@@ -281,12 +592,14 @@ export class Plugin {
* @param ctx - The context to manage this plugin
* @param manifest - The {@link Manifest}
* @param wasi - Set to true to enable WASI support
* @param functions - An array of {@link HostFunction}
* @param config - The plugin config
*/
constructor(
ctx: Context,
manifest: ManifestData,
wasi: boolean = false,
functions: HostFunction[] = [],
config?: PluginConfig
) {
let dataRaw: string | Buffer;
@@ -298,10 +611,16 @@ export class Plugin {
throw Error(`Unknown manifest type ${typeof manifest}`);
}
if (!ctx.pointer) throw Error("No Context set");
this.functions = new PtrArray(functions.length);
for (var i = 0; i < functions.length; i++) {
this.functions[i] = functions[i].pointer;
}
let plugin = lib.extism_plugin_new(
ctx.pointer,
dataRaw,
Buffer.byteLength(dataRaw, 'utf-8'),
Buffer.byteLength(dataRaw, "utf-8"),
this.functions,
functions.length,
wasi
);
if (plugin < 0) {
@@ -312,27 +631,43 @@ export class Plugin {
throw `Unable to load plugin: ${err.toString()}`;
}
this.id = plugin;
this.token = { id: this.id, pointer: ctx.pointer };
this.ctx = ctx;
pluginRegistry.register(
this,
{ id: this.id, pointer: this.ctx.pointer },
this
);
if (config != null) {
let s = JSON.stringify(config);
lib.extism_plugin_config(ctx.pointer, this.id, s, Buffer.byteLength(s, 'utf-8'),);
lib.extism_plugin_config(
ctx.pointer,
this.id,
s,
Buffer.byteLength(s, "utf-8")
);
}
}
/**
* Return a new `CancelHandle`, which can be used to cancel a running Plugin
*/
cancelHandle(): CancelHandle {
if (!this.ctx.pointer) throw Error("No Context set");
let handle = lib.extism_plugin_cancel_handle(this.ctx.pointer, this.id);
return new CancelHandle(handle);
}
/**
* Update an existing plugin with new WASM or manifest
*
* @param manifest - The new {@link Manifest} data
* @param wasi - Set to true to enable WASI support
* @param functions - An array of {@link HostFunction}
* @param config - The new plugin config
*/
update(manifest: ManifestData, wasi: boolean = false, config?: PluginConfig) {
update(
manifest: ManifestData,
wasi: boolean = false,
functions: HostFunction[] = [],
config?: PluginConfig
) {
let dataRaw: string | Buffer;
if (Buffer.isBuffer(manifest) || typeof manifest === "string") {
dataRaw = manifest;
@@ -342,11 +677,17 @@ export class Plugin {
throw Error("Unknown manifest type type");
}
if (!this.ctx.pointer) throw Error("No Context set");
this.functions = new PtrArray(functions.length);
for (var i = 0; i < functions.length; i++) {
this.functions[i] = functions[i].pointer;
}
const ok = lib.extism_plugin_update(
this.ctx.pointer,
this.id,
dataRaw,
Buffer.byteLength(dataRaw, 'utf-8'),
Buffer.byteLength(dataRaw, "utf-8"),
this.functions,
functions.length,
wasi
);
if (!ok) {
@@ -359,7 +700,12 @@ export class Plugin {
if (config != null) {
let s = JSON.stringify(config);
lib.extism_plugin_config(this.ctx.pointer, this.id, s, Buffer.byteLength(s, 'utf-8'),);
lib.extism_plugin_config(
this.ctx.pointer,
this.id,
s,
Buffer.byteLength(s, "utf-8")
);
}
}
@@ -393,7 +739,7 @@ export class Plugin {
*
* @param functionName - The name of the function
* @param input - The input data
* @returns A Buffer repreesentation of the output
*@returns A Buffer repreesentation of the output
*/
async call(functionName: string, input: string | Buffer): Promise<Buffer> {
return new Promise<Buffer>((resolve, reject) => {
@@ -403,7 +749,7 @@ export class Plugin {
this.id,
functionName,
input.toString(),
Buffer.byteLength(input, 'utf-8'),
Buffer.byteLength(input, "utf-8")
);
if (rc !== 0) {
var err = lib.extism_error(this.ctx.pointer, this.id);
@@ -427,8 +773,7 @@ export class Plugin {
* Free a plugin, this should be called when the plugin is no longer needed
*/
free() {
if (this.ctx.pointer && this.id !== -1) {
pluginRegistry.unregister(this);
if (this.ctx.pointer && this.id >= 0) {
lib.extism_plugin_free(this.ctx.pointer, this.id);
this.id = -1;
}

Binary file not shown.

View File

@@ -2,14 +2,23 @@ import * as extism from "../src/index";
import { readFileSync } from "fs";
import { join } from "path";
function manifest(): extism.Manifest {
function manifest(functions: boolean = false): extism.Manifest {
return {
wasm: [{ path: join(__dirname, "/code.wasm") }],
wasm: [
{
path: join(
__dirname,
functions
? "/../../wasm/code-functions.wasm"
: "/../../wasm/code.wasm"
),
},
],
};
}
function wasmBuffer(): Buffer {
return readFileSync(join(__dirname, "/code.wasm"));
return readFileSync(join(__dirname, "/../../wasm/code.wasm"));
}
describe("test extism", () => {
@@ -102,4 +111,27 @@ describe("test extism", () => {
).rejects.toMatch(/Plugin error/);
});
});
test("host functions work", async () => {
await extism.withContext(async (ctx: extism.Context) => {
const plugin = ctx.plugin(manifest(true), true, [
new extism.HostFunction(
"hello_world",
[extism.ValType.I64],
[extism.ValType.I64],
(plugin: any, params: any, results: any, user_data: string) => {
const offs = plugin.memoryAlloc(user_data.length);
const mem = plugin.memory(offs);
mem.write(user_data);
results[0].v.i64 = offs;
},
"test"
),
]);
const res = await plugin.call("count_vowels", "aaa");
expect(res.toString()).toBe("test");
});
});
});

Binary file not shown.

15
ocaml/Makefile Normal file
View File

@@ -0,0 +1,15 @@
VERSION?=0.2.0
build:
dune build
test:
dune test
format:
dune build @fmt --auto-promote
prepare:
opam install .. --deps-only
publish:
opam publish -v $(VERSION) -t $(VERSION) ..

View File

@@ -7,7 +7,7 @@ let main file func_name input =
with_context @@ fun ctx ->
let input = if String.equal input "-" then read_stdin () else input in
let file = In_channel.with_open_bin file In_channel.input_all in
let plugin = Plugin.make ctx file ~wasi:true |> Result.get_ok in
let plugin = Plugin.create ctx file ~wasi:true |> Result.get_ok in
let res = Plugin.call plugin ~name:func_name input |> Result.get_ok in
print_endline res

View File

@@ -27,7 +27,16 @@ let locate () =
init paths
|> function
| Some x -> x
| None -> raise Not_found
| None -> (
let fail n =
Printf.fprintf stderr
"Unable to find Extism installation, see \
https://extism.org/docs/install/ for installation instructions\n";
exit n
in
match Sys.getenv_opt "EXTISM_TEST_NO_LIB" with
| None -> fail 1
| Some _ -> fail 0)
let from =
let filename = locate () in
@@ -40,13 +49,62 @@ let context = ptr void
let extism_context_new = fn "extism_context_new" (void @-> returning context)
let extism_context_free = fn "extism_context_free" (context @-> returning void)
module Extism_val_type = struct
type t = I32 | I64 | F32 | F64 | V128 | FuncRef | ExternRef
let to_int = function
| I32 -> 0
| I64 -> 1
| F32 -> 2
| F64 -> 3
| V128 -> 4
| FuncRef -> 5
| ExternRef -> 6
let of_int = function
| 0 -> I32
| 1 -> I64
| 2 -> F32
| 3 -> F64
| 4 -> V128
| 5 -> FuncRef
| 6 -> ExternRef
| n -> invalid_arg ("Extism_val_type.of_int: " ^ string_of_int n)
let t : t typ = view ~read:of_int ~write:to_int int
end
module Extism_val_union = struct
type t
let t : t union typ = union "ExtismValUnion"
let i32 = field t "i32" int32_t
let i64 = field t "i64" int64_t
let f32 = field t "f32" float
let f64 = field t "f64" double
let () = seal t
end
module Extism_val = struct
type t
let t : t structure typ = structure "ExtismVal"
let ty = field t "t" Extism_val_type.t
let v = field t "v" Extism_val_union.t
let () = seal t
end
let extism_plugin_new =
fn "extism_plugin_new"
(context @-> string @-> uint64_t @-> bool @-> returning int32_t)
(context @-> string @-> uint64_t
@-> ptr (ptr void)
@-> uint64_t @-> bool @-> returning int32_t)
let extism_plugin_update =
fn "extism_plugin_update"
(context @-> int32_t @-> string @-> uint64_t @-> bool @-> returning bool)
(context @-> int32_t @-> string @-> uint64_t
@-> ptr (ptr void)
@-> uint64_t @-> bool @-> returning bool)
let extism_plugin_config =
fn "extism_plugin_config"
@@ -84,3 +142,44 @@ let extism_context_reset = fn "extism_context_reset" (context @-> returning void
let extism_plugin_function_exists =
fn "extism_plugin_function_exists"
(context @-> int32_t @-> string @-> returning bool)
let extism_function_type =
Foreign.funptr ~runtime_lock:true
(ptr void @-> ptr Extism_val.t @-> uint64_t @-> ptr Extism_val.t
@-> uint64_t @-> ptr void @-> returning void)
let extism_free_user_data =
Foreign.funptr_opt ~runtime_lock:true (ptr void @-> returning void)
let extism_function_new =
fn "extism_function_new"
(string @-> ptr Extism_val_type.t @-> uint64_t @-> ptr Extism_val_type.t
@-> uint64_t @-> extism_function_type @-> ptr void @-> extism_free_user_data
@-> returning (ptr void))
let extism_function_set_namespace =
fn "extism_function_set_namespace" (ptr void @-> string @-> returning void)
let extism_function_free =
fn "extism_function_free" (ptr void @-> returning void)
let extism_current_plugin_memory =
fn "extism_current_plugin_memory" (ptr void @-> returning (ptr uint8_t))
let extism_current_plugin_memory_length =
fn "extism_current_plugin_memory_length"
(ptr void @-> uint64_t @-> returning uint64_t)
let extism_current_plugin_memory_alloc =
fn "extism_current_plugin_memory_alloc"
(ptr void @-> uint64_t @-> returning uint64_t)
let extism_current_plugin_memory_free =
fn "extism_current_plugin_memory_free"
(ptr void @-> uint64_t @-> returning void)
let extism_plugin_cancel_handle =
fn "extism_plugin_cancel_handle" (context @-> int32_t @-> returning (ptr void))
let extism_plugin_cancel =
fn "extism_plugin_cancel" (ptr void @-> returning bool)

View File

@@ -0,0 +1,84 @@
open Ctypes
type t = unit ptr
type memory_block = { offs : Unsigned.UInt64.t; len : Unsigned.UInt64.t }
let memory ?(offs = Unsigned.UInt64.zero) t =
Bindings.extism_current_plugin_memory t +@ Unsigned.UInt64.to_int offs
let find t offs =
let len = Bindings.extism_current_plugin_memory_length t offs in
if Unsigned.UInt64.(equal zero len) then None else Some { offs; len }
let alloc t len =
let len = Unsigned.UInt64.of_int len in
let offs = Bindings.extism_current_plugin_memory_alloc t len in
{ offs; len }
let free t { offs; _ } = Bindings.extism_current_plugin_memory_free t offs
module Memory_block = struct
let of_val t v =
match Types.Val.to_i64 v with
| None -> None
| Some v ->
let offs = Unsigned.UInt64.of_int64 v in
find t offs
let of_val_exn t v =
match of_val t v with
| None -> invalid_arg "Memory_block.of_val_exn"
| Some v -> v
let to_val { offs; len = _ } =
Types.Val.of_i64 (Unsigned.UInt64.to_int64 offs)
let get_bigstring t { offs; len } : Bigstringaf.t =
let p = memory t ~offs in
bigarray_of_ptr array1
(Unsigned.UInt64.to_int len)
Bigarray.Char
(coerce (ptr uint8_t) (ptr char) p)
let get_string t { offs; len } =
let p = memory t ~offs in
Ctypes.string_from_ptr
(coerce (ptr uint8_t) (ptr char) p)
~length:(Unsigned.UInt64.to_int len)
let set_bigstring t { offs; len } bs =
let length = min (Unsigned.UInt64.to_int @@ len) (Bigstringaf.length bs) in
let p = coerce (ptr uint8_t) (ptr char) @@ memory t ~offs in
for i = 0 to length - 1 do
p +@ i <-@ Bigstringaf.unsafe_get bs i
done
let set_string t { offs; len } s =
let length = min (Unsigned.UInt64.to_int @@ len) (String.length s) in
let p = coerce (ptr uint8_t) (ptr char) @@ memory t ~offs in
for i = 0 to length - 1 do
p +@ i <-@ String.unsafe_get s i
done
end
let return_string t (outputs : Types.Val_array.t) index s =
let mem = alloc t (String.length s) in
Memory_block.set_string t mem s;
Types.Val_array.(
outputs.$[index] <- Types.Val.of_i64 (Unsigned.UInt64.to_int64 mem.offs))
let return_bigstring t (outputs : Types.Val_array.t) index s =
let mem = alloc t (Bigstringaf.length s) in
Memory_block.set_bigstring t mem s;
Types.Val_array.(
outputs.$[index] <- Types.Val.of_i64 (Unsigned.UInt64.to_int64 mem.offs))
let input_string t inputs index =
let inp = Types.Val_array.(inputs.$[index]) in
let mem = Memory_block.of_val_exn t inp in
Memory_block.get_string t mem
let input_bigstring t inputs index =
let inp = Types.Val_array.(inputs.$[index]) in
let mem = Memory_block.of_val_exn t inp in
Memory_block.get_bigstring t mem

View File

@@ -2,7 +2,7 @@
(name extism)
(public_name extism)
(inline_tests
(deps test/code.wasm))
(deps test/code.wasm test/code-functions.wasm))
(libraries ctypes.foreign bigstringaf extism-manifest)
(preprocess
(pps ppx_yojson_conv ppx_inline_test)))

View File

@@ -8,3 +8,4 @@ let () =
| _ -> None)
let unwrap = function Ok x -> x | Error t -> raise (Error t)
let throw e = raise (Error e)

View File

@@ -2,6 +2,9 @@ module Manifest = Extism_manifest
module Error = Error
module Context = Context
module Plugin = Plugin
module Function = Function
module Current_plugin = Current_plugin
include Types
let with_context = Plugin.with_context
let extism_version = Bindings.extism_version

View File

@@ -1,36 +1,201 @@
(** Extism bindings for OCaml *)
(** Returns the libextism version, not the version of the OCaml library *)
val extism_version : unit -> string
(** Returns the libextism version, not the version of the OCaml library *)
module Manifest = Extism_manifest
module Error : sig
type t = [`Msg of string]
type t = [ `Msg of string ]
exception Error of t
val unwrap: ('a, t) result -> 'a
val unwrap : ('a, t) result -> 'a
val throw : t -> 'a
end
(** [Val_type] enumerates every possible argument/result type *)
module Val_type : sig
type t =
| I32
| I64
| F32
| F64
| V128
| FuncRef
| ExternRef (** Value type *)
val of_int : int -> t
val to_int : t -> int
end
(** [Val] represents low-level WebAssembly values *)
module Val : sig
type t
(** Val *)
val ty : t -> Val_type.t
(** [ty v] returns the [Val_type.t] for the value [v] *)
val of_i32 : int32 -> t
(** Create an i32 [Val] *)
val of_i64 : int64 -> t
(** Create an i64 [Val] *)
val of_f32 : float -> t
(** Create an f32 [Val] *)
val of_f64 : float -> t
(** Create an f64 [Val] *)
val to_i32 : t -> int32 option
(** Get an int32 from [Val] if the type matches *)
val to_i64 : t -> int64 option
(** Get an int64 from [Val] if the type matches *)
val to_f32 : t -> float option
(** Get a f32 from [Val] if the type matches *)
val to_f64 : t -> float option
(** Get an f64 from [Val] if the type matches *)
val to_i32_exn : t -> int32
(** Same as [to_i32] but raises an exception if the types don't match*)
val to_i64_exn : t -> int64
(** Same as [to_i64] but raises an exception if the types don't match*)
val to_f32_exn : t -> float
(** Same as [to_f32] but raises an exception if the types don't match*)
val to_f64_exn : t -> float
(** Same as [to_f64] but raises an exception if the types don't match*)
end
(** [Val_array] is used for input/output parameters for host functions *)
module Val_array : sig
type t = Val.t Ctypes.CArray.t
(** [Val_array] type *)
val get : t -> int -> Val.t
(** Get an index *)
val set : t -> int -> Val.t -> unit
(** Set an index *)
val length : t -> int
(** Get the number of items in a [Val_array]*)
val ( .$[] ) : t -> int -> Val.t
(** Syntax for [get] *)
val ( .$[]<- ) : t -> int -> Val.t -> unit
(** Syntax for [set] *)
end
(** [Current_plugin] represents the plugin that is currently running, it should
it should only be used from a host function *)
module Current_plugin : sig
type t
(** Opaque type, wraps [ExtismCurrentPlugin] *)
type memory_block = { offs : Unsigned.UInt64.t; len : Unsigned.UInt64.t }
(** Represents a block of guest memory *)
val memory : ?offs:Unsigned.UInt64.t -> t -> Unsigned.uint8 Ctypes.ptr
(** Get pointer to entire plugin memory *)
val find : t -> Unsigned.UInt64.t -> memory_block option
(** Find memory block *)
val alloc : t -> int -> memory_block
(** Allocate a new block of memory *)
val free : t -> memory_block -> unit
(** Free an allocated block of memory *)
val return_string : t -> Val_array.t -> int -> string -> unit
val return_bigstring : t -> Val_array.t -> int -> Bigstringaf.t -> unit
val input_string : t -> Val_array.t -> int -> string
val input_bigstring : t -> Val_array.t -> int -> Bigstringaf.t
(** Some helpter functions for reading/writing memory *)
module Memory_block : sig
val to_val : memory_block -> Val.t
(** Convert memory block to [Val] *)
val of_val : t -> Val.t -> memory_block option
(** Convert [Val] to memory block *)
val of_val_exn : t -> Val.t -> memory_block
(** Convert [Val] to memory block, raises [Invalid_argument] if the value is not a pointer
to a valid memory block *)
val get_string : t -> memory_block -> string
(** Get a string from memory stored at the provided offset *)
val get_bigstring : t -> memory_block -> Bigstringaf.t
(** Get a bigstring from memory stored at the provided offset *)
val set_string : t -> memory_block -> string -> unit
(** Store a string into memory at the provided offset *)
val set_bigstring : t -> memory_block -> Bigstringaf.t -> unit
(** Store a bigstring into memory at the provided offset *)
end
end
(** [Function] is used to create new a new function, which can be called
from a WebAssembly plugin *)
module Function : sig
type t
(** Function type *)
val create :
string ->
?namespace:string ->
params:Val_type.t list ->
results:Val_type.t list ->
user_data:'a ->
(Current_plugin.t -> Val_array.t -> Val_array.t -> 'a -> unit) ->
t
(** Create a new function, [Function.v name ~params ~results ~user_data f] creates
a new [Function] with the given [name], [params] specifies the argument types,
[results] specifies the return types, [user_data] is used to pass arbitrary
OCaml values into the function and [f] is the OCaml function that will be
called.
*)
val with_namespace : t -> string -> t
(** Update a function's namespace *)
val free : t -> unit
(** Free a function *)
val free_all : t list -> unit
(** Free a list of functions *)
end
(** [Context] is used to group plugins *)
module Context : sig
(** Context type *)
type t
(** Context type *)
(** Create a new context *)
val create : unit -> t
(** Create a new context *)
val free : t -> unit
(** Free a context. All plugins will be removed and the value should not be
accessed after this call *)
val free : t -> unit
(** Reset a context. All plugins will be removed *)
val reset : t -> unit
(** Reset a context. All plugins will be removed *)
end
(** Execute a function with a fresh context and free it after *)
val with_context : (Context.t -> 'a) -> 'a
(** Execute a function with a fresh context and free it after *)
val set_log_file :
?level:[ `Error | `Warn | `Info | `Debug | `Trace ] -> string -> bool
@@ -39,40 +204,53 @@ val set_log_file :
module Plugin : sig
type t
(** Make a new plugin from raw WebAssembly or JSON encoded manifest *)
val make :
val create :
?config:Manifest.config ->
?wasi:bool ->
?functions:Function.t list ->
Context.t ->
string ->
(t, Error.t) result
(** Make a new plugin from raw WebAssembly or JSON encoded manifest *)
(** Make a new plugin from a [Manifest] *)
val of_manifest :
?wasi:bool -> Context.t -> Manifest.t -> (t, Error.t) result
?wasi:bool ->
?functions:Function.t list ->
Context.t ->
Manifest.t ->
(t, Error.t) result
(** Make a new plugin from a [Manifest] *)
(** Update a plugin from raw WebAssembly or JSON encoded manifest *)
val update :
t ->
?config:(string * string option) list ->
?wasi:bool ->
?functions:Function.t list ->
string ->
(unit, [ `Msg of string ]) result
(** Update a plugin from raw WebAssembly or JSON encoded manifest *)
val update_manifest : t -> ?wasi:bool -> Manifest.t -> (unit, Error.t) result
(** Update a plugin from a [Manifest] *)
val update_manifest :
t -> ?wasi:bool -> Manifest.t -> (unit, Error.t) result
(** Call a function, uses [Bigstringaf.t] for input/output *)
val call_bigstring :
t -> name:string -> Bigstringaf.t -> (Bigstringaf.t, Error.t) result
(** Call a function, uses [Bigstringaf.t] for input/output *)
(** Call a function, uses [string] for input/output *)
val call : t -> name:string -> string -> (string, Error.t) result
(** Call a function, uses [string] for input/output *)
(** Drop a plugin *)
val free : t -> unit
(** Drop a plugin *)
(** Check if a function is exported by a plugin *)
val function_exists : t -> string -> bool
(** Check if a function is exported by a plugin *)
module Cancel_handle: sig
type t
val cancel: t -> bool
end
val cancel_handle: t -> Cancel_handle.t
end

47
ocaml/lib/function.ml Normal file
View File

@@ -0,0 +1,47 @@
open Ctypes
type t = {
mutable pointer : unit ptr;
mutable user_data : unit ptr;
name : string;
}
let free t =
let () =
if not (is_null t.user_data) then
let () = Root.release t.user_data in
t.user_data <- null
in
if not (is_null t.pointer) then
let () = Bindings.extism_function_free t.pointer in
t.pointer <- null
let free_all l = List.iter free l
let create name ?namespace ~params ~results ~user_data f =
let inputs = CArray.of_list Bindings.Extism_val_type.t params in
let n_inputs = Unsigned.UInt64.of_int (CArray.length inputs) in
let outputs = CArray.of_list Bindings.Extism_val_type.t results in
let n_outputs = Unsigned.UInt64.of_int (CArray.length outputs) in
let free' = Some Root.release in
let user_data = Root.create user_data in
let f current inputs n_inputs outputs n_outputs user_data =
let user_data = Root.get user_data in
let inputs = CArray.from_ptr inputs (Unsigned.UInt64.to_int n_inputs) in
let outputs = CArray.from_ptr outputs (Unsigned.UInt64.to_int n_outputs) in
f current inputs outputs user_data
in
let pointer =
Bindings.extism_function_new name (CArray.start inputs) n_inputs
(CArray.start outputs) n_outputs f user_data free'
in
let () =
Option.iter (Bindings.extism_function_set_namespace pointer) namespace
in
let t = { pointer; user_data; name } in
Gc.finalise free t;
t
let with_namespace f ns =
Bindings.extism_function_set_namespace f.pointer ns;
f

View File

@@ -1,6 +1,6 @@
module Manifest = Extism_manifest
type t = { id : int32; ctx : Context.t }
type t = { id : int32; ctx : Context.t; mutable functions : Function.t list }
let with_context f =
let ctx = Context.create () in
@@ -26,10 +26,15 @@ let free t =
if not (Ctypes.is_null t.ctx.pointer) then
Bindings.extism_plugin_free t.ctx.pointer t.id
let make ?config ?(wasi = false) ctx wasm =
let create ?config ?(wasi = false) ?(functions = []) ctx wasm =
let func_ptrs = List.map (fun x -> x.Function.pointer) functions in
let arr = Ctypes.CArray.of_list Ctypes.(ptr void) func_ptrs in
let n_funcs = Ctypes.CArray.length arr in
let id =
Bindings.extism_plugin_new ctx.Context.pointer wasm
(Unsigned.UInt64.of_int (String.length wasm))
(Ctypes.CArray.start arr)
(Unsigned.UInt64.of_int n_funcs)
wasi
in
if id < 0l then
@@ -37,28 +42,33 @@ let make ?config ?(wasi = false) ctx wasm =
| None -> Error (`Msg "extism_plugin_call failed")
| Some msg -> Error (`Msg msg)
else
let t = { id; ctx } in
let t = { id; ctx; functions } in
if not (set_config t config) then Error (`Msg "call to set_config failed")
else
let () = Gc.finalise free t in
Ok t
let of_manifest ?wasi ctx manifest =
let data = Manifest.json manifest in
make ctx ?wasi data
let of_manifest ?wasi ?functions ctx manifest =
let data = Manifest.to_json manifest in
create ctx ?wasi ?functions data
let%test "free plugin" =
let manifest = Manifest.v [ Manifest.file "test/code.wasm" ] in
let manifest = Manifest.(create [ Wasm.file "test/code.wasm" ]) in
with_context (fun ctx ->
let plugin = of_manifest ctx manifest |> Result.get_ok in
let plugin = of_manifest ctx manifest |> Error.unwrap in
free plugin;
true)
let update plugin ?config ?(wasi = false) wasm =
let { id; ctx } = plugin in
let update plugin ?config ?(wasi = false) ?(functions = []) wasm =
let { id; ctx; _ } = plugin in
let func_ptrs = List.map (fun x -> x.Function.pointer) functions in
let arr = Ctypes.CArray.of_list Ctypes.(ptr void) func_ptrs in
let n_funcs = Ctypes.CArray.length arr in
let ok =
Bindings.extism_plugin_update ctx.pointer id wasm
(Unsigned.UInt64.of_int (String.length wasm))
(Ctypes.CArray.start arr)
(Unsigned.UInt64.of_int n_funcs)
wasi
in
if not ok then
@@ -70,18 +80,18 @@ let update plugin ?config ?(wasi = false) wasm =
else Ok ()
let update_manifest plugin ?wasi manifest =
let data = Manifest.json manifest in
let data = Manifest.to_json manifest in
update plugin ?wasi data
let%test "update plugin manifest and config" =
let manifest = Manifest.v [ Manifest.file "test/code.wasm" ] in
let manifest = Manifest.(create [ Wasm.file "test/code.wasm" ]) in
with_context (fun ctx ->
let config = [ ("a", Some "1") ] in
let plugin = of_manifest ctx manifest |> Result.get_ok in
let plugin = of_manifest ctx manifest |> Error.unwrap in
let manifest = Manifest.with_config manifest config in
update_manifest plugin manifest |> Result.is_ok)
let call' f { id; ctx } ~name input len =
let call' f { id; ctx; _ } ~name input len =
let rc = f ctx.pointer id name input len in
if rc <> 0l then
match Bindings.extism_error ctx.pointer id with
@@ -103,12 +113,12 @@ let call_bigstring (t : t) ~name input =
call' Bindings.extism_plugin_call t ~name ptr len
let%test "call_bigstring" =
let manifest = Manifest.v [ Manifest.file "test/code.wasm" ] in
let manifest = Manifest.(create [ Wasm.file "test/code.wasm" ]) in
with_context (fun ctx ->
let plugin = of_manifest ctx manifest |> Result.get_ok in
let plugin = of_manifest ctx manifest |> Error.unwrap in
call_bigstring plugin ~name:"count_vowels"
(Bigstringaf.of_string ~off:0 ~len:14 "this is a test")
|> Result.get_ok |> Bigstringaf.to_string = "{\"count\": 4}")
|> Error.unwrap |> Bigstringaf.to_string = "{\"count\": 4}")
let call (t : t) ~name input =
let len = String.length input in
@@ -116,18 +126,49 @@ let call (t : t) ~name input =
|> Result.map Bigstringaf.to_string
let%test "call" =
let manifest = Manifest.v [ Manifest.file "test/code.wasm" ] in
let manifest = Manifest.(create [ Wasm.file "test/code.wasm" ]) in
with_context (fun ctx ->
let plugin = of_manifest ctx manifest |> Result.get_ok in
let plugin = of_manifest ctx manifest |> Error.unwrap in
call plugin ~name:"count_vowels" "this is a test"
|> Result.get_ok = "{\"count\": 4}")
|> Error.unwrap = "{\"count\": 4}")
let function_exists { id; ctx } name =
let%test "call_functions" =
let open Types.Val_type in
let hello_world =
Function.create "hello_world" ~params:[ I64 ] ~results:[ I64 ]
~user_data:"Hello again!"
@@ fun plugin params results user_data ->
let open Types.Val_array in
let s = Current_plugin.input_string plugin params 0 in
let () = print_endline "Hello from OCaml!" in
let () = print_endline user_data in
let () = print_endline s in
results.$[0] <- params.$[0]
in
let functions = [ hello_world ] in
let manifest = Manifest.(create [ Wasm.file "test/code-functions.wasm" ]) in
with_context (fun ctx ->
let plugin =
of_manifest ctx manifest ~functions ~wasi:true |> Error.unwrap
in
call plugin ~name:"count_vowels" "this is a test"
|> Error.unwrap = "{\"count\": 4}")
let function_exists { id; ctx; _ } name =
Bindings.extism_plugin_function_exists ctx.pointer id name
let%test "function exists" =
let manifest = Manifest.v [ Manifest.file "test/code.wasm" ] in
let manifest = Manifest.(create [ Wasm.file "test/code.wasm" ]) in
with_context (fun ctx ->
let plugin = of_manifest ctx manifest |> Result.get_ok in
let plugin = of_manifest ctx manifest |> Error.unwrap in
function_exists plugin "count_vowels"
&& not (function_exists plugin "function_does_not_exist"))
module Cancel_handle = struct
type t = { inner : unit Ctypes.ptr }
let cancel { inner } = Bindings.extism_plugin_cancel inner
end
let cancel_handle { id; ctx; _ } =
Cancel_handle.{ inner = Bindings.extism_plugin_cancel_handle ctx.pointer id }

92
ocaml/lib/types.ml Normal file
View File

@@ -0,0 +1,92 @@
open Ctypes
module Val_type = Bindings.Extism_val_type
module Val = struct
type t = (Bindings.Extism_val.t, [ `Struct ]) Ctypes.structured
let t = Bindings.Extism_val.t
let of_i32 (x : int32) : t =
let u = Ctypes.make Bindings.Extism_val_union.t in
u @. Bindings.Extism_val_union.i32 <-@ x;
let t = Ctypes.make Bindings.Extism_val.t in
t @. Bindings.Extism_val.ty <-@ Val_type.I32;
t @. Bindings.Extism_val.v <-@ u;
t
let of_i64 (x : int64) : t =
let u = Ctypes.make Bindings.Extism_val_union.t in
u @. Bindings.Extism_val_union.i64 <-@ x;
let t = Ctypes.make Bindings.Extism_val.t in
t @. Bindings.Extism_val.ty <-@ Val_type.I64;
t @. Bindings.Extism_val.v <-@ u;
t
let of_f32 (x : float) : t =
let u = Ctypes.make Bindings.Extism_val_union.t in
u @. Bindings.Extism_val_union.f32 <-@ x;
let t = Ctypes.make Bindings.Extism_val.t in
t @. Bindings.Extism_val.ty <-@ Val_type.F32;
t @. Bindings.Extism_val.v <-@ u;
t
let of_f64 (x : float) : t =
let u = Ctypes.make Bindings.Extism_val_union.t in
u @. Bindings.Extism_val_union.f64 <-@ x;
let t = Ctypes.make Bindings.Extism_val.t in
t @. Bindings.Extism_val.ty <-@ Val_type.F64;
t @. Bindings.Extism_val.v <-@ u;
t
let to_i32 t : int32 option =
let ty = t @. Bindings.Extism_val.ty in
let v = t @. Bindings.Extism_val.v in
match !@ty with
| Bindings.Extism_val_type.I32 ->
Some !@(!@v @. Bindings.Extism_val_union.i32)
| _ -> None
let to_i64 t : int64 option =
let ty = t @. Bindings.Extism_val.ty in
let v = t @. Bindings.Extism_val.v in
match !@ty with
| Bindings.Extism_val_type.I64 ->
Some !@(!@v @. Bindings.Extism_val_union.i64)
| _ -> None
let to_f32 t : float option =
let ty = t @. Bindings.Extism_val.ty in
let v = t @. Bindings.Extism_val.v in
match !@ty with
| Bindings.Extism_val_type.F32 ->
Some !@(!@v @. Bindings.Extism_val_union.f32)
| _ -> None
let to_f64 t : float option =
let ty = t @. Bindings.Extism_val.ty in
let v = t @. Bindings.Extism_val.v in
match !@ty with
| Bindings.Extism_val_type.F64 ->
Some !@(!@v @. Bindings.Extism_val_union.f64)
| _ -> None
let ty t = !@(t @. Bindings.Extism_val.ty)
let make_exn f x =
match f x with Some x -> x | None -> Error.throw (`Msg "invalid type")
let to_i32_exn = make_exn to_i32
let to_i64_exn = make_exn to_i64
let to_f32_exn = make_exn to_f32
let to_f64_exn = make_exn to_f64
end
module Val_array = struct
type t = Val.t Ctypes.CArray.t
let get t i = Ctypes.CArray.get t i
let set t i x = Ctypes.CArray.set t i x
let length t = Ctypes.CArray.length t
let ( .$[] ) = get
let ( .$[]<- ) = set
end

View File

@@ -1,6 +1,7 @@
(library
(name extism_manifest)
(public_name extism-manifest)
(inline_tests)
(libraries base64)
(preprocess
(pps ppx_yojson_conv)))
(pps ppx_yojson_conv ppx_inline_test)))

View File

@@ -1,22 +1,9 @@
type memory = { max_pages : int option [@yojson.option] } [@@deriving yojson]
type wasm_file = {
path : string;
name : string option; [@yojson.option]
hash : string option; [@yojson.option]
}
[@@deriving yojson]
type base64 = string
let yojson_of_base64 x = `String (Base64.encode_exn x)
let base64_of_yojson j = Yojson.Safe.Util.to_string j
type wasm_data = {
data : base64;
name : string option; [@yojson.option]
hash : string option; [@yojson.option]
}
type memory_options = { max_pages : int option [@yojson.option] }
[@@deriving yojson]
type dict = (string * string) list
@@ -43,30 +30,51 @@ let yojson_of_config c =
(fun (k, v) -> (k, match v with None -> `Null | Some v -> `String v))
c)
type wasm_url = {
url : string;
headers : dict option; [@yojson.option]
name : string option; [@yojson.option]
meth : string option; [@yojson.option] [@key "method"]
hash : string option; [@yojson.option]
}
[@@deriving yojson]
module Wasm = struct
type file = {
path : string;
name : string option; [@yojson.option]
hash : string option; [@yojson.option]
}
[@@deriving yojson]
type wasm = File of wasm_file | Data of wasm_data | Url of wasm_url
type data = {
data : base64;
name : string option; [@yojson.option]
hash : string option; [@yojson.option]
}
[@@deriving yojson]
let yojson_of_wasm = function
| File f -> yojson_of_wasm_file f
| Data d -> yojson_of_wasm_data d
| Url u -> yojson_of_wasm_url u
type url = {
url : string;
headers : dict option; [@yojson.option]
name : string option; [@yojson.option]
meth : string option; [@yojson.option] [@key "method"]
hash : string option; [@yojson.option]
}
[@@deriving yojson]
let wasm_of_yojson x =
try File (wasm_file_of_yojson x)
with _ -> (
try Data (wasm_data_of_yojson x) with _ -> Url (wasm_url_of_yojson x))
type t = File of file | Data of data | Url of url
let yojson_of_t = function
| File f -> yojson_of_file f
| Data d -> yojson_of_data d
| Url u -> yojson_of_url u
let t_of_yojson x =
try File (file_of_yojson x)
with _ -> ( try Data (data_of_yojson x) with _ -> Url (url_of_yojson x))
let file ?name ?hash path = File { path; name; hash }
let data ?name ?hash data = Data { data; name; hash }
let url ?headers ?name ?meth ?hash url =
Url { headers; name; meth; hash; url }
end
type t = {
wasm : wasm list;
memory : memory option; [@yojson.option]
wasm : Wasm.t list;
memory : memory_options option; [@yojson.option]
config : config option; [@yojson.option]
allowed_hosts : string list option; [@yojson.option]
allowed_paths : dict option; [@yojson.option]
@@ -74,12 +82,30 @@ type t = {
}
[@@deriving yojson]
let file ?name ?hash path = File { path; name; hash }
let data ?name ?hash data = Data { data; name; hash }
let url ?headers ?name ?meth ?hash url = Url { headers; name; meth; hash; url }
let v ?config ?memory ?allowed_hosts ?allowed_paths ?timeout_ms wasm =
let create ?config ?memory ?allowed_hosts ?allowed_paths ?timeout_ms wasm =
{ config; wasm; memory; allowed_hosts; allowed_paths; timeout_ms }
let json t = yojson_of_t t |> Yojson.Safe.to_string
let to_json t = yojson_of_t t |> Yojson.Safe.to_string
let of_json s =
let j = Yojson.Safe.from_string s in
t_of_yojson j
let of_file filename =
let j = Yojson.Safe.from_file filename in
t_of_yojson j
let with_config t config = { t with config = Some config }
let%test "rountrip" =
let config = [ ("a", Some "b"); ("b", Some "c") ] in
let memory = { max_pages = Some 5 } in
let t =
create ~config ~memory ~allowed_hosts:[ "example.com" ]
~allowed_paths:[ ("a", "b") ]
~timeout_ms:1000 []
in
let a = to_json t in
let b = of_json a in
let c = to_json b in
String.equal a c

View File

@@ -1,75 +1,87 @@
type memory_options = { max_pages : int option } [@@deriving yojson]
(** Memory options *)
type memory = { max_pages : int option } [@@deriving yojson]
(** Key/value dictionary *)
type dict = (string * string) list [@@deriving yojson]
(** Key/value dictionary *)
(** Key/value dictionary with optional values *)
type config = (string * string option) list [@@deriving yojson]
(** Key/value dictionary with optional values *)
(** WebAssembly file *)
type wasm_file = {
path : string;
name : string option; [@yojson.option]
hash : string option; [@yojson.option]
} [@@deriving yojson]
module Wasm : sig
type file = {
path : string;
name : string option; [@yojson.option]
hash : string option; [@yojson.option]
}
[@@deriving yojson]
(** WebAssembly file *)
(** WebAssembly module data *)
type wasm_data = {
data : string;
name : string option; [@yojson.option]
hash : string option; [@yojson.option]
} [@@deriving yojson]
type data = {
data : string;
name : string option; [@yojson.option]
hash : string option; [@yojson.option]
}
[@@deriving yojson]
(** WebAssembly module data *)
(** WebAssembly URL *)
type wasm_url = {
url : string;
headers : dict option; [@yojson.option]
name : string option; [@yojson.option]
meth : string option; [@yojson.option] [@key "method"]
hash : string option; [@yojson.option]
} [@@deriving yojson]
type url = {
url : string;
headers : dict option; [@yojson.option]
name : string option; [@yojson.option]
meth : string option; [@yojson.option] [@key "method"]
hash : string option; [@yojson.option]
}
[@@deriving yojson]
(** WebAssembly URL *)
(** WebAssembly from a file, module data or URL *)
type wasm = File of wasm_file | Data of wasm_data | Url of wasm_url [@@deriving yojson]
(** WebAssembly from a file, module data or URL *)
type t = File of file | Data of data | Url of url [@@deriving yojson]
val file : ?name:string -> ?hash:string -> string -> t
(** Create [wasm] from filename *)
val data : ?name:string -> ?hash:string -> string -> t
(** Create [wasm] from WebAssembly module data *)
val url :
?headers:(string * string) list ->
?name:string ->
?meth:string ->
?hash:string ->
string ->
t
(** Create [wasm] from URL *)
end
(** Manifest type *)
type t = {
wasm : wasm list;
memory : memory option;
wasm : Wasm.t list;
memory : memory_options option;
config : config option;
allowed_hosts : string list option;
allowed_paths : dict option;
timeout_ms : int option;
} [@@deriving yojson]
}
[@@deriving yojson]
(** Manifest type *)
(** Create [wasm] from filename *)
val file : ?name:string -> ?hash:string -> string -> wasm
(** Create [wasm] from WebAssembly module data *)
val data : ?name:string -> ?hash:string -> string -> wasm
(** Create [wasm] from URL *)
val url :
?headers:(string * string) list ->
?name:string ->
?meth:string ->
?hash:string ->
string ->
wasm
(** Create new manifest *)
val v :
val create :
?config:config ->
?memory:memory ->
?memory:memory_options ->
?allowed_hosts:string list ->
?allowed_paths:dict ->
?timeout_ms:int ->
wasm list ->
Wasm.t list ->
t
(** Create new manifest *)
val to_json : t -> string
(** Convert manifest to JSON *)
val json : t -> string
(** Updates a manifest config *)
val of_json : string -> t
(** Read manifest from JSON string *)
val of_file : string -> t
(** Read manifest from JSON file *)
val with_config : t -> config -> t
(** Updates a manifest config *)

1
php/example/code.wasm Symbolic link
View File

@@ -0,0 +1 @@
../../wasm/code.wasm

View File

@@ -3,16 +3,16 @@
require_once __DIR__ . '/vendor/autoload.php';
$ctx = new \Extism\Context();
$wasm = file_get_contents("../../wasm/code.wasm");
$wasm = file_get_contents("code.wasm");
$plugin = new \Extism\Plugin($ctx, $wasm);
$output = $plugin->call("count_vowels", "this is an example");
$json = json_decode(pack('C*', ...$output));
echo "Vowels counted = " . $json->{'count'} . PHP_EOL;
$wasm = file_get_contents("../../wasm/code.wasm");
$wasm = file_get_contents("code.wasm");
$ok = $plugin->update($wasm);
if ($ok) {
$id = $plugin->getId();
echo "updated plugin: $id";
}
}

View File

@@ -4,6 +4,23 @@ namespace Extism;
require_once "ExtismLib.php";
class CancelHandle
{
private $lib;
private $handle;
function __construct($lib, $handle)
{
$this->lib = $lib;
$this->handle = $handle;
}
public function cancel()
{
return $this->lib->extism_plugin_cancel($this->handle);
}
}
class Plugin
{
private $lib;
@@ -29,7 +46,7 @@ class Plugin
$data = string_to_bytes($data);
}
$id = $this->lib->extism_plugin_new($ctx->pointer, $data, count($data), (int)$wasi);
$id = $this->lib->extism_plugin_new($ctx->pointer, $data, count($data), null, 0, (int)$wasi);
if ($id < 0) {
$err = $this->lib->extism_error($ctx->pointer, -1);
throw new \Exception("Extism: unable to load plugin: " . $err);
@@ -58,6 +75,11 @@ class Plugin
return $this->lib->extism_plugin_function_exists($this->context->pointer, $this->id, $name);
}
public function cancelHandle()
{
return new \CancelHandle($this->lib, $this->lib->extism_plugin_cancel_handle($this->context->pointer, $this->id));
}
public function call($name, $input = null)
{
if (gettype($input) == "string") {
@@ -96,7 +118,7 @@ class Plugin
$data = string_to_bytes($data);
}
$ok = $this->lib->extism_plugin_update($this->context->pointer, $this->id, $data, count($data), (int)$wasi);
$ok = $this->lib->extism_plugin_update($this->context->pointer, $this->id, $data, count($data), null, 0, (int)$wasi);
if (!$ok) {
$err = $this->lib->extism_error($this->context->pointer, -1);
throw new \Exception("Extism: unable to update plugin: " . $err);

Some files were not shown because too many files have changed in this diff Show More