@eudiplo/cli 8.1.0-main.7e6a44b → 8.1.0-main.8f6abca
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 +4 -4
- package/dist/commands/upgrade/action.d.ts.map +1 -1
- package/dist/commands/upgrade/action.js +3 -1
- package/dist/commands/upgrade/action.js.map +1 -1
- package/dist/index.js +999 -221
- package/dist/services/compose-project.js +2 -2
- package/dist/services/compose-project.js.map +1 -1
- package/dist/services/compose-upgrade.d.ts +8 -5
- package/dist/services/compose-upgrade.d.ts.map +1 -1
- package/dist/services/compose-upgrade.js +36 -11
- package/dist/services/compose-upgrade.js.map +1 -1
- package/package.json +5 -5
- package/templates/docker-compose.yml +3 -3
- package/templates/schemas/DCQL.schema.json +30 -4
- package/templates/schemas/PresentationConfigCreateDto.schema.json +30 -4
- package/templates/schemas/PresentationConfigFile.schema.json +720 -1
package/dist/index.js
CHANGED
|
@@ -14907,7 +14907,7 @@ var CONFIG_FORMATS = {
|
|
|
14907
14907
|
PresentationConfig: {
|
|
14908
14908
|
slug: "presentation-config",
|
|
14909
14909
|
file: "PresentationConfigFile",
|
|
14910
|
-
version:
|
|
14910
|
+
version: 3
|
|
14911
14911
|
},
|
|
14912
14912
|
AttributeProvider: {
|
|
14913
14913
|
slug: "attribute-provider",
|
|
@@ -14980,7 +14980,18 @@ var CONFIG_MIGRATIONS = [
|
|
|
14980
14980
|
// valid v2 spec whose offers keep having no lifetime.
|
|
14981
14981
|
migrate: (spec) => ({ spec })
|
|
14982
14982
|
},
|
|
14983
|
-
presentationConfigV1ToV2
|
|
14983
|
+
presentationConfigV1ToV2,
|
|
14984
|
+
{
|
|
14985
|
+
id: "presentation-config-v3-typed-claim-values",
|
|
14986
|
+
kind: "PresentationConfig",
|
|
14987
|
+
from: 2,
|
|
14988
|
+
to: 3,
|
|
14989
|
+
// v3 accepts integer and boolean DCQL claim `values` besides strings
|
|
14990
|
+
// and requires them to be non-empty. A v2 spec with non-empty string
|
|
14991
|
+
// values is a valid v3 spec; an empty `values` array fails v3
|
|
14992
|
+
// validation, since it could never match a disclosed claim.
|
|
14993
|
+
migrate: (spec) => ({ spec })
|
|
14994
|
+
}
|
|
14984
14995
|
];
|
|
14985
14996
|
function schemaUrl(kind, version = CONFIG_FORMATS[kind].version) {
|
|
14986
14997
|
if (!Number.isSafeInteger(version) || version < 1)
|
|
@@ -21440,212 +21451,957 @@ var CONFIG_SCHEMAS = [
|
|
|
21440
21451
|
"title": "PresentationConfigCreateDto"
|
|
21441
21452
|
}
|
|
21442
21453
|
}
|
|
21443
|
-
}
|
|
21444
|
-
|
|
21445
|
-
|
|
21446
|
-
|
|
21447
|
-
|
|
21448
|
-
|
|
21449
|
-
|
|
21450
|
-
|
|
21451
|
-
|
|
21452
|
-
|
|
21453
|
-
|
|
21454
|
-
|
|
21455
|
-
|
|
21456
|
-
|
|
21457
|
-
|
|
21458
|
-
|
|
21459
|
-
|
|
21460
|
-
|
|
21461
|
-
|
|
21462
|
-
|
|
21463
|
-
|
|
21464
|
-
|
|
21465
|
-
|
|
21466
|
-
|
|
21467
|
-
|
|
21468
|
-
|
|
21469
|
-
|
|
21470
|
-
|
|
21471
|
-
|
|
21472
|
-
|
|
21473
|
-
|
|
21474
|
-
|
|
21475
|
-
|
|
21476
|
-
|
|
21477
|
-
|
|
21478
|
-
|
|
21479
|
-
|
|
21480
|
-
|
|
21481
|
-
|
|
21482
|
-
|
|
21483
|
-
|
|
21484
|
-
|
|
21485
|
-
|
|
21486
|
-
|
|
21487
|
-
|
|
21488
|
-
|
|
21489
|
-
|
|
21490
|
-
|
|
21491
|
-
|
|
21492
|
-
} catch {
|
|
21493
|
-
throw new Error(`Invalid JSON in ${path2}`);
|
|
21494
|
-
}
|
|
21495
|
-
}
|
|
21496
|
-
function upgradeJson(input, file, context) {
|
|
21497
|
-
const bundle = Array.isArray(input?.documents);
|
|
21498
|
-
if (bundle) assertConfigBundle(input);
|
|
21499
|
-
const results = (bundle ? input.documents : [input]).map(
|
|
21500
|
-
(document) => upgradeDocument(document)
|
|
21501
|
-
);
|
|
21502
|
-
let blocked = false;
|
|
21503
|
-
for (const result of results) {
|
|
21504
|
-
for (const issue of result.issues) {
|
|
21505
|
-
context.stderr.write(
|
|
21506
|
-
`${file}${issue.path}: ${issue.severity} ${issue.code}: ${issue.message}
|
|
21507
|
-
`
|
|
21508
|
-
);
|
|
21509
|
-
if (issue.severity !== "warning") blocked = true;
|
|
21510
|
-
}
|
|
21511
|
-
for (const migration of result.migrations)
|
|
21512
|
-
context.stdout.write(`${file}: migration ${migration}
|
|
21513
|
-
`);
|
|
21514
|
-
}
|
|
21515
|
-
if (blocked) throw new Error(`${file}: upgrade blocked; no output written`);
|
|
21516
|
-
if (!bundle) return results[0].document;
|
|
21517
|
-
const documents = results.map(
|
|
21518
|
-
(result) => result.document
|
|
21519
|
-
);
|
|
21520
|
-
const resources = input.manifest.resources.map(
|
|
21521
|
-
(resource) => {
|
|
21522
|
-
const index = input.documents.findIndex(
|
|
21523
|
-
(candidate) => normalizeDocument(candidate).kind === resource.kind && resourceId(candidate) === resource.id
|
|
21524
|
-
);
|
|
21525
|
-
const document = documents[index];
|
|
21526
|
-
return {
|
|
21527
|
-
...resource,
|
|
21528
|
-
id: resourceId(document),
|
|
21529
|
-
$schema: document.$schema,
|
|
21530
|
-
sha256: createHash2("sha256").update(JSON.stringify(document)).digest("hex")
|
|
21531
|
-
};
|
|
21532
|
-
}
|
|
21533
|
-
);
|
|
21534
|
-
const output = {
|
|
21535
|
-
...input,
|
|
21536
|
-
manifest: { ...input.manifest, formatVersion: 2, resources },
|
|
21537
|
-
documents
|
|
21538
|
-
};
|
|
21539
|
-
assertConfigBundle(output);
|
|
21540
|
-
return output;
|
|
21541
|
-
}
|
|
21542
|
-
function report(input, output, file, parsed, context) {
|
|
21543
|
-
const changed = stableConfigJson(input) !== stableConfigJson(output);
|
|
21544
|
-
context.stdout.write(
|
|
21545
|
-
`${file}: ${changed ? "upgrade required" : "current"}
|
|
21546
|
-
`
|
|
21547
|
-
);
|
|
21548
|
-
if (parsed.flags.diff === true)
|
|
21549
|
-
for (const change of configChanges(input, output)) {
|
|
21550
|
-
context.stdout.write(
|
|
21551
|
-
` ${change.path}: ${JSON.stringify(change.before) ?? "(absent)"} -> ${JSON.stringify(change.after) ?? "(absent)"}
|
|
21552
|
-
`
|
|
21553
|
-
);
|
|
21554
|
-
}
|
|
21555
|
-
return changed;
|
|
21556
|
-
}
|
|
21557
|
-
function inferredKind(path2) {
|
|
21558
|
-
const normalized = path2.split(sep2).join("/");
|
|
21559
|
-
const match = TENANT_RESOURCE_REGISTRY.find(
|
|
21560
|
-
(entry) => entry.kind === "file" ? normalized === entry.file || normalized.endsWith(`/${entry.file}`) : normalized.endsWith(`/${entry.subfolder}/${basename2(path2)}`) || normalized === `${entry.subfolder}/${basename2(path2)}`
|
|
21561
|
-
);
|
|
21562
|
-
return CONFIG_RESOURCE_KINDS.find(
|
|
21563
|
-
(kind) => `${CONFIG_FORMATS[kind].file}.schema.json` === match?.schemaFile
|
|
21564
|
-
);
|
|
21565
|
-
}
|
|
21566
|
-
function wrapBare(kind, input, path2) {
|
|
21567
|
-
if (!input || typeof input !== "object" || Array.isArray(input))
|
|
21568
|
-
throw new Error(`${path2}: configuration must be an object`);
|
|
21569
|
-
const singleton = {
|
|
21570
|
-
Tenant: "tenant",
|
|
21571
|
-
KmsConfig: "kms",
|
|
21572
|
-
RegistrarConfig: "registrar",
|
|
21573
|
-
IssuanceConfig: "issuance"
|
|
21574
|
-
};
|
|
21575
|
-
const spec = structuredClone(input);
|
|
21576
|
-
if (kind === "KeyChain" && spec.key && !spec.keySource) {
|
|
21577
|
-
spec.keySource = { type: "private-jwk", jwk: spec.key };
|
|
21578
|
-
delete spec.key;
|
|
21579
|
-
}
|
|
21580
|
-
const id = String(
|
|
21581
|
-
singleton[kind] ?? spec.id ?? spec.clientId ?? basename2(path2, ".json")
|
|
21582
|
-
);
|
|
21583
|
-
if (!singleton[kind]) spec[kind === "Client" ? "clientId" : "id"] = id;
|
|
21584
|
-
return { $schema: schemaUrl(kind, 1), metadata: { generation: 1 }, spec };
|
|
21585
|
-
}
|
|
21586
|
-
async function folderFiles(path2) {
|
|
21587
|
-
const files = [];
|
|
21588
|
-
for (const entry of await readdir(path2, { withFileTypes: true })) {
|
|
21589
|
-
if (entry.name.startsWith(".")) continue;
|
|
21590
|
-
const file = join4(path2, entry.name);
|
|
21591
|
-
if (entry.isSymbolicLink())
|
|
21592
|
-
throw new Error(`Config folder contains a symbolic link: ${file}`);
|
|
21593
|
-
if (entry.isDirectory()) files.push(...await folderFiles(file));
|
|
21594
|
-
else if (entry.isFile()) files.push(file);
|
|
21595
|
-
}
|
|
21596
|
-
return files.sort();
|
|
21597
|
-
}
|
|
21598
|
-
async function upgradeFolder(source, parsed, context) {
|
|
21599
|
-
const outputs = /* @__PURE__ */ new Map();
|
|
21600
|
-
let changed = 0;
|
|
21601
|
-
for (const file of await folderFiles(source)) {
|
|
21602
|
-
if (extname(file) !== ".json" || relative2(source, file).split(sep2).includes("images"))
|
|
21603
|
-
continue;
|
|
21604
|
-
const input = parse3(await readFile4(file, "utf8"), file);
|
|
21605
|
-
const kind = inferredKind(relative2(source, file));
|
|
21606
|
-
if (!kind && !isConfigDocument(input)) continue;
|
|
21607
|
-
const candidate = isConfigDocument(input) ? input : wrapBare(kind, input, file);
|
|
21608
|
-
const output = upgradeJson(candidate, file, context);
|
|
21609
|
-
if (kind && normalizeDocument(output).kind !== kind)
|
|
21610
|
-
throw new Error(`${file}: expected ${kind} configuration`);
|
|
21611
|
-
if (report(input, output, relative2(source, file), parsed, context))
|
|
21612
|
-
changed++;
|
|
21613
|
-
outputs.set(
|
|
21614
|
-
relative2(source, file),
|
|
21615
|
-
`${JSON.stringify(output, null, 2)}
|
|
21616
|
-
`
|
|
21617
|
-
);
|
|
21618
|
-
}
|
|
21619
|
-
if (!outputs.size)
|
|
21620
|
-
throw new Error(`No configuration documents found in ${source}`);
|
|
21621
|
-
context.stdout.write(
|
|
21622
|
-
`${outputs.size - changed} current, ${changed} require upgrading
|
|
21623
|
-
`
|
|
21624
|
-
);
|
|
21625
|
-
if (parsed.flags.check === true) return changed ? 1 : 0;
|
|
21626
|
-
if (parsed.flags["dry-run"] === true) return 0;
|
|
21627
|
-
const destination = resolve3(
|
|
21628
|
-
context.cwd,
|
|
21629
|
-
readStringFlag(parsed.flags, "output") ?? `${source}.upgraded`
|
|
21630
|
-
);
|
|
21631
|
-
const overlap = (parent, child) => {
|
|
21632
|
-
const path2 = relative2(parent, child);
|
|
21633
|
-
return path2 === "" || !path2.startsWith(`..${sep2}`) && path2 !== "..";
|
|
21634
|
-
};
|
|
21635
|
-
if (overlap(source, destination) || overlap(destination, source))
|
|
21636
|
-
throw new Error(
|
|
21637
|
-
"Folder output must be separate from the source directory"
|
|
21638
|
-
);
|
|
21639
|
-
await lstat(destination).then(
|
|
21640
|
-
() => {
|
|
21641
|
-
throw new Error(`Output already exists: ${destination}`);
|
|
21454
|
+
},
|
|
21455
|
+
{
|
|
21456
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
21457
|
+
"$id": "https://eudiplo.dev/schemas/v3/PresentationConfigFile.schema.json",
|
|
21458
|
+
"title": "PresentationConfigFile",
|
|
21459
|
+
"type": "object",
|
|
21460
|
+
"properties": {
|
|
21461
|
+
"$schema": {
|
|
21462
|
+
"type": "string",
|
|
21463
|
+
"const": "https://eudiplo.dev/schemas/v3/PresentationConfigFile.schema.json"
|
|
21464
|
+
},
|
|
21465
|
+
"metadata": {
|
|
21466
|
+
"type": "object",
|
|
21467
|
+
"properties": {
|
|
21468
|
+
"generation": {
|
|
21469
|
+
"type": "integer",
|
|
21470
|
+
"minimum": 1,
|
|
21471
|
+
"description": "Monotonically increasing configuration generation."
|
|
21472
|
+
},
|
|
21473
|
+
"ownership": {
|
|
21474
|
+
"type": "string",
|
|
21475
|
+
"enum": [
|
|
21476
|
+
"unmanaged",
|
|
21477
|
+
"file-managed"
|
|
21478
|
+
],
|
|
21479
|
+
"description": "Requested ownership recorded when the document is applied."
|
|
21480
|
+
}
|
|
21481
|
+
},
|
|
21482
|
+
"additionalProperties": false
|
|
21483
|
+
},
|
|
21484
|
+
"spec": {
|
|
21485
|
+
"allOf": [
|
|
21486
|
+
{
|
|
21487
|
+
"$ref": "#/$defs/PresentationConfigCreateDto"
|
|
21488
|
+
},
|
|
21489
|
+
{
|
|
21490
|
+
"type": "object",
|
|
21491
|
+
"required": [
|
|
21492
|
+
"id"
|
|
21493
|
+
],
|
|
21494
|
+
"properties": {
|
|
21495
|
+
"id": {
|
|
21496
|
+
"type": "string",
|
|
21497
|
+
"minLength": 1
|
|
21498
|
+
}
|
|
21499
|
+
}
|
|
21500
|
+
}
|
|
21501
|
+
]
|
|
21502
|
+
}
|
|
21642
21503
|
},
|
|
21643
|
-
|
|
21644
|
-
|
|
21645
|
-
|
|
21646
|
-
|
|
21647
|
-
|
|
21648
|
-
|
|
21504
|
+
"required": [
|
|
21505
|
+
"$schema",
|
|
21506
|
+
"spec"
|
|
21507
|
+
],
|
|
21508
|
+
"additionalProperties": false,
|
|
21509
|
+
"$defs": {
|
|
21510
|
+
"PresentationConfigCreateDto": {
|
|
21511
|
+
"type": "object",
|
|
21512
|
+
"properties": {
|
|
21513
|
+
"id": {
|
|
21514
|
+
"type": "string",
|
|
21515
|
+
"minLength": 1,
|
|
21516
|
+
"description": "Presentation configuration identifier."
|
|
21517
|
+
},
|
|
21518
|
+
"description": {
|
|
21519
|
+
"description": "Optional presentation configuration description.",
|
|
21520
|
+
"type": [
|
|
21521
|
+
"string",
|
|
21522
|
+
"null"
|
|
21523
|
+
]
|
|
21524
|
+
},
|
|
21525
|
+
"lifeTime": {
|
|
21526
|
+
"description": "Presentation request lifetime in seconds.",
|
|
21527
|
+
"type": "integer",
|
|
21528
|
+
"minimum": 1,
|
|
21529
|
+
"maximum": 9007199254740991
|
|
21530
|
+
},
|
|
21531
|
+
"skewSeconds": {
|
|
21532
|
+
"description": "Clock skew tolerance in seconds.",
|
|
21533
|
+
"type": "integer",
|
|
21534
|
+
"minimum": 0,
|
|
21535
|
+
"maximum": 9007199254740991
|
|
21536
|
+
},
|
|
21537
|
+
"statusCheckMode": {
|
|
21538
|
+
"description": "Revocation/status check mode.",
|
|
21539
|
+
"type": "string",
|
|
21540
|
+
"enum": [
|
|
21541
|
+
"strict",
|
|
21542
|
+
"best_effort",
|
|
21543
|
+
"disabled"
|
|
21544
|
+
]
|
|
21545
|
+
},
|
|
21546
|
+
"dcql_query": {
|
|
21547
|
+
"type": "object",
|
|
21548
|
+
"properties": {
|
|
21549
|
+
"credentials": {
|
|
21550
|
+
"minItems": 1,
|
|
21551
|
+
"type": "array",
|
|
21552
|
+
"items": {
|
|
21553
|
+
"oneOf": [
|
|
21554
|
+
{
|
|
21555
|
+
"type": "object",
|
|
21556
|
+
"properties": {
|
|
21557
|
+
"id": {
|
|
21558
|
+
"type": "string",
|
|
21559
|
+
"minLength": 1,
|
|
21560
|
+
"pattern": "^[A-Za-z0-9_-]+$",
|
|
21561
|
+
"description": "Credential query identifier."
|
|
21562
|
+
},
|
|
21563
|
+
"multiple": {
|
|
21564
|
+
"description": "Allow multiple matching credentials.",
|
|
21565
|
+
"type": "boolean"
|
|
21566
|
+
},
|
|
21567
|
+
"claim_sets": {
|
|
21568
|
+
"description": "Optional claim set constraints.",
|
|
21569
|
+
"type": "array",
|
|
21570
|
+
"items": {
|
|
21571
|
+
"type": "array",
|
|
21572
|
+
"items": {
|
|
21573
|
+
"type": "string"
|
|
21574
|
+
}
|
|
21575
|
+
}
|
|
21576
|
+
},
|
|
21577
|
+
"trusted_authorities": {
|
|
21578
|
+
"description": "Optional trusted authority constraints.",
|
|
21579
|
+
"type": "array",
|
|
21580
|
+
"items": {
|
|
21581
|
+
"oneOf": [
|
|
21582
|
+
{
|
|
21583
|
+
"type": "object",
|
|
21584
|
+
"properties": {
|
|
21585
|
+
"type": {
|
|
21586
|
+
"type": "string",
|
|
21587
|
+
"const": "etsi_tl",
|
|
21588
|
+
"description": "Trusted authority type discriminator for ETSI trust lists."
|
|
21589
|
+
},
|
|
21590
|
+
"values": {
|
|
21591
|
+
"type": "array",
|
|
21592
|
+
"items": {
|
|
21593
|
+
"type": "object",
|
|
21594
|
+
"properties": {
|
|
21595
|
+
"trustListId": {
|
|
21596
|
+
"description": "Optional trust list id reference.",
|
|
21597
|
+
"type": "string"
|
|
21598
|
+
},
|
|
21599
|
+
"url": {
|
|
21600
|
+
"description": "Optional trust list URL reference.",
|
|
21601
|
+
"anyOf": [
|
|
21602
|
+
{
|
|
21603
|
+
"type": "string",
|
|
21604
|
+
"format": "uri"
|
|
21605
|
+
},
|
|
21606
|
+
{
|
|
21607
|
+
"type": "string",
|
|
21608
|
+
"pattern": "^<TENANT_URL>(?:\\/.*)?$"
|
|
21609
|
+
}
|
|
21610
|
+
]
|
|
21611
|
+
},
|
|
21612
|
+
"verifierKey": {
|
|
21613
|
+
"description": "Optional verifier key material.",
|
|
21614
|
+
"type": "object",
|
|
21615
|
+
"propertyNames": {
|
|
21616
|
+
"type": "string"
|
|
21617
|
+
},
|
|
21618
|
+
"additionalProperties": {}
|
|
21619
|
+
},
|
|
21620
|
+
"verifierX509Der": {
|
|
21621
|
+
"description": "Optional verifier certificate in DER/base64 form.",
|
|
21622
|
+
"type": "string"
|
|
21623
|
+
}
|
|
21624
|
+
},
|
|
21625
|
+
"additionalProperties": false
|
|
21626
|
+
},
|
|
21627
|
+
"description": "Trust list references for ETSI TL verification."
|
|
21628
|
+
}
|
|
21629
|
+
},
|
|
21630
|
+
"required": [
|
|
21631
|
+
"type",
|
|
21632
|
+
"values"
|
|
21633
|
+
],
|
|
21634
|
+
"additionalProperties": false
|
|
21635
|
+
},
|
|
21636
|
+
{
|
|
21637
|
+
"type": "object",
|
|
21638
|
+
"properties": {
|
|
21639
|
+
"type": {
|
|
21640
|
+
"type": "string",
|
|
21641
|
+
"const": "openid_federation",
|
|
21642
|
+
"description": "Trusted authority type discriminator for OpenID Federation."
|
|
21643
|
+
},
|
|
21644
|
+
"values": {
|
|
21645
|
+
"type": "array",
|
|
21646
|
+
"items": {
|
|
21647
|
+
"type": "string"
|
|
21648
|
+
},
|
|
21649
|
+
"description": "OpenID Federation authority identifiers."
|
|
21650
|
+
}
|
|
21651
|
+
},
|
|
21652
|
+
"required": [
|
|
21653
|
+
"type",
|
|
21654
|
+
"values"
|
|
21655
|
+
],
|
|
21656
|
+
"additionalProperties": false
|
|
21657
|
+
}
|
|
21658
|
+
]
|
|
21659
|
+
}
|
|
21660
|
+
},
|
|
21661
|
+
"format": {
|
|
21662
|
+
"type": "string",
|
|
21663
|
+
"const": "dc+sd-jwt",
|
|
21664
|
+
"description": "Credential format discriminator."
|
|
21665
|
+
},
|
|
21666
|
+
"meta": {
|
|
21667
|
+
"type": "object",
|
|
21668
|
+
"properties": {
|
|
21669
|
+
"vct_values": {
|
|
21670
|
+
"minItems": 1,
|
|
21671
|
+
"type": "array",
|
|
21672
|
+
"items": {
|
|
21673
|
+
"type": "string"
|
|
21674
|
+
},
|
|
21675
|
+
"description": "Accepted VCT values."
|
|
21676
|
+
}
|
|
21677
|
+
},
|
|
21678
|
+
"required": [
|
|
21679
|
+
"vct_values"
|
|
21680
|
+
],
|
|
21681
|
+
"additionalProperties": false
|
|
21682
|
+
},
|
|
21683
|
+
"claims": {
|
|
21684
|
+
"description": "Optional claim-level constraints.",
|
|
21685
|
+
"type": "array",
|
|
21686
|
+
"items": {
|
|
21687
|
+
"type": "object",
|
|
21688
|
+
"properties": {
|
|
21689
|
+
"id": {
|
|
21690
|
+
"description": "Optional claim query id.",
|
|
21691
|
+
"type": "string"
|
|
21692
|
+
},
|
|
21693
|
+
"path": {
|
|
21694
|
+
"type": "array",
|
|
21695
|
+
"items": {
|
|
21696
|
+
"type": [
|
|
21697
|
+
"string",
|
|
21698
|
+
"number"
|
|
21699
|
+
]
|
|
21700
|
+
},
|
|
21701
|
+
"description": "Path to the claim value in presented credentials."
|
|
21702
|
+
},
|
|
21703
|
+
"values": {
|
|
21704
|
+
"description": "Optional allowed values for the claim. A disclosed value must equal one of them in type and value.",
|
|
21705
|
+
"minItems": 1,
|
|
21706
|
+
"type": "array",
|
|
21707
|
+
"items": {
|
|
21708
|
+
"anyOf": [
|
|
21709
|
+
{
|
|
21710
|
+
"type": "string"
|
|
21711
|
+
},
|
|
21712
|
+
{
|
|
21713
|
+
"type": "integer",
|
|
21714
|
+
"minimum": -9007199254740991,
|
|
21715
|
+
"maximum": 9007199254740991
|
|
21716
|
+
},
|
|
21717
|
+
{
|
|
21718
|
+
"type": "boolean"
|
|
21719
|
+
}
|
|
21720
|
+
]
|
|
21721
|
+
}
|
|
21722
|
+
}
|
|
21723
|
+
},
|
|
21724
|
+
"required": [
|
|
21725
|
+
"path"
|
|
21726
|
+
],
|
|
21727
|
+
"additionalProperties": false
|
|
21728
|
+
}
|
|
21729
|
+
}
|
|
21730
|
+
},
|
|
21731
|
+
"required": [
|
|
21732
|
+
"id",
|
|
21733
|
+
"format",
|
|
21734
|
+
"meta"
|
|
21735
|
+
],
|
|
21736
|
+
"additionalProperties": false
|
|
21737
|
+
},
|
|
21738
|
+
{
|
|
21739
|
+
"type": "object",
|
|
21740
|
+
"properties": {
|
|
21741
|
+
"id": {
|
|
21742
|
+
"type": "string",
|
|
21743
|
+
"minLength": 1,
|
|
21744
|
+
"pattern": "^[A-Za-z0-9_-]+$",
|
|
21745
|
+
"description": "Credential query identifier."
|
|
21746
|
+
},
|
|
21747
|
+
"multiple": {
|
|
21748
|
+
"description": "Allow multiple matching credentials.",
|
|
21749
|
+
"type": "boolean"
|
|
21750
|
+
},
|
|
21751
|
+
"claim_sets": {
|
|
21752
|
+
"description": "Optional claim set constraints.",
|
|
21753
|
+
"type": "array",
|
|
21754
|
+
"items": {
|
|
21755
|
+
"type": "array",
|
|
21756
|
+
"items": {
|
|
21757
|
+
"type": "string"
|
|
21758
|
+
}
|
|
21759
|
+
}
|
|
21760
|
+
},
|
|
21761
|
+
"trusted_authorities": {
|
|
21762
|
+
"description": "Optional trusted authority constraints.",
|
|
21763
|
+
"type": "array",
|
|
21764
|
+
"items": {
|
|
21765
|
+
"oneOf": [
|
|
21766
|
+
{
|
|
21767
|
+
"type": "object",
|
|
21768
|
+
"properties": {
|
|
21769
|
+
"type": {
|
|
21770
|
+
"type": "string",
|
|
21771
|
+
"const": "etsi_tl",
|
|
21772
|
+
"description": "Trusted authority type discriminator for ETSI trust lists."
|
|
21773
|
+
},
|
|
21774
|
+
"values": {
|
|
21775
|
+
"type": "array",
|
|
21776
|
+
"items": {
|
|
21777
|
+
"type": "object",
|
|
21778
|
+
"properties": {
|
|
21779
|
+
"trustListId": {
|
|
21780
|
+
"description": "Optional trust list id reference.",
|
|
21781
|
+
"type": "string"
|
|
21782
|
+
},
|
|
21783
|
+
"url": {
|
|
21784
|
+
"description": "Optional trust list URL reference.",
|
|
21785
|
+
"anyOf": [
|
|
21786
|
+
{
|
|
21787
|
+
"type": "string",
|
|
21788
|
+
"format": "uri"
|
|
21789
|
+
},
|
|
21790
|
+
{
|
|
21791
|
+
"type": "string",
|
|
21792
|
+
"pattern": "^<TENANT_URL>(?:\\/.*)?$"
|
|
21793
|
+
}
|
|
21794
|
+
]
|
|
21795
|
+
},
|
|
21796
|
+
"verifierKey": {
|
|
21797
|
+
"description": "Optional verifier key material.",
|
|
21798
|
+
"type": "object",
|
|
21799
|
+
"propertyNames": {
|
|
21800
|
+
"type": "string"
|
|
21801
|
+
},
|
|
21802
|
+
"additionalProperties": {}
|
|
21803
|
+
},
|
|
21804
|
+
"verifierX509Der": {
|
|
21805
|
+
"description": "Optional verifier certificate in DER/base64 form.",
|
|
21806
|
+
"type": "string"
|
|
21807
|
+
}
|
|
21808
|
+
},
|
|
21809
|
+
"additionalProperties": false
|
|
21810
|
+
},
|
|
21811
|
+
"description": "Trust list references for ETSI TL verification."
|
|
21812
|
+
}
|
|
21813
|
+
},
|
|
21814
|
+
"required": [
|
|
21815
|
+
"type",
|
|
21816
|
+
"values"
|
|
21817
|
+
],
|
|
21818
|
+
"additionalProperties": false
|
|
21819
|
+
},
|
|
21820
|
+
{
|
|
21821
|
+
"type": "object",
|
|
21822
|
+
"properties": {
|
|
21823
|
+
"type": {
|
|
21824
|
+
"type": "string",
|
|
21825
|
+
"const": "openid_federation",
|
|
21826
|
+
"description": "Trusted authority type discriminator for OpenID Federation."
|
|
21827
|
+
},
|
|
21828
|
+
"values": {
|
|
21829
|
+
"type": "array",
|
|
21830
|
+
"items": {
|
|
21831
|
+
"type": "string"
|
|
21832
|
+
},
|
|
21833
|
+
"description": "OpenID Federation authority identifiers."
|
|
21834
|
+
}
|
|
21835
|
+
},
|
|
21836
|
+
"required": [
|
|
21837
|
+
"type",
|
|
21838
|
+
"values"
|
|
21839
|
+
],
|
|
21840
|
+
"additionalProperties": false
|
|
21841
|
+
}
|
|
21842
|
+
]
|
|
21843
|
+
}
|
|
21844
|
+
},
|
|
21845
|
+
"format": {
|
|
21846
|
+
"type": "string",
|
|
21847
|
+
"const": "mso_mdoc",
|
|
21848
|
+
"description": "Credential format discriminator."
|
|
21849
|
+
},
|
|
21850
|
+
"meta": {
|
|
21851
|
+
"type": "object",
|
|
21852
|
+
"properties": {
|
|
21853
|
+
"doctype_value": {
|
|
21854
|
+
"type": "string",
|
|
21855
|
+
"minLength": 1,
|
|
21856
|
+
"description": "Expected mDoc doctype value."
|
|
21857
|
+
}
|
|
21858
|
+
},
|
|
21859
|
+
"required": [
|
|
21860
|
+
"doctype_value"
|
|
21861
|
+
],
|
|
21862
|
+
"additionalProperties": false
|
|
21863
|
+
},
|
|
21864
|
+
"claims": {
|
|
21865
|
+
"description": "Optional mDoc claim-level constraints.",
|
|
21866
|
+
"type": "array",
|
|
21867
|
+
"items": {
|
|
21868
|
+
"type": "object",
|
|
21869
|
+
"properties": {
|
|
21870
|
+
"id": {
|
|
21871
|
+
"description": "Optional claim query id.",
|
|
21872
|
+
"type": "string"
|
|
21873
|
+
},
|
|
21874
|
+
"path": {
|
|
21875
|
+
"type": "array",
|
|
21876
|
+
"items": {
|
|
21877
|
+
"type": [
|
|
21878
|
+
"string",
|
|
21879
|
+
"number"
|
|
21880
|
+
]
|
|
21881
|
+
},
|
|
21882
|
+
"description": "Path to the claim value in presented credentials."
|
|
21883
|
+
},
|
|
21884
|
+
"values": {
|
|
21885
|
+
"description": "Optional allowed values for the claim. A disclosed value must equal one of them in type and value.",
|
|
21886
|
+
"minItems": 1,
|
|
21887
|
+
"type": "array",
|
|
21888
|
+
"items": {
|
|
21889
|
+
"anyOf": [
|
|
21890
|
+
{
|
|
21891
|
+
"type": "string"
|
|
21892
|
+
},
|
|
21893
|
+
{
|
|
21894
|
+
"type": "integer",
|
|
21895
|
+
"minimum": -9007199254740991,
|
|
21896
|
+
"maximum": 9007199254740991
|
|
21897
|
+
},
|
|
21898
|
+
{
|
|
21899
|
+
"type": "boolean"
|
|
21900
|
+
}
|
|
21901
|
+
]
|
|
21902
|
+
}
|
|
21903
|
+
},
|
|
21904
|
+
"intent_to_retain": {
|
|
21905
|
+
"description": "Whether relying party intends to retain the claim.",
|
|
21906
|
+
"type": "boolean"
|
|
21907
|
+
}
|
|
21908
|
+
},
|
|
21909
|
+
"required": [
|
|
21910
|
+
"path"
|
|
21911
|
+
],
|
|
21912
|
+
"additionalProperties": false
|
|
21913
|
+
}
|
|
21914
|
+
}
|
|
21915
|
+
},
|
|
21916
|
+
"required": [
|
|
21917
|
+
"id",
|
|
21918
|
+
"format",
|
|
21919
|
+
"meta"
|
|
21920
|
+
],
|
|
21921
|
+
"additionalProperties": false
|
|
21922
|
+
}
|
|
21923
|
+
]
|
|
21924
|
+
},
|
|
21925
|
+
"description": "Credential queries requested by the verifier."
|
|
21926
|
+
},
|
|
21927
|
+
"credential_sets": {
|
|
21928
|
+
"description": "Optional higher-level credential set requirements.",
|
|
21929
|
+
"type": "array",
|
|
21930
|
+
"items": {
|
|
21931
|
+
"type": "object",
|
|
21932
|
+
"properties": {
|
|
21933
|
+
"options": {
|
|
21934
|
+
"minItems": 1,
|
|
21935
|
+
"type": "array",
|
|
21936
|
+
"items": {
|
|
21937
|
+
"minItems": 1,
|
|
21938
|
+
"type": "array",
|
|
21939
|
+
"items": {
|
|
21940
|
+
"type": "string"
|
|
21941
|
+
}
|
|
21942
|
+
},
|
|
21943
|
+
"description": "Alternative credential query id combinations."
|
|
21944
|
+
},
|
|
21945
|
+
"required": {
|
|
21946
|
+
"description": "Whether this credential set is mandatory.",
|
|
21947
|
+
"type": "boolean"
|
|
21948
|
+
}
|
|
21949
|
+
},
|
|
21950
|
+
"required": [
|
|
21951
|
+
"options"
|
|
21952
|
+
],
|
|
21953
|
+
"additionalProperties": false
|
|
21954
|
+
}
|
|
21955
|
+
}
|
|
21956
|
+
},
|
|
21957
|
+
"required": [
|
|
21958
|
+
"credentials"
|
|
21959
|
+
],
|
|
21960
|
+
"additionalProperties": false,
|
|
21961
|
+
"description": "DCQL query defining requested credentials and claims."
|
|
21962
|
+
},
|
|
21963
|
+
"transaction_data": {
|
|
21964
|
+
"description": "Optional transaction data descriptors.",
|
|
21965
|
+
"anyOf": [
|
|
21966
|
+
{
|
|
21967
|
+
"type": "array",
|
|
21968
|
+
"items": {
|
|
21969
|
+
"type": "object",
|
|
21970
|
+
"properties": {
|
|
21971
|
+
"type": {
|
|
21972
|
+
"type": "string",
|
|
21973
|
+
"description": "Transaction data type identifier."
|
|
21974
|
+
},
|
|
21975
|
+
"credential_ids": {
|
|
21976
|
+
"type": "array",
|
|
21977
|
+
"items": {
|
|
21978
|
+
"type": "string"
|
|
21979
|
+
},
|
|
21980
|
+
"description": "Credential query ids this transaction data applies to."
|
|
21981
|
+
},
|
|
21982
|
+
"payload": {
|
|
21983
|
+
"description": "Transaction details. Required for TS12 SCA transaction data."
|
|
21984
|
+
}
|
|
21985
|
+
},
|
|
21986
|
+
"required": [
|
|
21987
|
+
"type",
|
|
21988
|
+
"credential_ids"
|
|
21989
|
+
],
|
|
21990
|
+
"additionalProperties": {}
|
|
21991
|
+
}
|
|
21992
|
+
},
|
|
21993
|
+
{
|
|
21994
|
+
"type": "null"
|
|
21995
|
+
}
|
|
21996
|
+
]
|
|
21997
|
+
},
|
|
21998
|
+
"registration_cert": {
|
|
21999
|
+
"description": "Optional registration certificate request settings.",
|
|
22000
|
+
"anyOf": [
|
|
22001
|
+
{
|
|
22002
|
+
"type": "object",
|
|
22003
|
+
"properties": {
|
|
22004
|
+
"id": {
|
|
22005
|
+
"type": "string"
|
|
22006
|
+
},
|
|
22007
|
+
"body": {
|
|
22008
|
+
"type": "object",
|
|
22009
|
+
"properties": {
|
|
22010
|
+
"privacy_policy": {
|
|
22011
|
+
"type": "string"
|
|
22012
|
+
},
|
|
22013
|
+
"support_uri": {
|
|
22014
|
+
"type": "string"
|
|
22015
|
+
},
|
|
22016
|
+
"intermediary": {
|
|
22017
|
+
"type": "string"
|
|
22018
|
+
},
|
|
22019
|
+
"purpose": {
|
|
22020
|
+
"type": "array",
|
|
22021
|
+
"items": {
|
|
22022
|
+
"type": "object",
|
|
22023
|
+
"properties": {
|
|
22024
|
+
"lang": {
|
|
22025
|
+
"type": "string"
|
|
22026
|
+
},
|
|
22027
|
+
"content": {
|
|
22028
|
+
"type": "string"
|
|
22029
|
+
}
|
|
22030
|
+
},
|
|
22031
|
+
"required": [
|
|
22032
|
+
"lang",
|
|
22033
|
+
"content"
|
|
22034
|
+
],
|
|
22035
|
+
"additionalProperties": false
|
|
22036
|
+
}
|
|
22037
|
+
},
|
|
22038
|
+
"credentials": {
|
|
22039
|
+
"type": "array",
|
|
22040
|
+
"items": {
|
|
22041
|
+
"type": "object",
|
|
22042
|
+
"propertyNames": {
|
|
22043
|
+
"type": "string"
|
|
22044
|
+
},
|
|
22045
|
+
"additionalProperties": {}
|
|
22046
|
+
}
|
|
22047
|
+
},
|
|
22048
|
+
"provides_attestations": {
|
|
22049
|
+
"type": "array",
|
|
22050
|
+
"items": {
|
|
22051
|
+
"type": "string",
|
|
22052
|
+
"minLength": 1
|
|
22053
|
+
}
|
|
22054
|
+
}
|
|
22055
|
+
},
|
|
22056
|
+
"additionalProperties": false
|
|
22057
|
+
},
|
|
22058
|
+
"jwt": {
|
|
22059
|
+
"type": "string"
|
|
22060
|
+
}
|
|
22061
|
+
},
|
|
22062
|
+
"additionalProperties": false
|
|
22063
|
+
},
|
|
22064
|
+
{
|
|
22065
|
+
"type": "null"
|
|
22066
|
+
}
|
|
22067
|
+
]
|
|
22068
|
+
},
|
|
22069
|
+
"registrationCertImportJwt": {
|
|
22070
|
+
"description": "Optional imported registration certificate JWT.",
|
|
22071
|
+
"type": [
|
|
22072
|
+
"string",
|
|
22073
|
+
"null"
|
|
22074
|
+
]
|
|
22075
|
+
},
|
|
22076
|
+
"registrationCertImportId": {
|
|
22077
|
+
"description": "Optional registrar-side registration certificate id.",
|
|
22078
|
+
"type": [
|
|
22079
|
+
"string",
|
|
22080
|
+
"null"
|
|
22081
|
+
]
|
|
22082
|
+
},
|
|
22083
|
+
"registrationCertBodyPrivacyPolicy": {
|
|
22084
|
+
"description": "Optional registration certificate privacy policy URI.",
|
|
22085
|
+
"type": [
|
|
22086
|
+
"string",
|
|
22087
|
+
"null"
|
|
22088
|
+
]
|
|
22089
|
+
},
|
|
22090
|
+
"registrationCertBodySupportUri": {
|
|
22091
|
+
"description": "Optional registration certificate support URI.",
|
|
22092
|
+
"type": [
|
|
22093
|
+
"string",
|
|
22094
|
+
"null"
|
|
22095
|
+
]
|
|
22096
|
+
},
|
|
22097
|
+
"registrationCertBodyIntermediary": {
|
|
22098
|
+
"description": "Optional registration certificate intermediary.",
|
|
22099
|
+
"type": [
|
|
22100
|
+
"string",
|
|
22101
|
+
"null"
|
|
22102
|
+
]
|
|
22103
|
+
},
|
|
22104
|
+
"registrationCertBodyPurpose": {
|
|
22105
|
+
"description": "Optional registration certificate purpose entries.",
|
|
22106
|
+
"anyOf": [
|
|
22107
|
+
{
|
|
22108
|
+
"type": "array",
|
|
22109
|
+
"items": {
|
|
22110
|
+
"type": "object",
|
|
22111
|
+
"properties": {
|
|
22112
|
+
"lang": {
|
|
22113
|
+
"type": "string"
|
|
22114
|
+
},
|
|
22115
|
+
"content": {
|
|
22116
|
+
"type": "string"
|
|
22117
|
+
}
|
|
22118
|
+
},
|
|
22119
|
+
"additionalProperties": false
|
|
22120
|
+
}
|
|
22121
|
+
},
|
|
22122
|
+
{
|
|
22123
|
+
"type": "null"
|
|
22124
|
+
}
|
|
22125
|
+
]
|
|
22126
|
+
},
|
|
22127
|
+
"webhookEndpointId": {
|
|
22128
|
+
"description": "Optional webhook endpoint id for presentation callbacks.",
|
|
22129
|
+
"type": [
|
|
22130
|
+
"string",
|
|
22131
|
+
"null"
|
|
22132
|
+
]
|
|
22133
|
+
},
|
|
22134
|
+
"attached": {
|
|
22135
|
+
"description": "Optional attachments included with presentation requests.",
|
|
22136
|
+
"anyOf": [
|
|
22137
|
+
{
|
|
22138
|
+
"type": "array",
|
|
22139
|
+
"items": {
|
|
22140
|
+
"type": "object",
|
|
22141
|
+
"properties": {
|
|
22142
|
+
"format": {
|
|
22143
|
+
"type": "string",
|
|
22144
|
+
"description": "Attachment format identifier."
|
|
22145
|
+
},
|
|
22146
|
+
"data": {
|
|
22147
|
+
"description": "Attachment payload."
|
|
22148
|
+
},
|
|
22149
|
+
"credential_ids": {
|
|
22150
|
+
"description": "Optional credential query ids bound to this attachment.",
|
|
22151
|
+
"type": "array",
|
|
22152
|
+
"items": {
|
|
22153
|
+
"type": "string"
|
|
22154
|
+
}
|
|
22155
|
+
}
|
|
22156
|
+
},
|
|
22157
|
+
"required": [
|
|
22158
|
+
"format",
|
|
22159
|
+
"data"
|
|
22160
|
+
],
|
|
22161
|
+
"additionalProperties": false
|
|
22162
|
+
}
|
|
22163
|
+
},
|
|
22164
|
+
{
|
|
22165
|
+
"type": "null"
|
|
22166
|
+
}
|
|
22167
|
+
]
|
|
22168
|
+
},
|
|
22169
|
+
"redirectUri": {
|
|
22170
|
+
"description": "Optional redirect URI after presentation completion.",
|
|
22171
|
+
"type": [
|
|
22172
|
+
"string",
|
|
22173
|
+
"null"
|
|
22174
|
+
]
|
|
22175
|
+
},
|
|
22176
|
+
"accessKeyChainId": {
|
|
22177
|
+
"description": "Optional key chain id for access token/auth operations.",
|
|
22178
|
+
"type": [
|
|
22179
|
+
"string",
|
|
22180
|
+
"null"
|
|
22181
|
+
]
|
|
22182
|
+
},
|
|
22183
|
+
"readerAuth": {
|
|
22184
|
+
"description": "Whether reader authentication is required for mDoc requests.",
|
|
22185
|
+
"type": [
|
|
22186
|
+
"boolean",
|
|
22187
|
+
"null"
|
|
22188
|
+
]
|
|
22189
|
+
}
|
|
22190
|
+
},
|
|
22191
|
+
"required": [
|
|
22192
|
+
"id",
|
|
22193
|
+
"dcql_query"
|
|
22194
|
+
],
|
|
22195
|
+
"additionalProperties": false,
|
|
22196
|
+
"title": "PresentationConfigCreateDto"
|
|
22197
|
+
}
|
|
22198
|
+
}
|
|
22199
|
+
}
|
|
22200
|
+
];
|
|
22201
|
+
|
|
22202
|
+
// ../../packages/eudiplo-config-format/dist/config-validator.js
|
|
22203
|
+
var ajv = new import__.Ajv2020({
|
|
22204
|
+
allErrors: true,
|
|
22205
|
+
strict: false,
|
|
22206
|
+
validateFormats: false
|
|
22207
|
+
});
|
|
22208
|
+
for (const schema of CONFIG_SCHEMAS)
|
|
22209
|
+
ajv.addSchema(schema);
|
|
22210
|
+
function validateConfigDocument(document) {
|
|
22211
|
+
const file = serializeDocument(document);
|
|
22212
|
+
const validate = ajv.getSchema(file.$schema);
|
|
22213
|
+
if (!validate)
|
|
22214
|
+
throw new Error(`No bundled validator for ${file.$schema}`);
|
|
22215
|
+
const issues = [];
|
|
22216
|
+
if (!validate(file)) {
|
|
22217
|
+
for (const issue of validate.errors ?? [])
|
|
22218
|
+
issues.push({
|
|
22219
|
+
severity: "error",
|
|
22220
|
+
code: "CONFIG_SCHEMA_VALIDATION_FAILED",
|
|
22221
|
+
path: issue.instancePath || "/",
|
|
22222
|
+
message: issue.keyword === "additionalProperties" ? `Unknown property: ${String(issue.params.additionalProperty)}` : issue.message ?? "Invalid configuration",
|
|
22223
|
+
resource: { kind: document.kind, id: resourceId(document) }
|
|
22224
|
+
});
|
|
22225
|
+
}
|
|
22226
|
+
const id = document.kind === "Client" ? document.spec.clientId : document.spec.id;
|
|
22227
|
+
if (id !== void 0 && id !== resourceId(document))
|
|
22228
|
+
issues.push({
|
|
22229
|
+
severity: "error",
|
|
22230
|
+
code: "RESOURCE_ID_MISMATCH",
|
|
22231
|
+
path: document.kind === "Client" ? "/spec/clientId" : "/spec/id",
|
|
22232
|
+
message: "Resource identifier does not match metadata.id"
|
|
22233
|
+
});
|
|
22234
|
+
return issues;
|
|
22235
|
+
}
|
|
22236
|
+
|
|
22237
|
+
// src/commands/config/portability/migrations.ts
|
|
22238
|
+
function upgradeDocument(input) {
|
|
22239
|
+
const result = migrateDocument(input, validateConfigDocument);
|
|
22240
|
+
return { ...result, document: serializeDocument(result.document) };
|
|
22241
|
+
}
|
|
22242
|
+
|
|
22243
|
+
// src/commands/config/portability/upgrade.ts
|
|
22244
|
+
var codec = new ConfigBundleCodec();
|
|
22245
|
+
function parse3(text, path2) {
|
|
22246
|
+
try {
|
|
22247
|
+
return JSON.parse(text);
|
|
22248
|
+
} catch {
|
|
22249
|
+
throw new Error(`Invalid JSON in ${path2}`);
|
|
22250
|
+
}
|
|
22251
|
+
}
|
|
22252
|
+
function upgradeJson(input, file, context) {
|
|
22253
|
+
const bundle = Array.isArray(input?.documents);
|
|
22254
|
+
if (bundle) assertConfigBundle(input);
|
|
22255
|
+
const results = (bundle ? input.documents : [input]).map(
|
|
22256
|
+
(document) => upgradeDocument(document)
|
|
22257
|
+
);
|
|
22258
|
+
let blocked = false;
|
|
22259
|
+
for (const result of results) {
|
|
22260
|
+
for (const issue of result.issues) {
|
|
22261
|
+
context.stderr.write(
|
|
22262
|
+
`${file}${issue.path}: ${issue.severity} ${issue.code}: ${issue.message}
|
|
22263
|
+
`
|
|
22264
|
+
);
|
|
22265
|
+
if (issue.severity !== "warning") blocked = true;
|
|
22266
|
+
}
|
|
22267
|
+
for (const migration of result.migrations)
|
|
22268
|
+
context.stdout.write(`${file}: migration ${migration}
|
|
22269
|
+
`);
|
|
22270
|
+
}
|
|
22271
|
+
if (blocked) throw new Error(`${file}: upgrade blocked; no output written`);
|
|
22272
|
+
if (!bundle) return results[0].document;
|
|
22273
|
+
const documents = results.map(
|
|
22274
|
+
(result) => result.document
|
|
22275
|
+
);
|
|
22276
|
+
const resources = input.manifest.resources.map(
|
|
22277
|
+
(resource) => {
|
|
22278
|
+
const index = input.documents.findIndex(
|
|
22279
|
+
(candidate) => normalizeDocument(candidate).kind === resource.kind && resourceId(candidate) === resource.id
|
|
22280
|
+
);
|
|
22281
|
+
const document = documents[index];
|
|
22282
|
+
return {
|
|
22283
|
+
...resource,
|
|
22284
|
+
id: resourceId(document),
|
|
22285
|
+
$schema: document.$schema,
|
|
22286
|
+
sha256: createHash2("sha256").update(JSON.stringify(document)).digest("hex")
|
|
22287
|
+
};
|
|
22288
|
+
}
|
|
22289
|
+
);
|
|
22290
|
+
const output = {
|
|
22291
|
+
...input,
|
|
22292
|
+
manifest: { ...input.manifest, formatVersion: 2, resources },
|
|
22293
|
+
documents
|
|
22294
|
+
};
|
|
22295
|
+
assertConfigBundle(output);
|
|
22296
|
+
return output;
|
|
22297
|
+
}
|
|
22298
|
+
function report(input, output, file, parsed, context) {
|
|
22299
|
+
const changed = stableConfigJson(input) !== stableConfigJson(output);
|
|
22300
|
+
context.stdout.write(
|
|
22301
|
+
`${file}: ${changed ? "upgrade required" : "current"}
|
|
22302
|
+
`
|
|
22303
|
+
);
|
|
22304
|
+
if (parsed.flags.diff === true)
|
|
22305
|
+
for (const change of configChanges(input, output)) {
|
|
22306
|
+
context.stdout.write(
|
|
22307
|
+
` ${change.path}: ${JSON.stringify(change.before) ?? "(absent)"} -> ${JSON.stringify(change.after) ?? "(absent)"}
|
|
22308
|
+
`
|
|
22309
|
+
);
|
|
22310
|
+
}
|
|
22311
|
+
return changed;
|
|
22312
|
+
}
|
|
22313
|
+
function inferredKind(path2) {
|
|
22314
|
+
const normalized = path2.split(sep2).join("/");
|
|
22315
|
+
const match = TENANT_RESOURCE_REGISTRY.find(
|
|
22316
|
+
(entry) => entry.kind === "file" ? normalized === entry.file || normalized.endsWith(`/${entry.file}`) : normalized.endsWith(`/${entry.subfolder}/${basename2(path2)}`) || normalized === `${entry.subfolder}/${basename2(path2)}`
|
|
22317
|
+
);
|
|
22318
|
+
return CONFIG_RESOURCE_KINDS.find(
|
|
22319
|
+
(kind) => `${CONFIG_FORMATS[kind].file}.schema.json` === match?.schemaFile
|
|
22320
|
+
);
|
|
22321
|
+
}
|
|
22322
|
+
function wrapBare(kind, input, path2) {
|
|
22323
|
+
if (!input || typeof input !== "object" || Array.isArray(input))
|
|
22324
|
+
throw new Error(`${path2}: configuration must be an object`);
|
|
22325
|
+
const singleton = {
|
|
22326
|
+
Tenant: "tenant",
|
|
22327
|
+
KmsConfig: "kms",
|
|
22328
|
+
RegistrarConfig: "registrar",
|
|
22329
|
+
IssuanceConfig: "issuance"
|
|
22330
|
+
};
|
|
22331
|
+
const spec = structuredClone(input);
|
|
22332
|
+
if (kind === "KeyChain" && spec.key && !spec.keySource) {
|
|
22333
|
+
spec.keySource = { type: "private-jwk", jwk: spec.key };
|
|
22334
|
+
delete spec.key;
|
|
22335
|
+
}
|
|
22336
|
+
const id = String(
|
|
22337
|
+
singleton[kind] ?? spec.id ?? spec.clientId ?? basename2(path2, ".json")
|
|
22338
|
+
);
|
|
22339
|
+
if (!singleton[kind]) spec[kind === "Client" ? "clientId" : "id"] = id;
|
|
22340
|
+
return { $schema: schemaUrl(kind, 1), metadata: { generation: 1 }, spec };
|
|
22341
|
+
}
|
|
22342
|
+
async function folderFiles(path2) {
|
|
22343
|
+
const files = [];
|
|
22344
|
+
for (const entry of await readdir(path2, { withFileTypes: true })) {
|
|
22345
|
+
if (entry.name.startsWith(".")) continue;
|
|
22346
|
+
const file = join4(path2, entry.name);
|
|
22347
|
+
if (entry.isSymbolicLink())
|
|
22348
|
+
throw new Error(`Config folder contains a symbolic link: ${file}`);
|
|
22349
|
+
if (entry.isDirectory()) files.push(...await folderFiles(file));
|
|
22350
|
+
else if (entry.isFile()) files.push(file);
|
|
22351
|
+
}
|
|
22352
|
+
return files.sort();
|
|
22353
|
+
}
|
|
22354
|
+
async function upgradeFolder(source, parsed, context) {
|
|
22355
|
+
const outputs = /* @__PURE__ */ new Map();
|
|
22356
|
+
let changed = 0;
|
|
22357
|
+
for (const file of await folderFiles(source)) {
|
|
22358
|
+
if (extname(file) !== ".json" || relative2(source, file).split(sep2).includes("images"))
|
|
22359
|
+
continue;
|
|
22360
|
+
const input = parse3(await readFile4(file, "utf8"), file);
|
|
22361
|
+
const kind = inferredKind(relative2(source, file));
|
|
22362
|
+
if (!kind && !isConfigDocument(input)) continue;
|
|
22363
|
+
const candidate = isConfigDocument(input) ? input : wrapBare(kind, input, file);
|
|
22364
|
+
const output = upgradeJson(candidate, file, context);
|
|
22365
|
+
if (kind && normalizeDocument(output).kind !== kind)
|
|
22366
|
+
throw new Error(`${file}: expected ${kind} configuration`);
|
|
22367
|
+
if (report(input, output, relative2(source, file), parsed, context))
|
|
22368
|
+
changed++;
|
|
22369
|
+
outputs.set(
|
|
22370
|
+
relative2(source, file),
|
|
22371
|
+
`${JSON.stringify(output, null, 2)}
|
|
22372
|
+
`
|
|
22373
|
+
);
|
|
22374
|
+
}
|
|
22375
|
+
if (!outputs.size)
|
|
22376
|
+
throw new Error(`No configuration documents found in ${source}`);
|
|
22377
|
+
context.stdout.write(
|
|
22378
|
+
`${outputs.size - changed} current, ${changed} require upgrading
|
|
22379
|
+
`
|
|
22380
|
+
);
|
|
22381
|
+
if (parsed.flags.check === true) return changed ? 1 : 0;
|
|
22382
|
+
if (parsed.flags["dry-run"] === true) return 0;
|
|
22383
|
+
const destination = resolve3(
|
|
22384
|
+
context.cwd,
|
|
22385
|
+
readStringFlag(parsed.flags, "output") ?? `${source}.upgraded`
|
|
22386
|
+
);
|
|
22387
|
+
const overlap = (parent, child) => {
|
|
22388
|
+
const path2 = relative2(parent, child);
|
|
22389
|
+
return path2 === "" || !path2.startsWith(`..${sep2}`) && path2 !== "..";
|
|
22390
|
+
};
|
|
22391
|
+
if (overlap(source, destination) || overlap(destination, source))
|
|
22392
|
+
throw new Error(
|
|
22393
|
+
"Folder output must be separate from the source directory"
|
|
22394
|
+
);
|
|
22395
|
+
await lstat(destination).then(
|
|
22396
|
+
() => {
|
|
22397
|
+
throw new Error(`Output already exists: ${destination}`);
|
|
22398
|
+
},
|
|
22399
|
+
(error) => {
|
|
22400
|
+
if (error.code !== "ENOENT") throw error;
|
|
22401
|
+
}
|
|
22402
|
+
);
|
|
22403
|
+
await mkdir3(dirname3(destination), { recursive: true });
|
|
22404
|
+
const staging = await mkdtemp(
|
|
21649
22405
|
join4(dirname3(destination), ".eudiplo-upgrade-")
|
|
21650
22406
|
);
|
|
21651
22407
|
try {
|
|
@@ -21996,8 +22752,8 @@ function createComposeEnv(options) {
|
|
|
21996
22752
|
const authClientSecret = options.authClientSecret ?? "root";
|
|
21997
22753
|
const lines = [
|
|
21998
22754
|
`EUDIPLO_ENV_FILE=${envFileName}`,
|
|
21999
|
-
`EUDIPLO_IMAGE=ghcr.io/
|
|
22000
|
-
`EUDIPLO_CLIENT_IMAGE=ghcr.io/
|
|
22755
|
+
`EUDIPLO_IMAGE=ghcr.io/eudiplo/eudiplo:${imageTag}`,
|
|
22756
|
+
`EUDIPLO_CLIENT_IMAGE=ghcr.io/eudiplo/eudiplo-client:${imageTag}`,
|
|
22001
22757
|
...options.mode === "demo" ? ["EUDIPLO_BIND_ADDRESS=127.0.0.1"] : [],
|
|
22002
22758
|
`EUDIPLO_CONFIG_MOUNT=./${configDirectoryName}:/app/config`,
|
|
22003
22759
|
"CONFIG_FOLDER=/app/config",
|
|
@@ -24161,7 +24917,7 @@ function createDeploymentCommands(context, setExitCode) {
|
|
|
24161
24917
|
// package.json
|
|
24162
24918
|
var package_default = {
|
|
24163
24919
|
name: "@eudiplo/cli",
|
|
24164
|
-
version: "8.1.0-main.
|
|
24920
|
+
version: "8.1.0-main.8f6abca",
|
|
24165
24921
|
description: "Deployment-aware command line tools for EUDIPLO",
|
|
24166
24922
|
private: false,
|
|
24167
24923
|
type: "module",
|
|
@@ -24197,14 +24953,14 @@ var package_default = {
|
|
|
24197
24953
|
],
|
|
24198
24954
|
repository: {
|
|
24199
24955
|
type: "git",
|
|
24200
|
-
url: "git+https://github.com/
|
|
24956
|
+
url: "git+https://github.com/EUDIPLO/eudiplo.git",
|
|
24201
24957
|
directory: "apps/cli"
|
|
24202
24958
|
},
|
|
24203
|
-
homepage: "https://github.com/
|
|
24959
|
+
homepage: "https://github.com/EUDIPLO/eudiplo/tree/main/apps/cli#readme",
|
|
24204
24960
|
bugs: {
|
|
24205
|
-
url: "https://github.com/
|
|
24961
|
+
url: "https://github.com/EUDIPLO/eudiplo/issues"
|
|
24206
24962
|
},
|
|
24207
|
-
author: "
|
|
24963
|
+
author: "LF Decentralized Trust",
|
|
24208
24964
|
license: "Apache-2.0",
|
|
24209
24965
|
engines: {
|
|
24210
24966
|
node: ">=22.12.0"
|
|
@@ -25511,6 +26267,10 @@ import { resolve as resolve8 } from "node:path";
|
|
|
25511
26267
|
|
|
25512
26268
|
// src/services/compose-upgrade.ts
|
|
25513
26269
|
var managedImages = {
|
|
26270
|
+
EUDIPLO_IMAGE: "ghcr.io/eudiplo/eudiplo",
|
|
26271
|
+
EUDIPLO_CLIENT_IMAGE: "ghcr.io/eudiplo/eudiplo-client"
|
|
26272
|
+
};
|
|
26273
|
+
var legacyImages = {
|
|
25514
26274
|
EUDIPLO_IMAGE: "ghcr.io/openwallet-foundation/eudiplo",
|
|
25515
26275
|
EUDIPLO_CLIENT_IMAGE: "ghcr.io/openwallet-foundation/eudiplo-client"
|
|
25516
26276
|
};
|
|
@@ -25522,6 +26282,14 @@ function assertImageTag(tag) {
|
|
|
25522
26282
|
);
|
|
25523
26283
|
}
|
|
25524
26284
|
}
|
|
26285
|
+
function tagOf(value, repository) {
|
|
26286
|
+
const prefix = `${repository}:`;
|
|
26287
|
+
if (!value.startsWith(prefix)) {
|
|
26288
|
+
return void 0;
|
|
26289
|
+
}
|
|
26290
|
+
const tag = value.slice(prefix.length);
|
|
26291
|
+
return TAG.test(tag) ? tag : void 0;
|
|
26292
|
+
}
|
|
25525
26293
|
function planImageUpgrade(content, tag) {
|
|
25526
26294
|
assertImageTag(tag);
|
|
25527
26295
|
const found = /* @__PURE__ */ new Set();
|
|
@@ -25543,17 +26311,26 @@ function planImageUpgrade(content, tag) {
|
|
|
25543
26311
|
);
|
|
25544
26312
|
}
|
|
25545
26313
|
found.add(key);
|
|
25546
|
-
const
|
|
25547
|
-
const
|
|
25548
|
-
|
|
26314
|
+
const currentTag = tagOf(value, repository);
|
|
26315
|
+
const legacyTag = tagOf(value, legacyImages[key]);
|
|
26316
|
+
const current = currentTag ?? legacyTag;
|
|
26317
|
+
if (current === void 0) {
|
|
25549
26318
|
throw new Error(
|
|
25550
|
-
`${key} is set to ${value}, which is not a CLI-managed image. Update it yourself, or restore ${
|
|
26319
|
+
`${key} is set to ${value}, which is not a CLI-managed image. Update it yourself, or restore ${repository}:<tag> to let the CLI manage it.`
|
|
25551
26320
|
);
|
|
25552
26321
|
}
|
|
25553
|
-
if (
|
|
26322
|
+
if (currentTag === void 0) {
|
|
26323
|
+
changes.push({
|
|
26324
|
+
key,
|
|
26325
|
+
repository,
|
|
26326
|
+
movedFrom: legacyImages[key],
|
|
26327
|
+
from: current,
|
|
26328
|
+
to: tag
|
|
26329
|
+
});
|
|
26330
|
+
} else if (current !== tag) {
|
|
25554
26331
|
changes.push({ key, repository, from: current, to: tag });
|
|
25555
26332
|
}
|
|
25556
|
-
return `${key}=${
|
|
26333
|
+
return `${key}=${repository}:${tag}${lineEnding}`;
|
|
25557
26334
|
});
|
|
25558
26335
|
if (!found.has("EUDIPLO_IMAGE")) {
|
|
25559
26336
|
throw new Error(
|
|
@@ -25640,7 +26417,8 @@ async function runUpgradeCommand(config, parsed, context) {
|
|
|
25640
26417
|
`);
|
|
25641
26418
|
for (const change of plan.changes) {
|
|
25642
26419
|
context.stdout.write(
|
|
25643
|
-
` ${change.
|
|
26420
|
+
change.movedFrom ? ` ${change.movedFrom}:${change.from} -> ${change.repository}:${change.to}
|
|
26421
|
+
` : ` ${change.repository}: ${change.from} -> ${change.to}
|
|
25644
26422
|
`
|
|
25645
26423
|
);
|
|
25646
26424
|
}
|