@arcforges/api-client 1.0.0-ci.9.1 → 1.0.0-ci.92.1
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/NOTICE +57 -5
- package/README.md +9 -2
- package/build-identity.json +146 -0
- package/contracts.binpb +0 -0
- package/dist/gen/http.d.ts +2 -0
- package/dist/gen/http.js +5 -0
- package/dist/index.d.ts +10 -1
- package/dist/index.js +20 -2
- package/dist/shapes/gen/PackageInventory.d.ts +24 -0
- package/dist/shapes/gen/PackageInventory.js +327 -0
- package/dist/shapes/gen/PartReceipt.d.ts +21 -0
- package/dist/shapes/gen/PartReceipt.js +290 -0
- package/package.json +15 -7
- package/sbom.cdx.json +17 -17
- package/schemas/public/http/v1/inventory.schema.json +49 -0
- package/schemas/public/http/v1/schema.json +30 -0
- package/schemas/public/proto/arcforges/events/v1/events.proto +14 -0
- package/schemas/public/proto/arcforges/foundation/v1/foundation.proto +248 -0
- package/schemas/public/proto/arcforges/hello/v1/hello.proto +23 -0
- package/schemas/public/proto/arcforges/publicapi/v1/content.proto +1200 -0
- package/source.json +31 -6
package/NOTICE
CHANGED
|
@@ -1,13 +1,65 @@
|
|
|
1
1
|
ArcForges Contracts
|
|
2
2
|
Copyright 2026 ArcForges contributors
|
|
3
3
|
|
|
4
|
-
@arcforges/api-client 1.0.0-ci.
|
|
4
|
+
@arcforges/api-client 1.0.0-ci.92.1 (Apache-2.0)
|
|
5
5
|
|
|
6
6
|
Resolved runtime dependency inventory (dependencies retain their own licences):
|
|
7
|
-
- @arcforges/proto 1.0.0-ci.
|
|
8
|
-
- @bufbuild/protobuf 2.
|
|
7
|
+
- @arcforges/proto 1.0.0-ci.92.1: Apache-2.0 (pkg:npm/%40arcforges/proto@1.0.0-ci.92.1)
|
|
8
|
+
- @bufbuild/protobuf 2.15.0: (Apache-2.0 AND BSD-3-Clause) (pkg:npm/%40bufbuild/protobuf@2.15.0)
|
|
9
9
|
- @connectrpc/connect 2.2.0: Apache-2.0 (pkg:npm/%40connectrpc/connect@2.2.0)
|
|
10
10
|
- @connectrpc/connect-web 2.2.0: Apache-2.0 (pkg:npm/%40connectrpc/connect-web@2.2.0)
|
|
11
11
|
|
|
12
|
-
Third-party dependencies are referenced, not vendored into this package.
|
|
13
|
-
|
|
12
|
+
Third-party dependencies are referenced, not vendored into this package. Installed dependencies supply their original licence and notice files.
|
|
13
|
+
|
|
14
|
+
ArcForges source provenance notices
|
|
15
|
+
|
|
16
|
+
Generated from reviewed active records. Original licence files and dependency notices remain authoritative.
|
|
17
|
+
|
|
18
|
+
contract-bindings-r5
|
|
19
|
+
Source: https://github.com/ArcForges/Contracts @ b6795dc55852e16bcd555751a58bd494958e3917
|
|
20
|
+
Material licence: Apache-2.0
|
|
21
|
+
Notice scope: packages
|
|
22
|
+
Copyright 2026 ArcForges contributors.
|
|
23
|
+
Copyright 2008 Google Inc. All rights reserved.
|
|
24
|
+
Copyright 2015, 2019, 2020 gRPC authors.
|
|
25
|
+
Copyright 2021-2026 Buf Technologies, Inc.
|
|
26
|
+
Copyright 2022-2026 The Connect Authors.
|
|
27
|
+
Selected ArcForges contract bindings are generated from Apache-2.0 schemas using Grpc.Tools 2.84.0, protoc-gen-es 2.15.0 and Connect-Kotlin 0.9.0. Shape validators, domain identity adapters and fixture exports use Apache-2.0 repository tooling. Historical protobuf BSD-3-Clause and applicable generator Apache-2.0 attributions are retained. Build tools are not bundled in client packages. Native-grpc-only Android generation remains retired.
|
|
28
|
+
|
|
29
|
+
protobuf-generator-licence-r1
|
|
30
|
+
Source: https://github.com/protocolbuffers/protobuf @ 35cd01f9fe9afbeea38cc7b979a3b6bfcde82c03
|
|
31
|
+
Material licence: BSD-3-Clause
|
|
32
|
+
Notice scope: packages
|
|
33
|
+
Copyright 2008 Google Inc. All rights reserved.
|
|
34
|
+
Copyright 2008 Google Inc. All rights reserved.
|
|
35
|
+
|
|
36
|
+
Redistribution and use in source and binary forms, with or without
|
|
37
|
+
modification, are permitted provided that the following conditions are
|
|
38
|
+
met:
|
|
39
|
+
|
|
40
|
+
* Redistributions of source code must retain the above copyright
|
|
41
|
+
notice, this list of conditions and the following disclaimer.
|
|
42
|
+
* Redistributions in binary form must reproduce the above
|
|
43
|
+
copyright notice, this list of conditions and the following disclaimer
|
|
44
|
+
in the documentation and/or other materials provided with the
|
|
45
|
+
distribution.
|
|
46
|
+
* Neither the name of Google Inc. nor the names of its
|
|
47
|
+
contributors may be used to endorse or promote products derived from
|
|
48
|
+
this software without specific prior written permission.
|
|
49
|
+
|
|
50
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
51
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
52
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
53
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
54
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
55
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
56
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
57
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
58
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
59
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
60
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
61
|
+
|
|
62
|
+
Code generated by the Protocol Buffer compiler is owned by the owner
|
|
63
|
+
of the input file used when generating it. This code is not
|
|
64
|
+
standalone and requires a support library to be linked with it. This
|
|
65
|
+
support library is itself covered by the above license.
|
package/README.md
CHANGED
|
@@ -12,10 +12,17 @@ const reply = await client.sayHello({ name: "World" }, { timeoutMs: 5000 });
|
|
|
12
12
|
console.log(reply.message);
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
`createPublicGrpcWebTransport` is the public business transport: binary gRPC-Web
|
|
16
|
+
only, unknown fields retained and the shared 100-level nesting bound. It refuses
|
|
17
|
+
`useBinaryFormat`, `jsonOptions` and `binaryOptions` overrides. The declared HTTP
|
|
18
|
+
exception records have strict codecs such as `tryParsePartReceiptJson` and
|
|
19
|
+
`serializePartReceiptJson`; they enforce the schema byte limit, UTF-8, JSON depth 32,
|
|
20
|
+
duplicate-property and integer-lexeme rules before the closed schema check.
|
|
21
|
+
|
|
15
22
|
The endpoint must serve gRPC-Web. Browser cross-origin access also requires
|
|
16
23
|
server CORS configuration. The demo host binds to loopback for tests.
|
|
17
24
|
|
|
18
|
-
|
|
19
|
-
|
|
25
|
+
Android uses the separately published Kotlin artifacts with binary gRPC-Web.
|
|
26
|
+
This package is the TypeScript Web client; it does not provide a mobile runtime.
|
|
20
27
|
|
|
21
28
|
Apache-2.0. [Source and full setup](https://github.com/ArcForges/Contracts).
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "arcforges.build-identity.v1",
|
|
3
|
+
"owner": "Contracts",
|
|
4
|
+
"artifact": {
|
|
5
|
+
"id": "@arcforges/api-client",
|
|
6
|
+
"version": "1.0.0-ci.92.1"
|
|
7
|
+
},
|
|
8
|
+
"build": {
|
|
9
|
+
"sourceCommit": "e6c4a77f3ba48d70de4bf524623985b29278c784",
|
|
10
|
+
"dirty": false,
|
|
11
|
+
"kind": "ci",
|
|
12
|
+
"buildId": "35797272606.1",
|
|
13
|
+
"runId": "35797272606",
|
|
14
|
+
"runAttempt": 1,
|
|
15
|
+
"pipelineRun": "https://github.com/ArcForges/Contracts/actions/runs/35797272606",
|
|
16
|
+
"sourceDateEpoch": 1790119475
|
|
17
|
+
},
|
|
18
|
+
"axes": {
|
|
19
|
+
"AppVersion": {
|
|
20
|
+
"status": "not-applicable",
|
|
21
|
+
"reason": "Contracts distributes libraries, not an installed product."
|
|
22
|
+
},
|
|
23
|
+
"ContractSet": {
|
|
24
|
+
"status": "present",
|
|
25
|
+
"values": [
|
|
26
|
+
{
|
|
27
|
+
"subject": "arcforges.events",
|
|
28
|
+
"version": "1",
|
|
29
|
+
"source": {
|
|
30
|
+
"path": "public/proto/arcforges/events/v1/events.proto",
|
|
31
|
+
"sha256": "ea0ac740c06bbb5b81724b4a7e601110424cabc4940b07e579cf97d852880f43"
|
|
32
|
+
},
|
|
33
|
+
"descriptorSha256": "f735938a31ead03abb331db2dd04dd12ace5335b6793e47feaeb4c5623386aba"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"subject": "arcforges.foundation",
|
|
37
|
+
"version": "1",
|
|
38
|
+
"source": {
|
|
39
|
+
"path": "public/proto/arcforges/foundation/v1/foundation.proto",
|
|
40
|
+
"sha256": "ceda869bf2998ca4bc21c4b7504c365a4662e7f28183e6db81660592d5bcdb3f"
|
|
41
|
+
},
|
|
42
|
+
"descriptorSha256": "f735938a31ead03abb331db2dd04dd12ace5335b6793e47feaeb4c5623386aba"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"subject": "arcforges.hello",
|
|
46
|
+
"version": "1",
|
|
47
|
+
"source": {
|
|
48
|
+
"path": "public/proto/arcforges/hello/v1/hello.proto",
|
|
49
|
+
"sha256": "92489f89d1898a3d3bbea56c72116416cd0152ae8866c98745739437020c67d9"
|
|
50
|
+
},
|
|
51
|
+
"descriptorSha256": "f735938a31ead03abb331db2dd04dd12ace5335b6793e47feaeb4c5623386aba"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"subject": "arcforges.publicapi",
|
|
55
|
+
"version": "1",
|
|
56
|
+
"source": {
|
|
57
|
+
"path": "public/proto/arcforges/publicapi/v1/content.proto",
|
|
58
|
+
"sha256": "a352f31e0bcee5e5523e59cb6bcfe2af04423e78389c67fc0d8d0ab52f104dee"
|
|
59
|
+
},
|
|
60
|
+
"descriptorSha256": "f735938a31ead03abb331db2dd04dd12ace5335b6793e47feaeb4c5623386aba"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"subject": "json:PackageInventory",
|
|
64
|
+
"version": "1",
|
|
65
|
+
"source": {
|
|
66
|
+
"path": "public/http/v1/inventory.schema.json",
|
|
67
|
+
"sha256": "2d17acc663de43ff847e522ddb16f32b1e7ec356df7db7dcafe8342d3fb014ce"
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"subject": "json:PartReceipt",
|
|
72
|
+
"version": "1",
|
|
73
|
+
"source": {
|
|
74
|
+
"path": "public/http/v1/schema.json",
|
|
75
|
+
"sha256": "8d4c1282c0f93452a0304e44c832179d4c6f65fa563ae53517aa324af87105ce"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
"CapabilityVersion": {
|
|
81
|
+
"status": "not-produced",
|
|
82
|
+
"reason": "The selected contract records do not declare implemented product capabilities.",
|
|
83
|
+
"producer": "WP09 and product capability owners"
|
|
84
|
+
},
|
|
85
|
+
"NativeFormatVersion": {
|
|
86
|
+
"status": "not-produced",
|
|
87
|
+
"reason": "No portable product format exists here.",
|
|
88
|
+
"producer": "WP18/28, WP34 and WP38"
|
|
89
|
+
},
|
|
90
|
+
"StorageSchemaVersion": {
|
|
91
|
+
"status": "not-produced",
|
|
92
|
+
"reason": "Contracts owns no implemented migration set.",
|
|
93
|
+
"producer": "WP07/21 and product storage owners"
|
|
94
|
+
},
|
|
95
|
+
"NativeAbiVersion": {
|
|
96
|
+
"status": "not-applicable",
|
|
97
|
+
"reason": "These packages contain no first-party native C boundary."
|
|
98
|
+
},
|
|
99
|
+
"PolicySchemaVersion": {
|
|
100
|
+
"status": "not-produced",
|
|
101
|
+
"reason": "The selected schemas contain no implemented product policy declaration.",
|
|
102
|
+
"producer": "WP03 and WP44"
|
|
103
|
+
},
|
|
104
|
+
"ExtensionProtocolVersion": {
|
|
105
|
+
"status": "not-applicable",
|
|
106
|
+
"reason": "This package closure contains no extension protocol."
|
|
107
|
+
},
|
|
108
|
+
"PackageVersion": {
|
|
109
|
+
"status": "present",
|
|
110
|
+
"values": [
|
|
111
|
+
{
|
|
112
|
+
"subject": "pkg:npm/%40arcforges/proto",
|
|
113
|
+
"version": "1.0.0-ci.92.1",
|
|
114
|
+
"source": {
|
|
115
|
+
"path": "sbom.cdx.json#components",
|
|
116
|
+
"sha256": "eed9ce9eb5fd29191d6c222746b88c1eb893704ba3a009478d57b93e03701f4d"
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"subject": "pkg:npm/%40bufbuild/protobuf",
|
|
121
|
+
"version": "2.15.0",
|
|
122
|
+
"source": {
|
|
123
|
+
"path": "sbom.cdx.json#components",
|
|
124
|
+
"sha256": "eed9ce9eb5fd29191d6c222746b88c1eb893704ba3a009478d57b93e03701f4d"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"subject": "pkg:npm/%40connectrpc/connect",
|
|
129
|
+
"version": "2.2.0",
|
|
130
|
+
"source": {
|
|
131
|
+
"path": "sbom.cdx.json#components",
|
|
132
|
+
"sha256": "eed9ce9eb5fd29191d6c222746b88c1eb893704ba3a009478d57b93e03701f4d"
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"subject": "pkg:npm/%40connectrpc/connect-web",
|
|
137
|
+
"version": "2.2.0",
|
|
138
|
+
"source": {
|
|
139
|
+
"path": "sbom.cdx.json#components",
|
|
140
|
+
"sha256": "eed9ce9eb5fd29191d6c222746b88c1eb893704ba3a009478d57b93e03701f4d"
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
package/contracts.binpb
ADDED
|
Binary file
|
package/dist/gen/http.js
ADDED
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
|
+
import type { Transport } from "@connectrpc/connect";
|
|
1
2
|
import type { GrpcWebTransportOptions } from "@connectrpc/connect-web";
|
|
3
|
+
/** Caller-owned endpoint, fetch, interceptors and timeout; the wire format is fixed. */
|
|
4
|
+
export type PublicGrpcWebTransportOptions = Omit<GrpcWebTransportOptions, "useBinaryFormat" | "jsonOptions" | "binaryOptions">;
|
|
5
|
+
/**
|
|
6
|
+
* Creates the public business transport: binary gRPC-Web only, unknown fields
|
|
7
|
+
* retained and the shared nesting bound. JSON selection is refused.
|
|
8
|
+
*/
|
|
9
|
+
export declare function createPublicGrpcWebTransport(options: PublicGrpcWebTransportOptions): Transport;
|
|
2
10
|
/** Creates the example client using the caller's gRPC-Web endpoint and fetch. */
|
|
3
|
-
export declare function createHelloClient(options:
|
|
11
|
+
export declare function createHelloClient(options: PublicGrpcWebTransportOptions): import("@connectrpc/connect").Client<import("@bufbuild/protobuf/codegenv2").GenService<{
|
|
4
12
|
sayHello: {
|
|
5
13
|
methodKind: "unary";
|
|
6
14
|
input: typeof import("@arcforges/proto").SayHelloRequestSchema;
|
|
7
15
|
output: typeof import("@arcforges/proto").SayHelloResponseSchema;
|
|
8
16
|
};
|
|
9
17
|
}>>;
|
|
18
|
+
export * from "./gen/http.js";
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,26 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
import { HelloService } from "@arcforges/proto";
|
|
2
|
+
import { contractBinaryReadOptions, HelloService } from "@arcforges/proto";
|
|
3
3
|
import { createClient } from "@connectrpc/connect";
|
|
4
4
|
import { createGrpcWebTransport } from "@connectrpc/connect-web";
|
|
5
|
+
/**
|
|
6
|
+
* Creates the public business transport: binary gRPC-Web only, unknown fields
|
|
7
|
+
* retained and the shared nesting bound. JSON selection is refused.
|
|
8
|
+
*/
|
|
9
|
+
export function createPublicGrpcWebTransport(options) {
|
|
10
|
+
const selected = options;
|
|
11
|
+
if (selected.useBinaryFormat !== undefined ||
|
|
12
|
+
selected.jsonOptions !== undefined ||
|
|
13
|
+
selected.binaryOptions !== undefined) {
|
|
14
|
+
throw new TypeError("Public ArcForges business calls use binary gRPC-Web with fixed codec options.");
|
|
15
|
+
}
|
|
16
|
+
return createGrpcWebTransport({
|
|
17
|
+
...options,
|
|
18
|
+
useBinaryFormat: true,
|
|
19
|
+
binaryOptions: { ...contractBinaryReadOptions, writeUnknownFields: true },
|
|
20
|
+
});
|
|
21
|
+
}
|
|
5
22
|
/** Creates the example client using the caller's gRPC-Web endpoint and fetch. */
|
|
6
23
|
export function createHelloClient(options) {
|
|
7
|
-
return createClient(HelloService,
|
|
24
|
+
return createClient(HelloService, createPublicGrpcWebTransport(options));
|
|
8
25
|
}
|
|
26
|
+
export * from "./gen/http.js";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface PackageInventory {
|
|
2
|
+
schemaVersion: string;
|
|
3
|
+
files: InventoryFile[];
|
|
4
|
+
}
|
|
5
|
+
export interface InventoryFile {
|
|
6
|
+
path: string;
|
|
7
|
+
size: string;
|
|
8
|
+
sha256: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function isPackageInventory(value: unknown): value is PackageInventory;
|
|
11
|
+
/** The schema's declared UTF-8 document bound in bytes. */
|
|
12
|
+
export declare const packageInventoryJsonMaxBytes = 4194304;
|
|
13
|
+
/** Parses one strict PackageInventory document; refusal kinds match the C# codec. */
|
|
14
|
+
export declare function tryParsePackageInventoryJson(input: Uint8Array | string): {
|
|
15
|
+
ok: true;
|
|
16
|
+
value: PackageInventory;
|
|
17
|
+
} | {
|
|
18
|
+
ok: false;
|
|
19
|
+
failure: "tooLarge" | "malformed" | "invalid";
|
|
20
|
+
};
|
|
21
|
+
/** Parses one strict PackageInventory document or throws an error carrying the refusal kind. */
|
|
22
|
+
export declare function parsePackageInventoryJson(input: Uint8Array | string): PackageInventory;
|
|
23
|
+
/** Writes compact UTF-8 in schema property order and refuses output the schema rejects. */
|
|
24
|
+
export declare function serializePackageInventoryJson(value: PackageInventory): Uint8Array;
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
export function isPackageInventory(value) { return check0(value); }
|
|
2
|
+
/** The schema's declared UTF-8 document bound in bytes. */
|
|
3
|
+
export const packageInventoryJsonMaxBytes = 4194304;
|
|
4
|
+
/** Parses one strict PackageInventory document; refusal kinds match the C# codec. */
|
|
5
|
+
export function tryParsePackageInventoryJson(input) {
|
|
6
|
+
const parsed = strictJson(input, 4194304);
|
|
7
|
+
if (!parsed.ok)
|
|
8
|
+
return parsed;
|
|
9
|
+
return isPackageInventory(parsed.value) ? { ok: true, value: parsed.value } : { ok: false, failure: "invalid" };
|
|
10
|
+
}
|
|
11
|
+
/** Parses one strict PackageInventory document or throws an error carrying the refusal kind. */
|
|
12
|
+
export function parsePackageInventoryJson(input) {
|
|
13
|
+
const result = tryParsePackageInventoryJson(input);
|
|
14
|
+
if (!result.ok)
|
|
15
|
+
throw Object.assign(new Error(`PackageInventory JSON refused: ${result.failure}.`), { failure: result.failure });
|
|
16
|
+
return result.value;
|
|
17
|
+
}
|
|
18
|
+
/** Writes compact UTF-8 in schema property order and refuses output the schema rejects. */
|
|
19
|
+
export function serializePackageInventoryJson(value) {
|
|
20
|
+
const bytes = new TextEncoder().encode(JSON.stringify(orderPackageInventory(value)));
|
|
21
|
+
const result = tryParsePackageInventoryJson(bytes);
|
|
22
|
+
if (!result.ok)
|
|
23
|
+
throw Object.assign(new Error(`PackageInventory JSON refused: ${result.failure}.`), { failure: result.failure });
|
|
24
|
+
return bytes;
|
|
25
|
+
}
|
|
26
|
+
function orderInventoryFile(value) {
|
|
27
|
+
const out = {};
|
|
28
|
+
out["path"] = value["path"];
|
|
29
|
+
out["size"] = value["size"];
|
|
30
|
+
out["sha256"] = value["sha256"];
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
function orderPackageInventory(value) {
|
|
34
|
+
const out = {};
|
|
35
|
+
out["schemaVersion"] = value["schemaVersion"];
|
|
36
|
+
out["files"] = value["files"].map(item => orderInventoryFile(item));
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
function check0(value) {
|
|
40
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
41
|
+
return false;
|
|
42
|
+
const object = value;
|
|
43
|
+
for (const key of Object.keys(object)) {
|
|
44
|
+
switch (key) {
|
|
45
|
+
case "schemaVersion":
|
|
46
|
+
if (!check1(object[key]))
|
|
47
|
+
return false;
|
|
48
|
+
break;
|
|
49
|
+
case "files":
|
|
50
|
+
if (!check2(object[key]))
|
|
51
|
+
return false;
|
|
52
|
+
break;
|
|
53
|
+
default: return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (!Object.prototype.hasOwnProperty.call(object, "schemaVersion"))
|
|
57
|
+
return false;
|
|
58
|
+
if (!Object.prototype.hasOwnProperty.call(object, "files"))
|
|
59
|
+
return false;
|
|
60
|
+
if (!inventoryRules(value))
|
|
61
|
+
return false;
|
|
62
|
+
if (!inventoryRules(value))
|
|
63
|
+
return false;
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
function check1(value) {
|
|
67
|
+
if (typeof value !== 'string' || !validText(value))
|
|
68
|
+
return false;
|
|
69
|
+
if (value !== "inventory.v1")
|
|
70
|
+
return false;
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
function check2(value) {
|
|
74
|
+
if (!Array.isArray(value))
|
|
75
|
+
return false;
|
|
76
|
+
if (value.length < 1)
|
|
77
|
+
return false;
|
|
78
|
+
if (value.length > 10000)
|
|
79
|
+
return false;
|
|
80
|
+
if (!value.every(item => check3(item)))
|
|
81
|
+
return false;
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
function check3(value) {
|
|
85
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
86
|
+
return false;
|
|
87
|
+
const object = value;
|
|
88
|
+
for (const key of Object.keys(object)) {
|
|
89
|
+
switch (key) {
|
|
90
|
+
case "path":
|
|
91
|
+
if (!check4(object[key]))
|
|
92
|
+
return false;
|
|
93
|
+
break;
|
|
94
|
+
case "size":
|
|
95
|
+
if (!check5(object[key]))
|
|
96
|
+
return false;
|
|
97
|
+
break;
|
|
98
|
+
case "sha256":
|
|
99
|
+
if (!check6(object[key]))
|
|
100
|
+
return false;
|
|
101
|
+
break;
|
|
102
|
+
default: return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (!Object.prototype.hasOwnProperty.call(object, "path"))
|
|
106
|
+
return false;
|
|
107
|
+
if (!Object.prototype.hasOwnProperty.call(object, "size"))
|
|
108
|
+
return false;
|
|
109
|
+
if (!Object.prototype.hasOwnProperty.call(object, "sha256"))
|
|
110
|
+
return false;
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
function check4(value) {
|
|
114
|
+
if (typeof value !== 'string' || !validText(value))
|
|
115
|
+
return false;
|
|
116
|
+
if ((new RegExp("^[A-Za-z0-9_.-]+(/[A-Za-z0-9_.-]+)*$", 'u')).exec(value)?.[0] !== value)
|
|
117
|
+
return false;
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
function check5(value) {
|
|
121
|
+
if (typeof value !== 'string' || !validText(value))
|
|
122
|
+
return false;
|
|
123
|
+
if ([...value].length > 20)
|
|
124
|
+
return false;
|
|
125
|
+
if ((new RegExp("^(0|[1-9][0-9]*)$", 'u')).exec(value)?.[0] !== value)
|
|
126
|
+
return false;
|
|
127
|
+
if (BigInt(value) > 18446744073709551615n)
|
|
128
|
+
return false;
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
function check6(value) {
|
|
132
|
+
if (typeof value !== 'string' || !validText(value))
|
|
133
|
+
return false;
|
|
134
|
+
if ((new RegExp("^[0-9a-f]{64}$", 'u')).exec(value)?.[0] !== value)
|
|
135
|
+
return false;
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
/** Strict UTF-8 JSON: no BOM, comments, trailing commas or duplicate properties; depth <= 32; integer lexemes only. */
|
|
139
|
+
function strictJson(input, maxBytes) {
|
|
140
|
+
let text;
|
|
141
|
+
if (typeof input === "string") {
|
|
142
|
+
if (!validText(input))
|
|
143
|
+
return { ok: false, failure: "malformed" };
|
|
144
|
+
if (new TextEncoder().encode(input).byteLength > maxBytes)
|
|
145
|
+
return { ok: false, failure: "tooLarge" };
|
|
146
|
+
text = input;
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
if (input.byteLength > maxBytes)
|
|
150
|
+
return { ok: false, failure: "tooLarge" };
|
|
151
|
+
try {
|
|
152
|
+
text = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(input);
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
return { ok: false, failure: "malformed" };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
return { ok: true, value: new StrictJsonReader(text).document() };
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return { ok: false, failure: "malformed" };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
class StrictJsonReader {
|
|
166
|
+
text;
|
|
167
|
+
index = 0;
|
|
168
|
+
constructor(text) {
|
|
169
|
+
this.text = text;
|
|
170
|
+
}
|
|
171
|
+
document() {
|
|
172
|
+
this.space();
|
|
173
|
+
const value = this.value(0);
|
|
174
|
+
this.space();
|
|
175
|
+
if (this.index !== this.text.length)
|
|
176
|
+
throw new SyntaxError("Trailing JSON content");
|
|
177
|
+
return value;
|
|
178
|
+
}
|
|
179
|
+
value(depth) {
|
|
180
|
+
switch (this.text[this.index]) {
|
|
181
|
+
case "{": return this.object(depth + 1);
|
|
182
|
+
case "[": return this.array(depth + 1);
|
|
183
|
+
case '"': return this.string();
|
|
184
|
+
case "t": return this.literal("true", true);
|
|
185
|
+
case "f": return this.literal("false", false);
|
|
186
|
+
case "n": return this.literal("null", null);
|
|
187
|
+
default: return this.number();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
object(depth) {
|
|
191
|
+
if (depth > 32)
|
|
192
|
+
throw new SyntaxError("JSON depth exceeded");
|
|
193
|
+
this.index++;
|
|
194
|
+
const out = {};
|
|
195
|
+
const keys = new Set();
|
|
196
|
+
this.space();
|
|
197
|
+
if (this.text[this.index] === "}") {
|
|
198
|
+
this.index++;
|
|
199
|
+
return out;
|
|
200
|
+
}
|
|
201
|
+
for (;;) {
|
|
202
|
+
this.space();
|
|
203
|
+
if (this.text[this.index] !== '"')
|
|
204
|
+
throw new SyntaxError("Expected property name");
|
|
205
|
+
const key = this.string();
|
|
206
|
+
if (keys.has(key))
|
|
207
|
+
throw new SyntaxError("Duplicate JSON property");
|
|
208
|
+
keys.add(key);
|
|
209
|
+
this.space();
|
|
210
|
+
if (this.text[this.index++] !== ":")
|
|
211
|
+
throw new SyntaxError("Expected colon");
|
|
212
|
+
this.space();
|
|
213
|
+
// defineProperty keeps names such as __proto__ as ordinary own properties.
|
|
214
|
+
Object.defineProperty(out, key, { value: this.value(depth), enumerable: true, writable: true, configurable: true });
|
|
215
|
+
this.space();
|
|
216
|
+
const next = this.text[this.index++];
|
|
217
|
+
if (next === "}")
|
|
218
|
+
return out;
|
|
219
|
+
if (next !== ",")
|
|
220
|
+
throw new SyntaxError("Expected comma");
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
array(depth) {
|
|
224
|
+
if (depth > 32)
|
|
225
|
+
throw new SyntaxError("JSON depth exceeded");
|
|
226
|
+
this.index++;
|
|
227
|
+
const out = [];
|
|
228
|
+
this.space();
|
|
229
|
+
if (this.text[this.index] === "]") {
|
|
230
|
+
this.index++;
|
|
231
|
+
return out;
|
|
232
|
+
}
|
|
233
|
+
for (;;) {
|
|
234
|
+
this.space();
|
|
235
|
+
out.push(this.value(depth));
|
|
236
|
+
this.space();
|
|
237
|
+
const next = this.text[this.index++];
|
|
238
|
+
if (next === "]")
|
|
239
|
+
return out;
|
|
240
|
+
if (next !== ",")
|
|
241
|
+
throw new SyntaxError("Expected comma");
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
string() {
|
|
245
|
+
this.index++;
|
|
246
|
+
let out = "";
|
|
247
|
+
for (;;) {
|
|
248
|
+
const c = this.text[this.index++];
|
|
249
|
+
if (c === undefined)
|
|
250
|
+
throw new SyntaxError("Unterminated string");
|
|
251
|
+
if (c === '"')
|
|
252
|
+
break;
|
|
253
|
+
if (c < " ")
|
|
254
|
+
throw new SyntaxError("Unescaped control character");
|
|
255
|
+
if (c !== "\\") {
|
|
256
|
+
out += c;
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
const e = this.text[this.index++];
|
|
260
|
+
const simple = { '"': '"', "\\": "\\", "/": "/", b: "\b", f: "\f", n: "\n", r: "\r", t: "\t" };
|
|
261
|
+
if (e !== undefined && e in simple) {
|
|
262
|
+
out += simple[e];
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
if (e !== "u" || !/^[0-9a-fA-F]{4}$/.test(this.text.slice(this.index, this.index + 4)))
|
|
266
|
+
throw new SyntaxError("Invalid escape");
|
|
267
|
+
out += String.fromCharCode(parseInt(this.text.slice(this.index, this.index + 4), 16));
|
|
268
|
+
this.index += 4;
|
|
269
|
+
}
|
|
270
|
+
if (!validText(out))
|
|
271
|
+
throw new SyntaxError("Lone surrogate escape");
|
|
272
|
+
return out;
|
|
273
|
+
}
|
|
274
|
+
number() {
|
|
275
|
+
const match = /-?(?:0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?/y;
|
|
276
|
+
match.lastIndex = this.index;
|
|
277
|
+
const found = match.exec(this.text);
|
|
278
|
+
if (found === null)
|
|
279
|
+
throw new SyntaxError("Invalid JSON value");
|
|
280
|
+
this.index = match.lastIndex;
|
|
281
|
+
// Selected schemas have no fractional numbers; fraction/exponent lexemes never satisfy an integer.
|
|
282
|
+
return found[1] !== undefined || found[2] !== undefined ? Number.NaN : Number(found[0]);
|
|
283
|
+
}
|
|
284
|
+
literal(word, value) {
|
|
285
|
+
if (this.text.slice(this.index, this.index + word.length) !== word)
|
|
286
|
+
throw new SyntaxError("Invalid JSON literal");
|
|
287
|
+
this.index += word.length;
|
|
288
|
+
return value;
|
|
289
|
+
}
|
|
290
|
+
space() {
|
|
291
|
+
while (this.text[this.index] === " " || this.text[this.index] === "\t" || this.text[this.index] === "\n" || this.text[this.index] === "\r")
|
|
292
|
+
this.index++;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
function validText(value) {
|
|
296
|
+
for (const scalar of value) {
|
|
297
|
+
const point = scalar.codePointAt(0);
|
|
298
|
+
if (point >= 0xd800 && point <= 0xdfff)
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
function inventoryRules(value) {
|
|
304
|
+
const files = value.files;
|
|
305
|
+
const seen = new Set();
|
|
306
|
+
let previous;
|
|
307
|
+
let total = 0n;
|
|
308
|
+
for (const file of files) {
|
|
309
|
+
const path = file.path;
|
|
310
|
+
const folded = path.toUpperCase();
|
|
311
|
+
if (path.length === 0 || folded === 'INVENTORY.JSON' || folded === 'SIGNATURE.JSON' || seen.has(folded) || (previous !== undefined && previous >= path))
|
|
312
|
+
return false;
|
|
313
|
+
for (const segment of path.split('/')) {
|
|
314
|
+
if (!/^[A-Za-z0-9_.-]+$/.test(segment) || segment === '.' || segment === '..' || segment.endsWith('.') || /^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(?:\.|$)/i.test(segment))
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
const size = BigInt(file.size);
|
|
318
|
+
if (size > 134217728n)
|
|
319
|
+
return false;
|
|
320
|
+
total += size;
|
|
321
|
+
if (total > 1073741824n)
|
|
322
|
+
return false;
|
|
323
|
+
seen.add(folded);
|
|
324
|
+
previous = path;
|
|
325
|
+
}
|
|
326
|
+
return files.some(file => file.path === 'manifest.json');
|
|
327
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface PartReceipt {
|
|
2
|
+
partNumber: number;
|
|
3
|
+
size: string;
|
|
4
|
+
sha256: string;
|
|
5
|
+
etag: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function isPartReceipt(value: unknown): value is PartReceipt;
|
|
8
|
+
/** The schema's declared UTF-8 document bound in bytes. */
|
|
9
|
+
export declare const partReceiptJsonMaxBytes = 65536;
|
|
10
|
+
/** Parses one strict PartReceipt document; refusal kinds match the C# codec. */
|
|
11
|
+
export declare function tryParsePartReceiptJson(input: Uint8Array | string): {
|
|
12
|
+
ok: true;
|
|
13
|
+
value: PartReceipt;
|
|
14
|
+
} | {
|
|
15
|
+
ok: false;
|
|
16
|
+
failure: "tooLarge" | "malformed" | "invalid";
|
|
17
|
+
};
|
|
18
|
+
/** Parses one strict PartReceipt document or throws an error carrying the refusal kind. */
|
|
19
|
+
export declare function parsePartReceiptJson(input: Uint8Array | string): PartReceipt;
|
|
20
|
+
/** Writes compact UTF-8 in schema property order and refuses output the schema rejects. */
|
|
21
|
+
export declare function serializePartReceiptJson(value: PartReceipt): Uint8Array;
|