dlintr 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -22
- package/ghc_wasm_jsffi.js +114 -0
- package/hadolint.wasm +0 -0
- package/lib/api.d.ts +4 -4
- package/lib/api.js +29 -30
- package/lib/api.js.map +1 -1
- package/lib/browser.d.ts +3 -4
- package/lib/browser.js +22 -3
- package/lib/browser.js.map +1 -1
- package/lib/index.cjs +212 -172
- package/lib/index.d.ts +3 -4
- package/lib/index.js +21 -3
- package/lib/index.js.map +1 -1
- package/lib/memoize.d.ts +1 -0
- package/lib/memoize.js +14 -0
- package/lib/memoize.js.map +1 -0
- package/lib/reactor.d.ts +6 -0
- package/lib/reactor.js +21 -0
- package/lib/reactor.js.map +1 -0
- package/lib/types.d.ts +0 -10
- package/lib/wasi.d.ts +11 -0
- package/lib/wasi.js +88 -0
- package/lib/wasi.js.map +1 -0
- package/package.json +7 -15
- package/lib/runtime.d.ts +0 -6
- package/lib/runtime.js +0 -3
- package/lib/runtime.js.map +0 -1
- package/lib/wasi-browser.d.ts +0 -2
- package/lib/wasi-browser.js +0 -48
- package/lib/wasi-browser.js.map +0 -1
- package/lib/wasi-node.d.ts +0 -2
- package/lib/wasi-node.js +0 -127
- package/lib/wasi-node.js.map +0 -1
package/README.md
CHANGED
|
@@ -20,6 +20,8 @@ Dockerfile linter, validate inline bash, powered by [`hadolint`](https://github.
|
|
|
20
20
|
- [Install](#install)
|
|
21
21
|
- [API](#api)
|
|
22
22
|
- [How it works](#how-it-works)
|
|
23
|
+
- [The WASI surface, and its residual risk](#the-wasi-surface-and-its-residual-risk)
|
|
24
|
+
- [The digest, and what it does not promise](#the-digest-and-what-it-does-not-promise)
|
|
23
25
|
- [Sponsors](#sponsors)
|
|
24
26
|
- [Backers](#backers)
|
|
25
27
|
- [Changelog](#changelog)
|
|
@@ -40,12 +42,13 @@ yarn add dlintr
|
|
|
40
42
|
npm i dlintr
|
|
41
43
|
```
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
The only runtime dependency is `tslib`. The WASI surface hadolint needs is
|
|
46
|
+
implemented in `src/wasi.ts` rather than taken from a library.
|
|
44
47
|
|
|
45
48
|
### API
|
|
46
49
|
|
|
47
50
|
```js
|
|
48
|
-
import { getVersion, lint
|
|
51
|
+
import { getVersion, lint } from 'dlintr'
|
|
49
52
|
|
|
50
53
|
// Lint Dockerfile content and get the findings back.
|
|
51
54
|
const results = await lint('FROM ubuntu:latest\nRUN apt-get update\n')
|
|
@@ -55,34 +58,93 @@ const results = await lint('FROM ubuntu:latest\nRUN apt-get update\n')
|
|
|
55
58
|
// ]
|
|
56
59
|
|
|
57
60
|
await lint('FROM alpine:3.20\n', {
|
|
58
|
-
ignore: ['DL3009'], // rule codes to suppress
|
|
61
|
+
ignore: ['DL3009'], // rule codes to suppress, applied to the findings
|
|
59
62
|
severityOverrides: { DL3007: 'error' }, // re-level a single rule
|
|
60
63
|
env: { HADOLINT_TRUSTED_REGISTRIES: 'docker.io' }, // anything hadolint reads
|
|
61
64
|
})
|
|
62
65
|
|
|
63
|
-
await getVersion() // 'Haskell Dockerfile Linter
|
|
64
|
-
|
|
65
|
-
// Or drive the CLI directly, for options `lint` does not model.
|
|
66
|
-
const { exitCode, stdout, stderr } = await run(
|
|
67
|
-
['--no-color', '--failure-threshold', 'error', '-'],
|
|
68
|
-
{
|
|
69
|
-
stdin: 'FROM ubuntu:latest\n',
|
|
70
|
-
},
|
|
71
|
-
)
|
|
66
|
+
await getVersion() // 'Haskell Dockerfile Linter 2.15.1'
|
|
72
67
|
```
|
|
73
68
|
|
|
74
|
-
An unparseable Dockerfile is reported, not thrown: hadolint returns it as a
|
|
69
|
+
An unparseable Dockerfile is reported, not thrown: hadolint returns it as a
|
|
70
|
+
`DL1000` finding with `level: 'error'`.
|
|
75
71
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
### How it works
|
|
72
|
+
To gate CI, look at `level`:
|
|
79
73
|
|
|
80
|
-
|
|
74
|
+
```js
|
|
75
|
+
const problems = (await lint(dockerfile)).filter(
|
|
76
|
+
({ level }) => level === 'error',
|
|
77
|
+
)
|
|
78
|
+
```
|
|
81
79
|
|
|
82
|
-
|
|
83
|
-
- **Browsers** get [`@bjorn3/browser_wasi_shim`][bjorn3] (~29 kB minified) through the `browser` export condition. It is an optional peer dependency — install it if you target the browser, and Node users never pay for it.
|
|
80
|
+
### How it works
|
|
84
81
|
|
|
85
|
-
|
|
82
|
+
[`hadolint`][hadolint] is compiled to a WebAssembly _reactor_ with the GHC
|
|
83
|
+
backend and called in-process; there is no native binary and no Docker. The
|
|
84
|
+
module is instantiated once and `lint` is called on it.
|
|
85
|
+
|
|
86
|
+
**This is a breaking change from 0.1.x.** The module previously exposed
|
|
87
|
+
hadolint's command-line interface, and now exports `lint()` and
|
|
88
|
+
`getVersion():`
|
|
89
|
+
|
|
90
|
+
- **`run()` is gone**, and with it the whole CLI surface. `--failure-threshold`,
|
|
91
|
+
`--config`, `--format`, `--no-color` and the rest are no longer reachable
|
|
92
|
+
from JavaScript. `lint` returns the findings as JSON, and the output format is
|
|
93
|
+
no longer configurable.
|
|
94
|
+
- `ignore` and `severityOverrides` survive, applied to the returned findings —
|
|
95
|
+
they only ever filtered and relabelled, so they never needed the Haskell side.
|
|
96
|
+
- `env` survives too, and reaches hadolint through WASI as before.
|
|
97
|
+
- **`node:wasi` cannot host this module at all.** Its `initialize` ends in
|
|
98
|
+
`proc_exit(71)` and the RTS never starts, so every call answers "RTS is not
|
|
99
|
+
initialised". That is true of upstream's published reactor as well, so it is a
|
|
100
|
+
limitation of `node:wasi` rather than of this build. Node and the browser
|
|
101
|
+
therefore share one WASI implementation, from `src/wasi.ts`.
|
|
102
|
+
|
|
103
|
+
Nothing is fed over stdin any more: the Dockerfile is passed straight to `lint`,
|
|
104
|
+
so the module never sees a file descriptor that could read the host.
|
|
105
|
+
|
|
106
|
+
### The WASI surface, and its residual risk
|
|
107
|
+
|
|
108
|
+
hadolint needs five WASI calls — `args_get`, `args_sizes_get`, `environ_get`,
|
|
109
|
+
`environ_sizes_get` and `clock_time_get` — and never touches the other fifteen
|
|
110
|
+
it declares, including all of `fd_*`, `path_*` and `proc_exit`. That is
|
|
111
|
+
**measured, not assumed**: `node wasm/calls.mjs` instruments every import and
|
|
112
|
+
reports what is actually called on each path. Run it when the hadolint submodule
|
|
113
|
+
or the wasm recipe moves.
|
|
114
|
+
|
|
115
|
+
`src/wasi.ts` implements those five and makes the rest **throw by name**, so a
|
|
116
|
+
module that reaches further fails at `fd_write` with an explanation rather than
|
|
117
|
+
silently losing output.
|
|
118
|
+
|
|
119
|
+
Two things follow, stated plainly:
|
|
120
|
+
|
|
121
|
+
- **The implemented surface is version-bound.** It is correct for the build that
|
|
122
|
+
was measured. That is exactly why the unimplemented imports throw rather than
|
|
123
|
+
doing nothing, and why `wasm/calls.mjs` is committed.
|
|
124
|
+
- **This is not a tested third-party WASI implementation.** The stubs protect the
|
|
125
|
+
paths the test suite exercises. A path it does not exercise could reach an
|
|
126
|
+
unimplemented import in your hands, and the failure there is an exception
|
|
127
|
+
rather than a wrong answer — better than silent corruption, but not the same
|
|
128
|
+
guarantee a maintained WASI library gives.
|
|
129
|
+
|
|
130
|
+
### The digest, and what it does not promise
|
|
131
|
+
|
|
132
|
+
The build is attested and the npm tarball is content-addressed, so what you
|
|
133
|
+
install is what was published. **A digest identifies a build; it does not
|
|
134
|
+
guarantee one.**
|
|
135
|
+
|
|
136
|
+
This module is **not reproducible**. Two from-scratch builds of the same source,
|
|
137
|
+
with the same toolchain and no build cache, produce different bytes — eight
|
|
138
|
+
distinct digests are on record for one pinned revision of hadolint. So the
|
|
139
|
+
digest is useful for telling one published artifact from another and for tying an
|
|
140
|
+
artifact to its attestation, and for nothing stronger than that.
|
|
141
|
+
|
|
142
|
+
An earlier version of this repository used the digest as a drift gate, comparing
|
|
143
|
+
each build against a recorded value and failing on a mismatch. It was retired,
|
|
144
|
+
because it failed on every run: a gate that presupposes a property the build does
|
|
145
|
+
not have is not a gate. The measurements are written up in
|
|
146
|
+
[`wasm/upstream-report.md`](./wasm/upstream-report.md) and filed upstream as
|
|
147
|
+
[haskell-wasm/ghc-wasm-bindists#49](https://github.com/haskell-wasm/ghc-wasm-bindists/issues/49).
|
|
86
148
|
|
|
87
149
|
## Sponsors
|
|
88
150
|
|
|
@@ -107,8 +169,6 @@ Detailed changes for each release are documented in [CHANGELOG.md](./CHANGELOG.m
|
|
|
107
169
|
[MIT][] © [JounQin][]@[1stG.me][]
|
|
108
170
|
|
|
109
171
|
[1stg.me]: https://www.1stg.me
|
|
110
|
-
[bjorn3]: https://github.com/bjorn3/browser_wasi_shim
|
|
111
172
|
[hadolint]: https://github.com/hadolint/hadolint
|
|
112
173
|
[jounqin]: https://GitHub.com/JounQin
|
|
113
174
|
[mit]: http://opensource.org/licenses/MIT
|
|
114
|
-
[node-wasi]: https://nodejs.org/api/wasi.html
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// This file implements the JavaScript runtime logic for Haskell
|
|
2
|
+
// modules that use JSFFI. It is not an ESM module, but the template
|
|
3
|
+
// of one; the post-linker script will copy all contents into a new
|
|
4
|
+
// ESM module.
|
|
5
|
+
|
|
6
|
+
// Manage a mapping from 32-bit ids to actual JavaScript values.
|
|
7
|
+
class JSValManager {
|
|
8
|
+
#lastk = 0;
|
|
9
|
+
#kv = new Map();
|
|
10
|
+
|
|
11
|
+
newJSVal(v) {
|
|
12
|
+
const k = ++this.#lastk;
|
|
13
|
+
this.#kv.set(k, v);
|
|
14
|
+
return k;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// A separate has() call to ensure we can store undefined as a value
|
|
18
|
+
// too. Also, unconditionally check this since the check is cheap
|
|
19
|
+
// anyway, if the check fails then there's a use-after-free to be
|
|
20
|
+
// fixed.
|
|
21
|
+
getJSVal(k) {
|
|
22
|
+
if (!this.#kv.has(k)) {
|
|
23
|
+
throw new WebAssembly.RuntimeError(`getJSVal(${k})`);
|
|
24
|
+
}
|
|
25
|
+
return this.#kv.get(k);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Check for double free as well.
|
|
29
|
+
freeJSVal(k) {
|
|
30
|
+
if (!this.#kv.delete(k)) {
|
|
31
|
+
throw new WebAssembly.RuntimeError(`freeJSVal(${k})`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// The actual setImmediate() to be used. This is a ESM module top
|
|
37
|
+
// level binding and doesn't pollute the globalThis namespace.
|
|
38
|
+
//
|
|
39
|
+
// To benchmark different setImmediate() implementations in the
|
|
40
|
+
// browser, use https://github.com/jphpsf/setImmediate-shim-demo as a
|
|
41
|
+
// starting point.
|
|
42
|
+
const setImmediate = await (async () => {
|
|
43
|
+
// node, bun, or other scripts might have set this up in the browser
|
|
44
|
+
if (globalThis.setImmediate) {
|
|
45
|
+
return globalThis.setImmediate;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// deno
|
|
49
|
+
if (globalThis.Deno) {
|
|
50
|
+
try {
|
|
51
|
+
return (await import("node:timers")).setImmediate;
|
|
52
|
+
} catch {}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Scheduler/postTask
|
|
56
|
+
if (globalThis.scheduler) {
|
|
57
|
+
return (cb, ...args) => scheduler.postTask(() => cb(...args));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Cloudflare workers doesn't support MessageChannel
|
|
61
|
+
if (globalThis.MessageChannel) {
|
|
62
|
+
// A simple & fast setImmediate() implementation for browsers. It's
|
|
63
|
+
// not a drop-in replacement for node.js setImmediate() because:
|
|
64
|
+
// 1. There's no clearImmediate(), and setImmediate() doesn't return
|
|
65
|
+
// anything
|
|
66
|
+
// 2. There's no guarantee that callbacks scheduled by setImmediate()
|
|
67
|
+
// are executed in the same order (in fact it's the opposite lol),
|
|
68
|
+
// but you are never supposed to rely on this assumption anyway
|
|
69
|
+
class SetImmediate {
|
|
70
|
+
#fs = [];
|
|
71
|
+
#mc = new MessageChannel();
|
|
72
|
+
|
|
73
|
+
constructor() {
|
|
74
|
+
this.#mc.port1.addEventListener("message", () => {
|
|
75
|
+
this.#fs.pop()();
|
|
76
|
+
});
|
|
77
|
+
this.#mc.port1.start();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
setImmediate(cb, ...args) {
|
|
81
|
+
this.#fs.push(() => cb(...args));
|
|
82
|
+
this.#mc.port2.postMessage(undefined);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const sm = new SetImmediate();
|
|
87
|
+
return (cb, ...args) => sm.setImmediate(cb, ...args);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return (cb, ...args) => setTimeout(cb, 0, ...args);
|
|
91
|
+
})();
|
|
92
|
+
|
|
93
|
+
export default (__exports) => {
|
|
94
|
+
const __ghc_wasm_jsffi_jsval_manager = new JSValManager();
|
|
95
|
+
const __ghc_wasm_jsffi_finalization_registry = globalThis.FinalizationRegistry ? new FinalizationRegistry(sp => __exports.rts_freeStablePtr(sp)) : { register: () => {}, unregister: () => true };
|
|
96
|
+
return {
|
|
97
|
+
newJSVal: (v) => __ghc_wasm_jsffi_jsval_manager.newJSVal(v),
|
|
98
|
+
getJSVal: (k) => __ghc_wasm_jsffi_jsval_manager.getJSVal(k),
|
|
99
|
+
freeJSVal: (k) => __ghc_wasm_jsffi_jsval_manager.freeJSVal(k),
|
|
100
|
+
scheduleWork: () => setImmediate(__exports.rts_schedulerLoop),
|
|
101
|
+
ZC0ZCghczminternalZCGHCziInternalziWasmziPrimziExportsZC: ($1,$2) => ($1.reject(new WebAssembly.RuntimeError($2))),
|
|
102
|
+
ZC18ZCghczminternalZCGHCziInternalziWasmziPrimziExportsZC: ($1,$2) => ($1.resolve($2)),
|
|
103
|
+
ZC20ZCghczminternalZCGHCziInternalziWasmziPrimziExportsZC: ($1) => {$1.throwTo = () => {};},
|
|
104
|
+
ZC21ZCghczminternalZCGHCziInternalziWasmziPrimziExportsZC: ($1,$2) => {$1.throwTo = (err) => __exports.rts_promiseThrowTo($2, err);},
|
|
105
|
+
ZC22ZCghczminternalZCGHCziInternalziWasmziPrimziExportsZC: () => {let res, rej; const p = new Promise((resolve, reject) => { res = resolve; rej = reject; }); p.resolve = res; p.reject = rej; return p;},
|
|
106
|
+
ZC0ZCghczminternalZCGHCziInternalziWasmziPrimziTypesZC: ($1) => (`${$1.stack ? $1.stack : $1}`),
|
|
107
|
+
ZC1ZCghczminternalZCGHCziInternalziWasmziPrimziTypesZC: ($1,$2) => ((new TextDecoder('utf-8', {fatal: true})).decode(new Uint8Array(__exports.memory.buffer, $1, $2))),
|
|
108
|
+
ZC2ZCghczminternalZCGHCziInternalziWasmziPrimziTypesZC: ($1,$2,$3) => ((new TextEncoder()).encodeInto($1, new Uint8Array(__exports.memory.buffer, $2, $3)).written),
|
|
109
|
+
ZC3ZCghczminternalZCGHCziInternalziWasmziPrimziTypesZC: ($1) => ($1.length),
|
|
110
|
+
ZC4ZCghczminternalZCGHCziInternalziWasmziPrimziTypesZC: ($1) => {try { __ghc_wasm_jsffi_finalization_registry.unregister($1); } catch {}},
|
|
111
|
+
ZC18ZCghczminternalZCGHCziInternalziWasmziPrimziImportsZC: ($1,$2) => ($1.then(() => __exports.rts_promiseResolveUnit($2), err => __exports.rts_promiseReject($2, err))),
|
|
112
|
+
ZC0ZCghczminternalZCGHCziInternalziWasmziPrimziConcziInternalZC: async ($1) => (new Promise(res => setTimeout(res, $1 / 1000))),
|
|
113
|
+
};
|
|
114
|
+
};
|
package/hadolint.wasm
CHANGED
|
Binary file
|
package/lib/api.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { LintOptions, LintResult
|
|
1
|
+
import type { Reactor } from './reactor.js';
|
|
2
|
+
import type { LintOptions, LintResult } from './types.js';
|
|
3
3
|
export interface Dlinter {
|
|
4
|
-
run: (args: string[], options?: RunOptions) => Promise<RunResult>;
|
|
5
4
|
lint: (dockerfile: string, options?: LintOptions) => Promise<LintResult[]>;
|
|
6
5
|
getVersion: () => Promise<string>;
|
|
7
6
|
}
|
|
8
|
-
export
|
|
7
|
+
export type LoadReactor = (env: readonly string[]) => Promise<Reactor>;
|
|
8
|
+
export declare const createDlinter: (load: LoadReactor) => Dlinter;
|
package/lib/api.js
CHANGED
|
@@ -1,37 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
const HOME = 'HOME=/';
|
|
2
|
+
export const createDlinter = (load) => {
|
|
3
|
+
const reactors = new Map();
|
|
4
|
+
const instance = (env) => {
|
|
5
|
+
const pairs = [
|
|
6
|
+
HOME,
|
|
7
|
+
...Object.entries(env ?? {}).map(([key, value]) => `${key}=${value}`),
|
|
8
|
+
];
|
|
9
|
+
const key = JSON.stringify(pairs);
|
|
10
|
+
let reactor = reactors.get(key);
|
|
11
|
+
if (!reactor) {
|
|
12
|
+
reactor = load(pairs);
|
|
13
|
+
reactors.set(key, reactor);
|
|
14
|
+
reactor.catch(() => reactors.delete(key));
|
|
15
|
+
}
|
|
16
|
+
return reactor;
|
|
17
|
+
};
|
|
3
18
|
return {
|
|
4
|
-
run: runtime.run,
|
|
5
19
|
lint: async (dockerfile, options = {}) => {
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
args.push('-');
|
|
16
|
-
const { stdout, stderr } = await runtime.run(args, {
|
|
17
|
-
stdin: dockerfile,
|
|
18
|
-
env: options.env,
|
|
20
|
+
const { lint } = await instance(options.env);
|
|
21
|
+
const findings = JSON.parse(await lint(dockerfile));
|
|
22
|
+
const ignored = new Set(options.ignore ?? []);
|
|
23
|
+
return findings
|
|
24
|
+
.filter(({ code }) => !ignored.has(code))
|
|
25
|
+
.map(finding => {
|
|
26
|
+
const level = options.severityOverrides?.[finding.code];
|
|
27
|
+
return level ? { ...finding, level } : finding;
|
|
19
28
|
});
|
|
20
|
-
if (!stdout) {
|
|
21
|
-
if (stderr) {
|
|
22
|
-
throw new Error(stderr.trim());
|
|
23
|
-
}
|
|
24
|
-
return [];
|
|
25
|
-
}
|
|
26
|
-
return JSON.parse(stdout);
|
|
27
29
|
},
|
|
28
|
-
getVersion: () =>
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
version = undefined;
|
|
33
|
-
throw error;
|
|
34
|
-
})),
|
|
30
|
+
getVersion: async () => {
|
|
31
|
+
const { version } = await instance();
|
|
32
|
+
return version();
|
|
33
|
+
},
|
|
35
34
|
};
|
|
36
35
|
};
|
|
37
36
|
//# sourceMappingURL=api.js.map
|
package/lib/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AA+BA,MAAM,IAAI,GAAG,QAAQ,CAAA;AAGrB,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAiB,EAAW,EAAE;IAC1D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA4B,CAAA;IAEpD,MAAM,QAAQ,GAAG,CAAC,GAA4B,EAAoB,EAAE;QAClE,MAAM,KAAK,GAAG;YACZ,IAAI;YACJ,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;SACtE,CAAA;QAGD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;QAEjC,IAAI,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;YACrB,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;YAE1B,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;QAC3C,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC,CAAA;IAED,OAAO;QACL,IAAI,EAAE,KAAK,EACT,UAAkB,EAClB,OAAO,GAAgB,EAAE,EACF,EAAE;YACzB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,CAAiB,CAAA;YAMnE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAA;YAC7C,OAAO,QAAQ;iBACZ,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;iBACxC,GAAG,CAAC,OAAO,CAAC,EAAE;gBACb,MAAM,KAAK,GACT,OAAO,CAAC,iBAAiB,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;gBAG3C,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;YAChD,CAAC,CAAC,CAAA;QACN,CAAC;QAED,UAAU,EAAE,KAAK,IAAqB,EAAE;YACtC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,EAAE,CAAA;YACpC,OAAO,OAAO,EAAE,CAAA;QAClB,CAAC;KACF,CAAA;AACH,CAAC,CAAA"}
|
package/lib/browser.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
export declare const run: (args: string[], options?: import("./types.js").RunOptions) => Promise<import("./types.js").RunResult>;
|
|
2
1
|
export declare const lint: (dockerfile: string, options?: import("./types.js").LintOptions) => Promise<import("./types.js").LintResult[]>;
|
|
3
2
|
export declare const getVersion: () => Promise<string>;
|
|
4
|
-
export type { Dlinter } from './api.js';
|
|
5
|
-
export type {
|
|
6
|
-
export type { LintOptions, LintResult,
|
|
3
|
+
export type { Dlinter, LoadReactor } from './api.js';
|
|
4
|
+
export type { Reactor } from './reactor.js';
|
|
5
|
+
export type { LintOptions, LintResult, Severity } from './types.js';
|
package/lib/browser.js
CHANGED
|
@@ -1,7 +1,26 @@
|
|
|
1
|
+
import { __rewriteRelativeImportExtension } from "tslib";
|
|
1
2
|
import { createDlinter } from './api.js';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import { memoize } from './memoize.js';
|
|
4
|
+
import { createReactor } from './reactor.js';
|
|
5
|
+
const loadAssets = memoize(async () => {
|
|
6
|
+
const wasmUrl = new URL('../hadolint.wasm', import.meta.url);
|
|
7
|
+
const glueUrl = new URL('../ghc_wasm_jsffi.js', import.meta.url);
|
|
8
|
+
const [response, glue] = await Promise.all([
|
|
9
|
+
fetch(wasmUrl),
|
|
10
|
+
import(__rewriteRelativeImportExtension(glueUrl.href, true)),
|
|
11
|
+
]);
|
|
12
|
+
if (!response.ok) {
|
|
13
|
+
throw new Error(`dlintr: could not fetch ${wasmUrl.pathname}: ${response.status} ${response.statusText}`);
|
|
14
|
+
}
|
|
15
|
+
return [
|
|
16
|
+
await WebAssembly.compile(await response.arrayBuffer()),
|
|
17
|
+
glue.default,
|
|
18
|
+
];
|
|
19
|
+
});
|
|
20
|
+
const dlinter = createDlinter(async (env) => {
|
|
21
|
+
const [module, glue] = await loadAssets();
|
|
22
|
+
return createReactor(module, glue, env);
|
|
23
|
+
});
|
|
5
24
|
export const lint = dlinter.lint;
|
|
6
25
|
export const getVersion = dlinter.getVersion;
|
|
7
26
|
//# sourceMappingURL=browser.js.map
|
package/lib/browser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":";AAQA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAO5C,MAAM,UAAU,GAAG,OAAO,CACxB,KAAK,IAA0D,EAAE;IAC/D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,kBAAkB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAA;IAC5D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,sBAAsB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAA;IAEhE,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACzC,KAAK,CAAC,OAAO,CAAC;QACd,MAAM,kCAAC,OAAO,CAAC,IAAI,QAAuC;KAC3D,CAAC,CAAA;IAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,2BAA2B,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CACzF,CAAA;IACH,CAAC;IAED,OAAO;QACL,MAAM,WAAW,CAAC,OAAO,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;QACvD,IAAI,CAAC,OAAO;KACJ,CAAA;AACZ,CAAC,CACF,CAAA;AAED,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,EAAC,GAAG,EAAC,EAAE;IACxC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,MAAM,UAAU,EAAE,CAAA;IACzC,OAAO,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;AACzC,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;AAChC,MAAM,CAAC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAA"}
|