@learncard/create-http-bridge 1.1.247 → 1.1.249

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @learncard/create-http-bridge
2
2
 
3
+ ## 1.1.249
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1444](https://github.com/learningeconomy/LearnCard/pull/1444) [`5489866631ce3b19709a3685c56ff68e2d817af4`](https://github.com/learningeconomy/LearnCard/commit/5489866631ce3b19709a3685c56ff68e2d817af4) Thanks [@TaylorBeeston](https://github.com/TaylorBeeston)! - [LC-1958] Fix W3C EdDSA Data Integrity interoperability and ship rebuilt native and WASM DIDKit artifacts.
8
+
9
+ - Updated dependencies [[`5489866631ce3b19709a3685c56ff68e2d817af4`](https://github.com/learningeconomy/LearnCard/commit/5489866631ce3b19709a3685c56ff68e2d817af4)]:
10
+ - @learncard/types@5.18.1
11
+ - @learncard/init@2.4.10
12
+
13
+ ## 1.1.248
14
+
15
+ ### Patch Changes
16
+
17
+ - Updated dependencies [[`660778e73161c9c185e1f6592a5ac90dd9309a0a`](https://github.com/learningeconomy/LearnCard/commit/660778e73161c9c185e1f6592a5ac90dd9309a0a), [`acf13250d6ffd39798b44f0c5b9331b3769ebd24`](https://github.com/learningeconomy/LearnCard/commit/acf13250d6ffd39798b44f0c5b9331b3769ebd24), [`f504c57823d2a978f9cec569a00c9478ea8b3158`](https://github.com/learningeconomy/LearnCard/commit/f504c57823d2a978f9cec569a00c9478ea8b3158)]:
18
+ - @learncard/types@5.18.0
19
+ - @learncard/init@2.4.9
20
+
3
21
  ## 1.1.247
4
22
 
5
23
  ### Patch Changes
package/README.md CHANGED
@@ -20,6 +20,64 @@ https://docs.learncard.com
20
20
  - Add a .env file exporting a wallet seed (e.g. `WALLET_SEED=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`)
21
21
  - Run `bun run serverless-deploy`
22
22
 
23
+ ## Local VC-API conformance testing
24
+
25
+ The bridge uses a source-controlled DIDKit WASM copied from the current plugin build. Every
26
+ build and start command verifies the canonical plugin artifact's SHA-256 before refreshing the
27
+ bridge copy, so local, CLI, and serverless execution cannot silently use different binaries.
28
+
29
+ ```bash
30
+ cd lib/didkit/lib/web
31
+ wasm-pack build --target=web && cd pkg && wasm-opt -Oz -o tmp.wasm didkit_wasm_bg.wasm && mv tmp.wasm didkit_wasm_bg.wasm && cp didkit* ../../../../../packages/plugins/didkit/src/didkit/pkg/ && cd ..
32
+ bun --cwd ../../../../packages/plugins/didkit run build
33
+ ```
34
+
35
+ Stop and restart any running bridge after rebuilding; it loads the DIDKit WASM during
36
+ initialization.
37
+ When intentionally rebuilding DIDKit, review the new binary and update
38
+ `EXPECTED_DIDKIT_SHA256` in `scripts/sync-didkit.ts`. To test an unreviewed local artifact
39
+ without changing that pin, set `LOCAL_DIDKIT_PATH` as described below.
40
+
41
+ Start the LearnCard HTTP bridge in the first terminal:
42
+
43
+ ```bash
44
+ cd packages/learn-card-bridge-http
45
+ WALLET_SEED=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
46
+ bun run start:local
47
+ ```
48
+
49
+ Set `LOCAL_DIDKIT_PATH=/absolute/path/to/didkit_wasm_bg.wasm` only to override the
50
+ package-provided WASM. The test seed must match the issuer DID in `w3c-localConfig.cjs`.
51
+
52
+ Run the current W3C EdDSA Data Integrity suite in a second terminal:
53
+
54
+ ```bash
55
+ git clone --depth 1 https://github.com/w3c/vc-di-eddsa-test-suite.git
56
+ cd vc-di-eddsa-test-suite
57
+ npm install
58
+ cp "$LEARN_CARD_REPO/packages/learn-card-bridge-http/w3c-localConfig.cjs" localConfig.cjs
59
+ npx mocha tests/05-di-rdfc-create.js --timeout 30000
60
+ npx mocha tests/15-di-rdfc-verify.js --timeout 30000
61
+ ```
62
+
63
+ Set `LEARN_CARD_REPO` to the absolute path of this monorepo. Set `BASE_URL` when the
64
+ bridge is not listening at `http://127.0.0.1:3100`.
65
+
66
+ ## URL issuer verification policy
67
+
68
+ When a credential names an HTTPS issuer but its proof uses a DID verification method, a
69
+ successful `proof` check establishes signature integrity only. DIDKit cannot establish that the
70
+ named URL issuer authorized that DID key because there is no issuer DID document to supply the
71
+ assertion-method relationship. The raw verification result therefore includes this
72
+ security-relevant warning:
73
+
74
+ ```text
75
+ Issuer authorization was not checked because the credential issuer is not a DID
76
+ ```
77
+
78
+ Consumers must surface or enforce this warning according to their trust policy; they must not
79
+ interpret `checks: ["proof"]` by itself as issuer authorization.
80
+
23
81
  ## Contributing
24
82
 
25
83
  Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
package/dist/index.js CHANGED
@@ -416,14 +416,16 @@ const App = ({ name = "LearnCardHTTPBridge" }) => {
416
416
  };
417
417
 
418
418
  var name = "@learncard/create-http-bridge";
419
- var version = "1.1.247";
419
+ var version = "1.1.249";
420
420
  var description = "Instantly create and deploy a Learn Card Bridge HTTP API via AWS Lambda!";
421
421
  var main = "dist/index.js";
422
422
  var bin = "dist/index.js";
423
423
  var scripts = {
424
- "serverless-deploy": "shx cp ../learn-card-core/src/didkit/pkg/didkit_wasm_bg.wasm src/didkit_wasm_bg.wasm && serverless deploy",
425
- start: "rollup -c && node dist/index.js",
426
- build: "rollup -c"
424
+ "sync-didkit": "bun scripts/sync-didkit.ts",
425
+ "serverless-deploy": "bun run sync-didkit && serverless deploy",
426
+ start: "bun run sync-didkit && rollup -c && node dist/index.js",
427
+ "start:local": "bun run sync-didkit && bun src/server.ts",
428
+ build: "bun run sync-didkit && rollup -c"
427
429
  };
428
430
  var author = "Learning Economy Foundation (www.learningeconomy.io)";
429
431
  var license = "MIT";
@@ -451,7 +453,8 @@ var dependencies = {
451
453
  "serverless-http": "^3.0.1",
452
454
  "serverless-plugin-warmup": "^8.1.0",
453
455
  "simple-git": "^3.36.0",
454
- "use-immer": "^0.7.0"
456
+ "use-immer": "^0.7.0",
457
+ zod: "4.1.13"
455
458
  };
456
459
  var devDependencies = {
457
460
  "@types/aws-lambda": "^8.10.106",
@@ -464,7 +467,6 @@ var devDependencies = {
464
467
  "@types/react": "^17.0.2",
465
468
  nodemon: "^2.0.16",
466
469
  "serverless-plugin-typescript": "^2.1.0",
467
- shx: "^0.3.4",
468
470
  "ts-node": "^10.8.1"
469
471
  };
470
472
  var repository = {
package/package.json CHANGED
@@ -1,19 +1,21 @@
1
1
  {
2
2
  "name": "@learncard/create-http-bridge",
3
- "version": "1.1.247",
3
+ "version": "1.1.249",
4
4
  "description": "Instantly create and deploy a Learn Card Bridge HTTP API via AWS Lambda!",
5
5
  "main": "dist/index.js",
6
6
  "bin": "dist/index.js",
7
7
  "scripts": {
8
- "serverless-deploy": "shx cp ../learn-card-core/src/didkit/pkg/didkit_wasm_bg.wasm src/didkit_wasm_bg.wasm && serverless deploy",
9
- "start": "rollup -c && node dist/index.js",
10
- "build": "rollup -c"
8
+ "sync-didkit": "bun scripts/sync-didkit.ts",
9
+ "serverless-deploy": "bun run sync-didkit && serverless deploy",
10
+ "start": "bun run sync-didkit && rollup -c && node dist/index.js",
11
+ "start:local": "bun run sync-didkit && bun src/server.ts",
12
+ "build": "bun run sync-didkit && rollup -c"
11
13
  },
12
14
  "author": "Learning Economy Foundation (www.learningeconomy.io)",
13
15
  "license": "MIT",
14
16
  "dependencies": {
15
- "@learncard/init": "2.4.8",
16
- "@learncard/types": "5.17.6",
17
+ "@learncard/init": "2.4.10",
18
+ "@learncard/types": "5.18.1",
17
19
  "@rollup/plugin-json": "^4.1.0",
18
20
  "commander": "^9.3.0",
19
21
  "cors": "^2.8.5",
@@ -35,7 +37,8 @@
35
37
  "serverless-http": "^3.0.1",
36
38
  "serverless-plugin-warmup": "^8.1.0",
37
39
  "simple-git": "^3.36.0",
38
- "use-immer": "^0.7.0"
40
+ "use-immer": "^0.7.0",
41
+ "zod": "4.1.13"
39
42
  },
40
43
  "devDependencies": {
41
44
  "@types/aws-lambda": "^8.10.106",
@@ -48,7 +51,6 @@
48
51
  "@types/react": "^17.0.2",
49
52
  "nodemon": "^2.0.16",
50
53
  "serverless-plugin-typescript": "^2.1.0",
51
- "shx": "^0.3.4",
52
54
  "ts-node": "^10.8.1"
53
55
  },
54
56
  "repository": {
package/project.json CHANGED
@@ -7,7 +7,11 @@
7
7
  "tags": [],
8
8
  "implicitDependencies": ["types", "init"],
9
9
  "namedInputs": {
10
- "source": ["{projectRoot}/src/**/*"],
10
+ "source": [
11
+ "{projectRoot}/src/**/*",
12
+ "{projectRoot}/scripts/sync-didkit.ts",
13
+ "{workspaceRoot}/packages/plugins/didkit/src/didkit/pkg/didkit_wasm_bg.wasm"
14
+ ],
11
15
  "dist": ["{projectRoot}/dist/**/*"]
12
16
  },
13
17
  "targets": {
@@ -0,0 +1,22 @@
1
+ import { createHash } from 'crypto';
2
+ import { readFile, writeFile } from 'fs/promises';
3
+
4
+ const EXPECTED_DIDKIT_SHA256 = '60efb6027699fda135db0d817f7a541bbd660ae88bec9cbec9796feeb3740b96';
5
+ const sourceUrl = new URL(
6
+ '../../plugins/didkit/src/didkit/pkg/didkit_wasm_bg.wasm',
7
+ import.meta.url
8
+ );
9
+ const destinationUrl = new URL('../src/didkit_wasm_bg.wasm', import.meta.url);
10
+ if (!process.env.LOCAL_DIDKIT_PATH) {
11
+ const didkit = await readFile(sourceUrl);
12
+ const actualHash = createHash('sha256').update(didkit).digest('hex');
13
+
14
+ if (actualHash !== EXPECTED_DIDKIT_SHA256) {
15
+ throw new Error(
16
+ `DIDKit WASM hash changed: expected ${EXPECTED_DIDKIT_SHA256}, received ${actualHash}. ` +
17
+ 'Review the rebuilt artifact and update EXPECTED_DIDKIT_SHA256 intentionally.'
18
+ );
19
+ }
20
+
21
+ await writeFile(destinationUrl, didkit);
22
+ }
package/serverless.yml CHANGED
@@ -11,7 +11,6 @@ plugins:
11
11
  custom:
12
12
  esbuild:
13
13
  packager: bun
14
- plugins: esbuildWasmPlugin.cjs
15
14
  warmup:
16
15
  default:
17
16
  enabled: true
@@ -27,6 +26,10 @@ provider:
27
26
  environment:
28
27
  WALLET_SEED: ${env:WALLET_SEED}
29
28
 
29
+ package:
30
+ patterns:
31
+ - src/didkit_wasm_bg.wasm
32
+
30
33
  functions:
31
34
  api:
32
35
  handler: lambda.handler
package/src/app.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import express from 'express';
2
2
  import cors from 'cors';
3
- import { VP, VPValidator } from '@learncard/types';
3
+ import { VCValidator, VPValidator, type UnsignedVC, type VP } from '@learncard/types';
4
4
 
5
5
  import { TypedRequest } from './types.helpers';
6
6
  import {
@@ -19,6 +19,9 @@ const router = express.Router();
19
19
 
20
20
  const app = express();
21
21
 
22
+ const W3C_V1_CREDENTIALS_CONTEXT = 'https://www.w3.org/2018/credentials/v1';
23
+ const W3C_ALT_V1_CREDENTIALS_CONTEXT = 'https://w3.org/2018/credentials/v1';
24
+
22
25
  app.use(cors());
23
26
  app.use(express.json());
24
27
 
@@ -48,11 +51,6 @@ app.delete('/credentials/:id', async (_req: TypedRequest<{}>, res) => {
48
51
 
49
52
  app.post('/credentials/issue', async (req: TypedRequest<IssueEndpoint>, res) => {
50
53
  try {
51
- // If incoming credential doesn't have an issuanceDate, default it to right now
52
- if (req.body?.credential && !('issuanceDate' in (req.body?.credential ?? {}))) {
53
- req.body.credential.issuanceDate = new Date().toISOString();
54
- }
55
-
56
54
  const validationResult = await IssueEndpointValidator.spa(req.body);
57
55
 
58
56
  if (!validationResult.success) {
@@ -67,13 +65,28 @@ app.post('/credentials/issue', async (req: TypedRequest<IssueEndpoint>, res) =>
67
65
  }
68
66
 
69
67
  const validatedBody = validationResult.data;
68
+ const credential = validatedBody.credential as UnsignedVC | undefined;
69
+
70
+ if (!credential) {
71
+ return res.status(400).json('Invalid input: credential is required');
72
+ }
73
+
74
+ const context = credential['@context'];
75
+ const isV1Credential = Array.isArray(context)
76
+ ? context.some(
77
+ contextEntry =>
78
+ contextEntry === W3C_V1_CREDENTIALS_CONTEXT ||
79
+ contextEntry === W3C_ALT_V1_CREDENTIALS_CONTEXT
80
+ )
81
+ : context === W3C_V1_CREDENTIALS_CONTEXT || context === W3C_ALT_V1_CREDENTIALS_CONTEXT;
82
+ const credentialToIssue =
83
+ isV1Credential && !('issuanceDate' in credential)
84
+ ? { ...credential, issuanceDate: new Date().toISOString() }
85
+ : credential;
70
86
  const learnCard = await getLearnCard();
71
87
  const { credentialStatus, ...options } = validatedBody.options ?? {};
72
88
 
73
- const issuedCredential = await learnCard.invoke.issueCredential(
74
- validatedBody.credential,
75
- options
76
- );
89
+ const issuedCredential = await learnCard.invoke.issueCredential(credentialToIssue, options);
77
90
 
78
91
  return res.status(201).json(issuedCredential);
79
92
  } catch (error) {
@@ -119,11 +132,6 @@ app.post('/credentials/verify', async (req: TypedRequest<VerifyCredentialEndpoin
119
132
  return res.status(400).json(verificationResult);
120
133
  }
121
134
 
122
- // Pass a test for interop 🙃
123
- verificationResult.checks = verificationResult.checks.filter(
124
- check => check !== 'expiration'
125
- );
126
-
127
135
  return res.status(200).json(verificationResult);
128
136
  } catch (error) {
129
137
  console.error('[/credentials/verify] Caught error: ', error, '(received: ', req.body);
@@ -265,7 +273,11 @@ app.post('/exchanges/:uri', async (req: TypedRequest<VP, { challenge?: string }>
265
273
 
266
274
  const subject = validatedBody.holder;
267
275
 
268
- const credential = await learnCard.read.get(req.params.uri);
276
+ const credentialResult = VCValidator.safeParse(await learnCard.read.get(req.params.uri));
277
+
278
+ if (!credentialResult.success) return res.status(404).json('Credential not found');
279
+
280
+ const credential = credentialResult.data;
269
281
 
270
282
  credential.issuer = {
271
283
  ...(typeof credential.issuer === 'string' ? {} : credential.issuer),
@@ -277,9 +289,10 @@ app.post('/exchanges/:uri', async (req: TypedRequest<VP, { challenge?: string }>
277
289
  credential.credentialSubject.id = subject;
278
290
  }
279
291
 
280
- delete credential.proof;
292
+ const { proof, ...unsignedCredential } = credential;
293
+ void proof;
281
294
 
282
- const newVc = await learnCard.invoke.issueCredential(credential);
295
+ const newVc = await learnCard.invoke.issueCredential(unsignedCredential);
283
296
 
284
297
  return res.status(201).json(newVc);
285
298
  } catch (error) {
Binary file
package/src/learn-card.ts CHANGED
@@ -1,13 +1,32 @@
1
1
  import fs from 'fs/promises';
2
+ import { existsSync } from 'fs';
3
+ import path from 'path';
2
4
  import { initLearnCard, LearnCardFromSeed } from '@learncard/init';
3
- import didkit from './didkit_wasm_bg.wasm';
5
+
6
+ const getBundledDidkitPath = (): string => {
7
+ const siblingPath = path.join(__dirname, 'didkit_wasm_bg.wasm');
8
+
9
+ if (existsSync(siblingPath)) return siblingPath;
10
+
11
+ return path.join(__dirname, 'src', 'didkit_wasm_bg.wasm');
12
+ };
13
+
14
+ let learnCardPromise: Promise<LearnCardFromSeed['returnValue']> | undefined;
4
15
 
5
16
  export const getLearnCard = async (): Promise<LearnCardFromSeed['returnValue']> => {
17
+ if (learnCardPromise) return learnCardPromise;
18
+
6
19
  const seed = process.env.WALLET_SEED;
7
20
 
8
21
  if (!seed) {
9
22
  throw new Error('No seed set! Please make a .env file and set WALLET_SEED to your seed!');
10
23
  }
11
24
 
12
- return initLearnCard({ seed, didkit });
25
+ const didkit = process.env.LOCAL_DIDKIT_PATH
26
+ ? fs.readFile(process.env.LOCAL_DIDKIT_PATH)
27
+ : fs.readFile(getBundledDidkitPath());
28
+
29
+ learnCardPromise = initLearnCard({ seed, didkit });
30
+
31
+ return learnCardPromise;
13
32
  };
package/src/server.ts ADDED
@@ -0,0 +1,10 @@
1
+ import app from './app';
2
+
3
+ const port = Number(process.env.PORT ?? 3100);
4
+
5
+ const server = app.listen(port, '127.0.0.1', () => {
6
+ console.log(`LearnCard VC API listening at http://127.0.0.1:${port}`);
7
+ });
8
+
9
+ process.on('SIGTERM', () => server.close());
10
+ process.on('SIGINT', () => server.close());
package/src/validators.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { z } from 'zod';
1
+ import { z } from 'zod/v4';
2
2
  import {
3
3
  UnsignedVCValidator,
4
4
  UnsignedVPValidator,
@@ -6,28 +6,42 @@ import {
6
6
  VPValidator,
7
7
  } from '@learncard/types';
8
8
 
9
+ const ProofOptionsValidator = z
10
+ .object({
11
+ type: z.string().optional(),
12
+ verificationMethod: z.string().optional(),
13
+ proofPurpose: z.string().optional(),
14
+ proofFormat: z.string().optional(),
15
+ created: z.string().optional(),
16
+ challenge: z.string().optional(),
17
+ domain: z.string().optional(),
18
+ cryptosuite: z
19
+ .enum([
20
+ 'eddsa-rdfc-2022',
21
+ 'eddsa-2022',
22
+ 'json-eddsa-2022',
23
+ 'ecdsa-2019',
24
+ 'jcs-ecdsa-2019',
25
+ ])
26
+ .optional(),
27
+ })
28
+ .strict();
29
+
30
+ const VerificationProofOptionsValidator = ProofOptionsValidator.extend({
31
+ checks: z.enum(['proof', 'JWS', 'credentialStatus', 'credentialSchema']).array().optional(),
32
+ });
33
+
9
34
  export const IssueEndpointValidator = z.object({
10
35
  credential: UnsignedVCValidator,
11
- options: z
12
- .object({
13
- created: z.string().optional(),
14
- challenge: z.string().optional(),
15
- domain: z.string().optional(),
16
- credentialStatus: z.object({ type: z.string() }).optional(),
17
- })
18
- .optional(),
36
+ options: ProofOptionsValidator.extend({
37
+ credentialStatus: z.object({ type: z.string() }).optional(),
38
+ }).optional(),
19
39
  });
20
40
  export type IssueEndpoint = z.infer<typeof IssueEndpointValidator>;
21
41
 
22
42
  export const IssuePresentationEndpointValidator = z.object({
23
43
  presentation: UnsignedVPValidator,
24
- options: z
25
- .object({
26
- created: z.string().optional(),
27
- challenge: z.string().optional(),
28
- domain: z.string().optional(),
29
- })
30
- .optional(),
44
+ options: ProofOptionsValidator.optional(),
31
45
  });
32
46
  export type IssuePresentationEndpoint = z.infer<typeof IssuePresentationEndpointValidator>;
33
47
 
@@ -42,18 +56,14 @@ export type UpdateStatusEndpoint = z.infer<typeof UpdateStatusEndpointValidator>
42
56
 
43
57
  export const VerifyCredentialEndpointValidator = z.object({
44
58
  verifiableCredential: VCValidator,
45
- options: z
46
- .object({ challenge: z.string().optional(), domain: z.string().optional() })
47
- .optional(),
59
+ options: VerificationProofOptionsValidator.optional(),
48
60
  });
49
61
  export type VerifyCredentialEndpoint = z.infer<typeof VerifyCredentialEndpointValidator>;
50
62
 
51
63
  export const VerifyPresentationEndpointValidator = z
52
64
  .object({
53
65
  verifiablePresentation: VPValidator,
54
- options: z
55
- .object({ challenge: z.string().optional(), domain: z.string().optional() })
56
- .optional(),
66
+ options: VerificationProofOptionsValidator.optional(),
57
67
  })
58
68
  .or(z.object({ presentation: UnsignedVPValidator }));
59
69
  export type VerifyPresentationEndpoint = z.infer<typeof VerifyPresentationEndpointValidator>;
@@ -0,0 +1,35 @@
1
+ const baseUrl = process.env.BASE_URL || 'http://127.0.0.1:3100';
2
+
3
+ module.exports = {
4
+ settings: {
5
+ enableInteropTests: false,
6
+ testAllImplementations: false,
7
+ },
8
+ implementations: [
9
+ {
10
+ name: 'Learning Economy Foundation',
11
+ implementation: 'LearnCard DIDKit',
12
+ issuers: [
13
+ {
14
+ id: 'did:key:z6Mkv1o2GEgtXjFdEMfLtupcKhGRydM8V7VHzii7Uh4aHoqH',
15
+ endpoint: `${baseUrl}/credentials/issue`,
16
+ options: {
17
+ type: 'DataIntegrityProof',
18
+ cryptosuite: 'eddsa-rdfc-2022',
19
+ },
20
+ supports: {
21
+ vc: ['1.1', '2.0'],
22
+ },
23
+ tags: ['eddsa-rdfc-2022', 'localhost'],
24
+ },
25
+ ],
26
+ verifiers: [
27
+ {
28
+ id: 'did:key:z6Mkv1o2GEgtXjFdEMfLtupcKhGRydM8V7VHzii7Uh4aHoqH',
29
+ endpoint: `${baseUrl}/credentials/verify`,
30
+ tags: ['eddsa-rdfc-2022', 'localhost'],
31
+ },
32
+ ],
33
+ },
34
+ ],
35
+ };
@@ -1,31 +0,0 @@
1
- const wasmPlugin = {
2
- name: 'wasm',
3
- setup(build) {
4
- let path = require('path');
5
- let fs = require('fs');
6
-
7
- // Resolve ".wasm" files to a path with a namespace
8
- build.onResolve({ filter: /\.wasm$/ }, args => {
9
- if (args.resolveDir === '') {
10
- return; // Ignore unresolvable paths
11
- }
12
- return {
13
- path: path.isAbsolute(args.path)
14
- ? args.path
15
- : path.join(args.resolveDir, args.path),
16
- namespace: 'wasm-binary',
17
- };
18
- });
19
-
20
- // Virtual modules in the "wasm-binary" namespace contain the
21
- // actual bytes of the WebAssembly file. This uses esbuild's
22
- // built-in "binary" loader instead of manually embedding the
23
- // binary data inside JavaScript code ourselves.
24
- build.onLoad({ filter: /.*/, namespace: 'wasm-binary' }, async args => ({
25
- contents: await fs.promises.readFile(args.path),
26
- loader: 'binary',
27
- }));
28
- },
29
- };
30
-
31
- module.exports = [wasmPlugin];