@mdbase-dev/connect-protocol 0.1.0-beta.126 → 0.1.0-beta.147
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/dist/application-contract.d.ts +23 -0
- package/dist/application-contract.js +76 -0
- package/dist/application-declaration.d.ts +120 -0
- package/dist/application-declaration.js +1 -0
- package/dist/authorization-errors.d.ts +34 -0
- package/dist/authorization-errors.js +52 -0
- package/dist/connect-problems.generated.d.ts +134 -0
- package/dist/connect-problems.generated.js +23 -0
- package/dist/index.d.ts +10 -115
- package/dist/index.js +4 -0
- package/dist/manifest-validators.generated.d.ts +13 -0
- package/dist/manifest-validators.generated.js +7940 -0
- package/dist/manifest.d.ts +3 -0
- package/dist/manifest.js +70 -33
- package/dist/next-authorization.d.ts +30 -0
- package/dist/next-authorization.js +90 -0
- package/package.json +10 -4
- package/schemas/connect-problem.v1.schema.json +493 -0
- package/schemas/connect-problems.v1.catalog.json +21 -0
- package/schemas/connect-protocol.v1.schema.json +1 -0
- package/schemas/mdbase-app.legacy-v1.schema.json +25 -0
- package/schemas/mdbase-app.schema.json +25 -0
- package/schemas/next-trust.v1.schema.json +54 -0
package/dist/manifest.d.ts
CHANGED
|
@@ -67,3 +67,6 @@ export declare function formatManifestValidationIssues(issues: readonly Manifest
|
|
|
67
67
|
* prefixed with `path`, the provision's location in its enclosing document.
|
|
68
68
|
*/
|
|
69
69
|
export declare function validateTypePackProvision(value: unknown, path?: string): ManifestValidationIssue[];
|
|
70
|
+
/** RFC 8252 §7.3 native exception: canonical literal IPv4 only, any valid port.
|
|
71
|
+
* This classifies transport; the registered manifest, consent and pairing grant authority. */
|
|
72
|
+
export declare function isNativeLoopbackOrigin(value: unknown): value is string;
|
package/dist/manifest.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import addFormatsModule from "ajv-formats";
|
|
1
|
+
import { sha256 as sha256Bytes } from "@noble/hashes/sha2.js";
|
|
2
|
+
import { bytesToHex, utf8ToBytes } from "@noble/hashes/utils.js";
|
|
4
3
|
import { isMap, parseDocument } from "yaml";
|
|
5
|
-
import
|
|
6
|
-
import legacyAppManifestSchema from "../schemas/mdbase-app.legacy-v1.schema.json" with { type: "json" };
|
|
4
|
+
import { appManifestValidator as generatedAppManifestValidator, legacyAppManifestValidator as generatedLegacyAppManifestValidator } from "./manifest-validators.generated.js";
|
|
7
5
|
import { RECORD_EXTENSIONS_CONFIGURATION_PATH } from "./collection-setup.js";
|
|
8
6
|
import { isNativeRedirectUri } from "./index.js";
|
|
9
7
|
export const APPLICATION_MANIFEST_MAX_BYTES = 524_288;
|
|
@@ -15,18 +13,11 @@ export class AppManifestValidationError extends Error {
|
|
|
15
13
|
this.name = "AppManifestValidationError";
|
|
16
14
|
}
|
|
17
15
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
});
|
|
24
|
-
const addFormats = addFormatsModule;
|
|
25
|
-
addFormats(ajv);
|
|
26
|
-
ajv.addSchema(appManifestSchema);
|
|
27
|
-
const appManifestValidator = requiredValidator(String(appManifestSchema.$id));
|
|
28
|
-
ajv.addSchema(legacyAppManifestSchema);
|
|
29
|
-
const legacyAppManifestValidator = requiredValidator(String(legacyAppManifestSchema.$id));
|
|
16
|
+
// Precompiled from the published JSON Schemas by
|
|
17
|
+
// scripts/generate-manifest-validators.mjs, so validation stays synchronous and
|
|
18
|
+
// identical without shipping the Ajv compiler to consumers.
|
|
19
|
+
const appManifestValidator = generatedAppManifestValidator;
|
|
20
|
+
const legacyAppManifestValidator = generatedLegacyAppManifestValidator;
|
|
30
21
|
/**
|
|
31
22
|
* Validate the complete bundled application declaration accepted by Connect.
|
|
32
23
|
*
|
|
@@ -55,7 +46,8 @@ function validateManifest(value, options, versioned) {
|
|
|
55
46
|
if (version !== 1 && version !== 2) {
|
|
56
47
|
return invalid([issue("/requirements/capabilities/contract_version", "contractVersion", "must declare supported contract version 1 or 2")]);
|
|
57
48
|
}
|
|
58
|
-
const
|
|
49
|
+
const native = asObject(value).platform === "native";
|
|
50
|
+
const candidate = options.allowLocal || native ? localManifestSchemaCandidate(value, !options.allowLocal) : value;
|
|
59
51
|
const schemaResult = validationResult(version === 1 ? legacyAppManifestValidator : appManifestValidator, candidate);
|
|
60
52
|
if (!schemaResult.valid)
|
|
61
53
|
return schemaResult;
|
|
@@ -104,12 +96,6 @@ function normalizeManifest(value) {
|
|
|
104
96
|
export function formatManifestValidationIssues(issues) {
|
|
105
97
|
return issues.map((issue) => `${issue.path || "/"} ${issue.message}`).join("; ");
|
|
106
98
|
}
|
|
107
|
-
function requiredValidator(reference) {
|
|
108
|
-
const validate = ajv.getSchema(reference);
|
|
109
|
-
if (!validate)
|
|
110
|
-
throw new Error(`Canonical schema is unavailable: ${reference}`);
|
|
111
|
-
return validate;
|
|
112
|
-
}
|
|
113
99
|
function validationResult(validate, value) {
|
|
114
100
|
if (validate(value))
|
|
115
101
|
return { valid: true, issues: [] };
|
|
@@ -192,6 +178,33 @@ function validateJsonValue(value, path, ancestors) {
|
|
|
192
178
|
}
|
|
193
179
|
function validateManifestOrigins(value, allowLocal) {
|
|
194
180
|
const manifest = asObject(value);
|
|
181
|
+
const native = manifest.platform === "native";
|
|
182
|
+
for (const [environment, policy] of Object.entries(asObject(manifest.installation_origins))) {
|
|
183
|
+
for (const [kind, origins] of Object.entries(asObject(policy))) {
|
|
184
|
+
for (const [index, origin] of origins.entries()) {
|
|
185
|
+
const path = `/installation_origins/${environment}/${kind}/${index}`;
|
|
186
|
+
try {
|
|
187
|
+
if (native && (kind !== "app-runtime" || !isNativeLoopbackOrigin(origin))) {
|
|
188
|
+
return [issue(path, "origin", "native applications require canonical IPv4 loopback HTTP app-runtime origins")];
|
|
189
|
+
}
|
|
190
|
+
const url = new URL(origin);
|
|
191
|
+
const web = (secureOrAllowedLocal(url, environment === "lab")
|
|
192
|
+
|| (native && isNativeLoopbackOrigin(origin))) && url.origin === origin;
|
|
193
|
+
const mobile = kind === "mobile" && url.protocol === "capacitor:"
|
|
194
|
+
&& /^[a-z0-9.-]+$/u.test(url.hostname) && `${url.protocol}//${url.host}` === origin;
|
|
195
|
+
// A Chrome extension ID is stable (derived from its key), so it can be
|
|
196
|
+
// declared exactly. Firefox extension origins are random per profile.
|
|
197
|
+
const extension = kind === "app-runtime" && /^chrome-extension:\/\/[a-p]{32}$/u.test(origin);
|
|
198
|
+
if ((!web && !mobile && !extension) || origin.includes("*") || url.username || url.password || url.search || url.hash) {
|
|
199
|
+
return [issue(path, "origin", "must be an exact HTTPS, loopback HTTP, mobile capacitor or Chrome extension origin without wildcards")];
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
return [issue(path, "origin", "must be an exact installation origin")];
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
195
208
|
if (manifest.distribution === "portable") {
|
|
196
209
|
if (manifest.project_url === undefined) {
|
|
197
210
|
return manifest.icon === undefined
|
|
@@ -215,12 +228,20 @@ function validateManifestOrigins(value, allowLocal) {
|
|
|
215
228
|
}
|
|
216
229
|
try {
|
|
217
230
|
const homepage = new URL(String(manifest.homepage));
|
|
218
|
-
if (!secureOrAllowedLocal(homepage, allowLocal)) {
|
|
219
|
-
return [issue("/homepage", "protocol", "must use HTTPS (or loopback HTTP in local mode)")];
|
|
231
|
+
if (native ? !isNativeLoopbackUrl(String(manifest.homepage)) : !secureOrAllowedLocal(homepage, allowLocal)) {
|
|
232
|
+
return [issue("/homepage", "protocol", native ? "native applications require canonical IPv4 loopback HTTP" : "must use HTTPS (or loopback HTTP in local mode)")];
|
|
220
233
|
}
|
|
221
234
|
for (const [index, redirect] of manifest.redirect_uris.entries()) {
|
|
235
|
+
// Redirects match exactly (RFC 8252 §8.10); a wildcard is never a pattern.
|
|
236
|
+
if (String(redirect).includes("*")) {
|
|
237
|
+
return [issue(`/redirect_uris/${index}`, "url", "must be an exact URI without wildcards")];
|
|
238
|
+
}
|
|
222
239
|
const url = new URL(String(redirect));
|
|
223
|
-
if (
|
|
240
|
+
if (native && ["http:", "https:"].includes(url.protocol) && !isNativeLoopbackUrl(String(redirect))) {
|
|
241
|
+
return [issue(`/redirect_uris/${index}`, "origin", "native HTTP(S) redirects require canonical IPv4 loopback HTTP")];
|
|
242
|
+
}
|
|
243
|
+
if (url.origin === homepage.origin && !secureOrAllowedLocal(url, allowLocal)
|
|
244
|
+
&& !(native && isNativeLoopbackUrl(String(redirect)))) {
|
|
224
245
|
return [issue(`/redirect_uris/${index}`, "protocol", "must use HTTPS (or loopback HTTP in local mode)")];
|
|
225
246
|
}
|
|
226
247
|
const nativeAllowed = nativeRedirectMatchesApplication(url, String(manifest.id));
|
|
@@ -358,7 +379,7 @@ function typeFrontmatter(document) {
|
|
|
358
379
|
return { kind: parsed.get("kind"), name: parsed.get("name"), version: parsed.get("version") };
|
|
359
380
|
}
|
|
360
381
|
function sha256(document) {
|
|
361
|
-
return `sha256:${
|
|
382
|
+
return `sha256:${bytesToHex(sha256Bytes(utf8ToBytes(document)))}`;
|
|
362
383
|
}
|
|
363
384
|
function validateConfigurationSetup(value) {
|
|
364
385
|
const manifest = asObject(value);
|
|
@@ -555,7 +576,7 @@ function validateLegacyCapabilityRequirements(value) {
|
|
|
555
576
|
}
|
|
556
577
|
return issues;
|
|
557
578
|
}
|
|
558
|
-
function localManifestSchemaCandidate(value) {
|
|
579
|
+
function localManifestSchemaCandidate(value, nativeOnly = false) {
|
|
559
580
|
const source = asObject(value);
|
|
560
581
|
if (source.distribution === "portable")
|
|
561
582
|
return value;
|
|
@@ -564,18 +585,18 @@ function localManifestSchemaCandidate(value) {
|
|
|
564
585
|
const object = { ...source };
|
|
565
586
|
for (const field of ["homepage", "icon"]) {
|
|
566
587
|
if (typeof object[field] === "string") {
|
|
567
|
-
object[field] = schemaSafeLocalUrl(object[field]);
|
|
588
|
+
object[field] = schemaSafeLocalUrl(object[field], nativeOnly);
|
|
568
589
|
}
|
|
569
590
|
}
|
|
570
591
|
if (Array.isArray(object.redirect_uris)) {
|
|
571
|
-
object.redirect_uris = object.redirect_uris.map((url) => typeof url === "string" ? schemaSafeLocalUrl(url) : url);
|
|
592
|
+
object.redirect_uris = object.redirect_uris.map((url) => typeof url === "string" ? schemaSafeLocalUrl(url, nativeOnly) : url);
|
|
572
593
|
}
|
|
573
594
|
return object;
|
|
574
595
|
}
|
|
575
|
-
function schemaSafeLocalUrl(value) {
|
|
596
|
+
function schemaSafeLocalUrl(value, nativeOnly) {
|
|
576
597
|
try {
|
|
577
598
|
const url = new URL(value);
|
|
578
|
-
if (url.protocol === "http:" && isLoopback(url.hostname))
|
|
599
|
+
if (url.protocol === "http:" && (nativeOnly ? isNativeLoopbackUrl(value) : isLoopback(url.hostname)))
|
|
579
600
|
url.protocol = "https:";
|
|
580
601
|
return url.href;
|
|
581
602
|
}
|
|
@@ -583,6 +604,22 @@ function schemaSafeLocalUrl(value) {
|
|
|
583
604
|
return value;
|
|
584
605
|
}
|
|
585
606
|
}
|
|
607
|
+
/** RFC 8252 §7.3 native exception: canonical literal IPv4 only, any valid port.
|
|
608
|
+
* This classifies transport; the registered manifest, consent and pairing grant authority. */
|
|
609
|
+
export function isNativeLoopbackOrigin(value) {
|
|
610
|
+
if (typeof value !== "string" || !/^http:\/\/127\.0\.0\.1(?::[1-9][0-9]{0,4})?$/.test(value))
|
|
611
|
+
return false;
|
|
612
|
+
try {
|
|
613
|
+
return new URL(value).origin === value;
|
|
614
|
+
}
|
|
615
|
+
catch {
|
|
616
|
+
return false;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
function isNativeLoopbackUrl(value) {
|
|
620
|
+
const origin = /^http:\/\/[^/?#]+/.exec(value)?.[0];
|
|
621
|
+
return isNativeLoopbackOrigin(origin);
|
|
622
|
+
}
|
|
586
623
|
function secureOrAllowedLocal(url, allowLocal) {
|
|
587
624
|
return url.protocol === "https:"
|
|
588
625
|
|| (allowLocal && url.protocol === "http:" && isLoopback(url.hostname));
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type ApplicationCapabilityId } from "./capabilities.js";
|
|
2
|
+
import type { ApplicationRequirements, LegacyApplicationRequirements } from "./application-declaration.js";
|
|
3
|
+
import type { FileAction } from "./files.js";
|
|
4
|
+
import type { CollectionOperation } from "./operations.js";
|
|
5
|
+
/** Exact record/file pairs used by both consent and next policy publication. */
|
|
6
|
+
export declare const NEXT_CAPABILITY_FILE_ACTIONS: Partial<Record<ApplicationCapabilityId, readonly FileAction[]>>;
|
|
7
|
+
export interface NextAuthorizationGroup {
|
|
8
|
+
id: ApplicationCapabilityId;
|
|
9
|
+
operations: CollectionOperation[];
|
|
10
|
+
fileActions: readonly FileAction[];
|
|
11
|
+
required: boolean;
|
|
12
|
+
}
|
|
13
|
+
type Requirements = {
|
|
14
|
+
access?: ApplicationRequirements["access"];
|
|
15
|
+
capabilities?: ApplicationRequirements["capabilities"] | LegacyApplicationRequirements["capabilities"];
|
|
16
|
+
files?: ApplicationRequirements["files"] | LegacyApplicationRequirements["files"];
|
|
17
|
+
};
|
|
18
|
+
/** Fresh offers only. Never change the original declaration or a retained grant. */
|
|
19
|
+
export declare function projectNextAuthorizationGroups(requirements: Requirements, requested: readonly string[]): {
|
|
20
|
+
groups: NextAuthorizationGroup[];
|
|
21
|
+
error?: string;
|
|
22
|
+
};
|
|
23
|
+
/** Exact projection: no dropping or rounding of stored/approved permissions.
|
|
24
|
+
* Setup is an independent complete pair, not structural administration. This
|
|
25
|
+
* projects ordinary policy groups only; it does not authenticate a declaration
|
|
26
|
+
* or grant authority to execute setup. Producers must verify the original
|
|
27
|
+
* signed declaration/authorization before mediating either setup operation.
|
|
28
|
+
*/
|
|
29
|
+
export declare function exactNextPermissionCapabilities(operations: readonly string[], files: readonly string[]): ApplicationCapabilityId[] | undefined;
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { APPLICATION_CAPABILITY_DEFINITIONS, APPLICATION_CAPABILITY_V1_DEFINITIONS, APPLICATION_SETUP_OPERATIONS } from "./capabilities.js";
|
|
2
|
+
/** Exact record/file pairs used by both consent and next policy publication. */
|
|
3
|
+
export const NEXT_CAPABILITY_FILE_ACTIONS = {
|
|
4
|
+
"collection.read": ["list", "read"], "records.create": ["add"],
|
|
5
|
+
"records.edit": ["replace", "move"], "records.delete": ["delete"]
|
|
6
|
+
};
|
|
7
|
+
const UPDATE_REQUIRED = "This app needs an update before it can connect. Try again after it updates.";
|
|
8
|
+
const refuse = () => ({ groups: [], error: UPDATE_REQUIRED });
|
|
9
|
+
const fileActions = new Set(["list", "read", "add", "replace", "move", "delete"]);
|
|
10
|
+
const equalSet = (left, right) => {
|
|
11
|
+
const a = new Set(left), b = new Set(right);
|
|
12
|
+
return a.size === b.size && [...a].every(value => b.has(value));
|
|
13
|
+
};
|
|
14
|
+
/** Fresh offers only. Never change the original declaration or a retained grant. */
|
|
15
|
+
export function projectNextAuthorizationGroups(requirements, requested) {
|
|
16
|
+
const declaration = requirements.capabilities;
|
|
17
|
+
if (!declaration || (declaration.contract_version !== 1 && declaration.contract_version !== 2)
|
|
18
|
+
|| !Array.isArray(declaration.required) || (declaration.optional !== undefined && !Array.isArray(declaration.optional)))
|
|
19
|
+
return refuse();
|
|
20
|
+
const legacy = declaration.contract_version === 1;
|
|
21
|
+
if (legacy && requirements.access !== "full_collection")
|
|
22
|
+
return refuse();
|
|
23
|
+
const catalog = legacy ? APPLICATION_CAPABILITY_V1_DEFINITIONS : APPLICATION_CAPABILITY_DEFINITIONS;
|
|
24
|
+
const ids = [...declaration.required, ...(declaration.optional ?? [])];
|
|
25
|
+
if (ids.some(id => !Object.hasOwn(catalog, id)) || new Set(ids).size !== ids.length)
|
|
26
|
+
return refuse();
|
|
27
|
+
const files = requirements.files;
|
|
28
|
+
if (files && (legacy
|
|
29
|
+
? !("actions" in files) || "required" in files || "optional" in files || !Array.isArray(files.actions)
|
|
30
|
+
: !("required" in files) || "actions" in files || !Array.isArray(files.required)
|
|
31
|
+
|| (files.optional !== undefined && !Array.isArray(files.optional))))
|
|
32
|
+
return refuse();
|
|
33
|
+
const requiredFiles = files ? "actions" in files ? files.actions : files.required : [];
|
|
34
|
+
const declaredFiles = files ? "actions" in files ? files.actions : [...files.required, ...(files.optional ?? [])] : [];
|
|
35
|
+
if (declaredFiles.some(action => !fileActions.has(action)) || new Set(declaredFiles).size !== declaredFiles.length)
|
|
36
|
+
return refuse();
|
|
37
|
+
const requestedSet = new Set(requested);
|
|
38
|
+
const expansions = catalog;
|
|
39
|
+
const requiredOperations = new Set(declaration.required.flatMap(id => expansions[id] ?? []));
|
|
40
|
+
if (legacy) {
|
|
41
|
+
const allowed = new Set(ids.flatMap(id => expansions[id] ?? []));
|
|
42
|
+
if (requested.some(operation => !allowed.has(operation)))
|
|
43
|
+
return refuse();
|
|
44
|
+
// A required file capability cannot disappear just because its operation
|
|
45
|
+
// expansion is empty in the predecessor catalog.
|
|
46
|
+
if (declaration.required.some(id => id.startsWith("files.") && !declaredFiles.includes(id.slice(6))))
|
|
47
|
+
return refuse();
|
|
48
|
+
}
|
|
49
|
+
const candidates = legacy ? Object.keys(APPLICATION_CAPABILITY_DEFINITIONS) : ids;
|
|
50
|
+
const groups = [];
|
|
51
|
+
for (const id of candidates) {
|
|
52
|
+
const operations = [...APPLICATION_CAPABILITY_DEFINITIONS[id]];
|
|
53
|
+
const pairedFiles = NEXT_CAPABILITY_FILE_ACTIONS[id] ?? [];
|
|
54
|
+
const required = operations.some(operation => requiredOperations.has(operation)) || pairedFiles.some(action => requiredFiles.includes(action));
|
|
55
|
+
if (id === "offline.replica" || !operations.every(operation => requestedSet.has(operation))
|
|
56
|
+
|| !pairedFiles.every(action => declaredFiles.includes(action))) {
|
|
57
|
+
if (required)
|
|
58
|
+
return refuse();
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (legacy && id === "definitions.manage" && APPLICATION_SETUP_OPERATIONS.every(operation => requestedSet.has(operation)))
|
|
62
|
+
operations.push(...APPLICATION_SETUP_OPERATIONS);
|
|
63
|
+
groups.push({ id, operations, fileActions: pairedFiles, required });
|
|
64
|
+
}
|
|
65
|
+
const covered = new Set(groups.flatMap(group => group.operations));
|
|
66
|
+
if ([...requiredOperations].some(operation => !covered.has(operation))
|
|
67
|
+
|| requiredFiles.some(action => !groups.some(group => group.fileActions.includes(action))) || groups.length === 0)
|
|
68
|
+
return refuse();
|
|
69
|
+
return { groups };
|
|
70
|
+
}
|
|
71
|
+
/** Exact projection: no dropping or rounding of stored/approved permissions.
|
|
72
|
+
* Setup is an independent complete pair, not structural administration. This
|
|
73
|
+
* projects ordinary policy groups only; it does not authenticate a declaration
|
|
74
|
+
* or grant authority to execute setup. Producers must verify the original
|
|
75
|
+
* signed declaration/authorization before mediating either setup operation.
|
|
76
|
+
*/
|
|
77
|
+
export function exactNextPermissionCapabilities(operations, files) {
|
|
78
|
+
const groups = Object.keys(APPLICATION_CAPABILITY_DEFINITIONS).filter(id => id !== "offline.replica" && APPLICATION_CAPABILITY_DEFINITIONS[id].every(operation => operations.includes(operation)));
|
|
79
|
+
const expected = groups.flatMap(id => [...APPLICATION_CAPABILITY_DEFINITIONS[id]]);
|
|
80
|
+
const setup = APPLICATION_SETUP_OPERATIONS.filter(operation => operations.includes(operation));
|
|
81
|
+
if (setup.length) {
|
|
82
|
+
if (setup.length !== APPLICATION_SETUP_OPERATIONS.length)
|
|
83
|
+
return undefined;
|
|
84
|
+
expected.push(...setup);
|
|
85
|
+
}
|
|
86
|
+
if (!groups.length || !equalSet(expected, operations)
|
|
87
|
+
|| !equalSet(groups.flatMap(id => [...(NEXT_CAPABILITY_FILE_ACTIONS[id] ?? [])]), files))
|
|
88
|
+
return undefined;
|
|
89
|
+
return groups.sort();
|
|
90
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mdbase-dev/connect-protocol",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.147",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
"types": "./dist/manifest.d.ts",
|
|
21
21
|
"import": "./dist/manifest.js"
|
|
22
22
|
},
|
|
23
|
+
"./next-authorization": {
|
|
24
|
+
"types": "./dist/next-authorization.d.ts",
|
|
25
|
+
"import": "./dist/next-authorization.js"
|
|
26
|
+
},
|
|
23
27
|
"./schemas/*": "./schemas/*"
|
|
24
28
|
},
|
|
25
29
|
"files": [
|
|
@@ -27,17 +31,19 @@
|
|
|
27
31
|
"schemas"
|
|
28
32
|
],
|
|
29
33
|
"dependencies": {
|
|
30
|
-
"
|
|
31
|
-
"ajv-formats": "^3.0.1",
|
|
34
|
+
"@noble/hashes": "2.4.0",
|
|
32
35
|
"yaml": "^2.9.1"
|
|
33
36
|
},
|
|
34
37
|
"devDependencies": {
|
|
35
38
|
"@types/node": "^24.0.0",
|
|
39
|
+
"ajv": "^8.20.0",
|
|
40
|
+
"ajv-formats": "^3.0.1",
|
|
41
|
+
"esbuild": "^0.28.1",
|
|
36
42
|
"typescript": "^7.0.2"
|
|
37
43
|
},
|
|
38
44
|
"scripts": {
|
|
39
45
|
"build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json",
|
|
40
|
-
"test": "node --test test/*.test.mjs && node ../../scripts/generate-change-events.mjs --check && node ../../scripts/generate-connect-problems.mjs --check && node ../../scripts/generate-operation-catalog.mjs --check && node ../../scripts/generate-application-capabilities.mjs --check",
|
|
46
|
+
"test": "node --test test/*.test.mjs && node ../../scripts/generate-manifest-validators.mjs --check && node ../../scripts/generate-change-events.mjs --check && node ../../scripts/generate-connect-problems.mjs --check && node ../../scripts/generate-operation-catalog.mjs --check && node ../../scripts/generate-application-capabilities.mjs --check",
|
|
41
47
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
42
48
|
}
|
|
43
49
|
}
|