plumb-fhir 0.6.1 → 0.6.2
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 +13 -0
- package/dist/cjs/commands.d.ts.map +1 -1
- package/dist/cjs/conformance.d.ts +4 -1
- package/dist/cjs/conformance.d.ts.map +1 -1
- package/dist/esm/cli.mjs +49 -32
- package/dist/esm/cli.mjs.map +3 -3
- package/dist/esm/commands.d.ts.map +1 -1
- package/dist/esm/conformance.d.ts +4 -1
- package/dist/esm/conformance.d.ts.map +1 -1
- package/package.json +11 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.6.2 (2026-10-05)
|
|
4
|
+
|
|
5
|
+
`validate` and `push` from an installed Plumb, and on Medplum's `awslambda`
|
|
6
|
+
bot runtime, where the checker now has its first verified run.
|
|
7
|
+
|
|
8
|
+
- **The installed CLI finds its own package.** It stopped at
|
|
9
|
+
`dist/esm/package.json`, so `validate` and `push` failed reading
|
|
10
|
+
`dist/esm/dist/checker.cjs`, and `--version` printed `undefined` (#117,
|
|
11
|
+
#118). `./package.json` is exported.
|
|
12
|
+
- **On the `awslambda` runtime, a page waits while the checker's function is
|
|
13
|
+
not ready** (`Pending` after an install, an update in progress after a
|
|
14
|
+
redeploy), for up to a minute, instead of failing the first gate (#119).
|
|
15
|
+
|
|
3
16
|
## 0.6.1 (2026-10-05)
|
|
4
17
|
|
|
5
18
|
Fixes from the first adoption of 0.6.0 in a Medplum monorepo. Regenerate to
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/commands.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,KAAK,OAAO,EAIb,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAiC,KAAK,IAAI,EAAE,MAAM,eAAe,CAAC;AAGzE,MAAM,WAAW,KAAK;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACxC,6DAA6D;IAC7D,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/commands.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,KAAK,OAAO,EAIb,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAiC,KAAK,IAAI,EAAE,MAAM,eAAe,CAAC;AAGzE,MAAM,WAAW,KAAK;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACxC,6DAA6D;IAC7D,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAyDD,uEAAuE;AACvE,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAe1D;AAED,2EAA2E;AAC3E,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBpE;AAqID,KAAK,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAAC,CAAC;AAIjD,kGAAkG;AAClG,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,EAAE,CAexD"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type MedplumClient } from '@medplum/core';
|
|
2
|
-
import type { Reason } from './checker/handler.js';
|
|
2
|
+
import type { PageResult, Reason } from './checker/handler.js';
|
|
3
|
+
import { checkerInput } from './checker/input.js';
|
|
3
4
|
import { type EnvOptions, type EnvResult } from './connect.js';
|
|
4
5
|
import type { LoadProfilesResult } from './loader.js';
|
|
5
6
|
type ValidateStepName = 'load' | 'connect' | 'checker' | 'profiles' | 'validate';
|
|
@@ -85,5 +86,7 @@ export declare function judge(result: Pick<Checked, 'types' | 'profiles'>, selec
|
|
|
85
86
|
summary: string;
|
|
86
87
|
failed: boolean;
|
|
87
88
|
};
|
|
89
|
+
/** One page, as an async job: a page can outlast an HTTP request, not the bot's timeout. */
|
|
90
|
+
export declare function runPage(medplum: MedplumClient, botId: string, input: ReturnType<typeof checkerInput>, wait?: (ms: number) => Promise<void>): Promise<PageResult>;
|
|
88
91
|
export {};
|
|
89
92
|
//# sourceMappingURL=conformance.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conformance.d.ts","sourceRoot":"","sources":["../../src/conformance.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"conformance.d.ts","sourceRoot":"","sources":["../../src/conformance.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/cli.mjs
CHANGED
|
@@ -1251,8 +1251,8 @@ function registerCore() {
|
|
|
1251
1251
|
coreIndexed = true;
|
|
1252
1252
|
}
|
|
1253
1253
|
function dependenciesOf(dir) {
|
|
1254
|
-
const
|
|
1255
|
-
return Object.entries(
|
|
1254
|
+
const manifest2 = JSON.parse(readFileSync(join2(dir, "package", "package.json"), "utf8"));
|
|
1255
|
+
return Object.entries(manifest2.dependencies ?? {}).map(([name2, version2]) => `${name2}@${version2}`);
|
|
1256
1256
|
}
|
|
1257
1257
|
var Closure = class {
|
|
1258
1258
|
definitions = /* @__PURE__ */ new Map();
|
|
@@ -1498,8 +1498,8 @@ async function resolve3(igs, lock, check2, cacheDir, fetch) {
|
|
|
1498
1498
|
const locked = lock?.packages[id]?.integrity;
|
|
1499
1499
|
if (check2 && !locked) throw new Failure("lock-disagrees", `plumb.lock does not list ${id}.`);
|
|
1500
1500
|
const { pkg, integrity } = await ensureCached(id, cacheDir, locked, fetch);
|
|
1501
|
-
const
|
|
1502
|
-
if (roots.has(id)) queue.push(...dependenciesOf2(id,
|
|
1501
|
+
const manifest2 = readManifest(id, pkg.dir);
|
|
1502
|
+
if (roots.has(id)) queue.push(...dependenciesOf2(id, manifest2));
|
|
1503
1503
|
packages.push(pkg);
|
|
1504
1504
|
integrities[id] = { integrity };
|
|
1505
1505
|
} catch (err) {
|
|
@@ -1542,16 +1542,16 @@ async function ensureCached(id, cacheDir, locked, fetch) {
|
|
|
1542
1542
|
return { pkg: { name: name2, version: version2, dir, fetched, integrity }, integrity };
|
|
1543
1543
|
}
|
|
1544
1544
|
function readManifest(id, dir) {
|
|
1545
|
-
const
|
|
1545
|
+
const manifest2 = JSON.parse(
|
|
1546
1546
|
readFileSync2(join3(dir, "package", "package.json"), "utf8")
|
|
1547
1547
|
);
|
|
1548
|
-
if (
|
|
1549
|
-
throw new Failure("not-r4", `${id} is for FHIR ${
|
|
1548
|
+
if (manifest2.fhirVersions && !manifest2.fhirVersions.some((v) => v.startsWith("4.0"))) {
|
|
1549
|
+
throw new Failure("not-r4", `${id} is for FHIR ${manifest2.fhirVersions.join(", ")}, not R4.`);
|
|
1550
1550
|
}
|
|
1551
|
-
return
|
|
1551
|
+
return manifest2;
|
|
1552
1552
|
}
|
|
1553
|
-
function dependenciesOf2(id,
|
|
1554
|
-
return Object.entries(
|
|
1553
|
+
function dependenciesOf2(id, manifest2) {
|
|
1554
|
+
return Object.entries(manifest2.dependencies ?? {}).filter(([name2]) => name2 !== BASE_R4).map(([name2, version2]) => {
|
|
1555
1555
|
if (!EXACT_VERSION.test(version2)) {
|
|
1556
1556
|
throw new Failure(
|
|
1557
1557
|
"inexact-dependency",
|
|
@@ -1570,8 +1570,8 @@ async function download(name2, version2, fetch) {
|
|
|
1570
1570
|
if (!response.ok) throw new Failure("registry-error", `${url} returned ${response.status}.`);
|
|
1571
1571
|
return response;
|
|
1572
1572
|
};
|
|
1573
|
-
const
|
|
1574
|
-
const dist =
|
|
1573
|
+
const manifest2 = await (await get(`${REGISTRY}/${name2}`)).json();
|
|
1574
|
+
const dist = manifest2.versions?.[version2]?.dist;
|
|
1575
1575
|
if (!dist?.tarball || !dist.shasum) {
|
|
1576
1576
|
throw new Failure("registry-error", `The registry has no ${id}.`);
|
|
1577
1577
|
}
|
|
@@ -1862,20 +1862,31 @@ async function checkType(medplum, saved, options, botId, input, onCore) {
|
|
|
1862
1862
|
await options.onPage?.(resourceType, saved.pages);
|
|
1863
1863
|
} while (!type.done);
|
|
1864
1864
|
}
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1865
|
+
var NOT_READY = /currently in the following state: Pending|An update is in progress for resource/;
|
|
1866
|
+
var READY_WAIT_MS = 2e3;
|
|
1867
|
+
var READY_TIMEOUT_MS = 6e4;
|
|
1868
|
+
async function runPage(medplum, botId, input, wait = (ms3) => new Promise((resolve4) => setTimeout(resolve4, ms3))) {
|
|
1869
|
+
for (let waited = 0; ; waited += READY_WAIT_MS) {
|
|
1870
|
+
const job = await medplum.post(
|
|
1871
|
+
medplum.fhirUrl("Bot", botId, "$execute"),
|
|
1872
|
+
input,
|
|
1873
|
+
ContentType.JSON,
|
|
1874
|
+
{ headers: { Prefer: "respond-async" }, pollStatusOnAccepted: true }
|
|
1875
|
+
);
|
|
1876
|
+
const output = job.output?.parameter ?? [];
|
|
1877
|
+
const body = output.find((p) => p.name === "responseBody")?.valueString;
|
|
1878
|
+
if (job.status === "completed" && body !== void 0) return JSON.parse(body);
|
|
1879
|
+
const reason = normalizeErrorString2(output.find((p) => p.resource)?.resource);
|
|
1880
|
+
if (!NOT_READY.test(reason)) {
|
|
1881
|
+
throw new Error(`The checker's job ended ${job.status}: ${reason}`);
|
|
1882
|
+
}
|
|
1883
|
+
if (waited >= READY_TIMEOUT_MS) {
|
|
1884
|
+
throw new Error(
|
|
1885
|
+
`The checker bot is still not ready after ${READY_TIMEOUT_MS / 1e3}s: ${reason}`
|
|
1886
|
+
);
|
|
1887
|
+
}
|
|
1888
|
+
await wait(READY_WAIT_MS);
|
|
1877
1889
|
}
|
|
1878
|
-
return JSON.parse(body);
|
|
1879
1890
|
}
|
|
1880
1891
|
function merge(saved, type, page) {
|
|
1881
1892
|
type.read += page.read;
|
|
@@ -3588,23 +3599,23 @@ function buildFsh(project, options = {}) {
|
|
|
3588
3599
|
return { ok: errors.length === 0, counts, warnings: messages.warn, errors };
|
|
3589
3600
|
}
|
|
3590
3601
|
function findSushi(project) {
|
|
3591
|
-
let
|
|
3602
|
+
let manifest2;
|
|
3592
3603
|
try {
|
|
3593
|
-
|
|
3604
|
+
manifest2 = createRequire(join6(project, "package.json")).resolve("fsh-sushi/package.json");
|
|
3594
3605
|
} catch {
|
|
3595
3606
|
return {
|
|
3596
3607
|
code: "sushi-not-installed",
|
|
3597
3608
|
message: `"fsh" needs SUSHI, and none is installed for ${project}. Run npm install --save-dev fsh-sushi.`
|
|
3598
3609
|
};
|
|
3599
3610
|
}
|
|
3600
|
-
const pkg = JSON.parse(readFileSync5(
|
|
3611
|
+
const pkg = JSON.parse(readFileSync5(manifest2, "utf8"));
|
|
3601
3612
|
if (Number.parseInt(pkg.version, 10) < OLDEST) {
|
|
3602
3613
|
return {
|
|
3603
3614
|
code: "sushi-too-old",
|
|
3604
3615
|
message: `"fsh" needs SUSHI ${OLDEST} or later; ${pkg.version} is installed. Run npm install --save-dev fsh-sushi@latest.`
|
|
3605
3616
|
};
|
|
3606
3617
|
}
|
|
3607
|
-
return { bin: join6(dirname4(
|
|
3618
|
+
return { bin: join6(dirname4(manifest2), typeof pkg.bin === "string" ? pkg.bin : pkg.bin.sushi) };
|
|
3608
3619
|
}
|
|
3609
3620
|
function parseLog(text) {
|
|
3610
3621
|
const messages = [];
|
|
@@ -4034,12 +4045,18 @@ var PROBLEMS = 1;
|
|
|
4034
4045
|
var USAGE_ERROR = 2;
|
|
4035
4046
|
function packageDir() {
|
|
4036
4047
|
let dir = dirname5(fileURLToPath(import.meta.url));
|
|
4037
|
-
while (
|
|
4048
|
+
while (manifest(dir)?.name !== "plumb-fhir") {
|
|
4049
|
+
if (dir === dirname5(dir)) throw new Error("plumb: cannot find the plumb-fhir package.json.");
|
|
4050
|
+
dir = dirname5(dir);
|
|
4051
|
+
}
|
|
4038
4052
|
return dir;
|
|
4039
4053
|
}
|
|
4054
|
+
function manifest(dir) {
|
|
4055
|
+
const file = join8(dir, "package.json");
|
|
4056
|
+
return existsSync6(file) ? JSON.parse(readFileSync6(file, "utf8")) : void 0;
|
|
4057
|
+
}
|
|
4040
4058
|
function version() {
|
|
4041
|
-
|
|
4042
|
-
return JSON.parse(readFileSync6(file, "utf8")).version;
|
|
4059
|
+
return manifest(packageDir())?.version ?? "";
|
|
4043
4060
|
}
|
|
4044
4061
|
var time = (ms3) => ms3 < 1e3 ? `${ms3}ms` : `${(ms3 / 1e3).toFixed(1)}s`;
|
|
4045
4062
|
function formatStep(step, out) {
|