@platforma-sdk/block-tools 2.3.0 → 2.3.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.
Files changed (35) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/cli.mjs +1 -1
  3. package/dist/{config-YukCegnp.mjs → config-BbxbO3Iw.mjs} +514 -500
  4. package/dist/config-BbxbO3Iw.mjs.map +1 -0
  5. package/dist/config-BczgUC2N.js +3 -0
  6. package/dist/config-BczgUC2N.js.map +1 -0
  7. package/dist/index.js +1 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +113 -99
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/io/folder_reader.d.ts +1 -15
  12. package/dist/io/folder_reader.d.ts.map +1 -1
  13. package/dist/util.d.ts +1 -0
  14. package/dist/util.d.ts.map +1 -1
  15. package/dist/v2/build_dist.d.ts.map +1 -1
  16. package/dist/v2/model/block_components.d.ts +297 -19
  17. package/dist/v2/model/block_components.d.ts.map +1 -1
  18. package/dist/v2/model/block_description.d.ts +281 -62
  19. package/dist/v2/model/block_description.d.ts.map +1 -1
  20. package/dist/v2/registry/registry.d.ts.map +1 -1
  21. package/dist/v2/registry/registry_reader.d.ts +6 -4
  22. package/dist/v2/registry/registry_reader.d.ts.map +1 -1
  23. package/dist/v2/registry/schema_public.d.ts +218 -100
  24. package/dist/v2/registry/schema_public.d.ts.map +1 -1
  25. package/package.json +2 -2
  26. package/src/io/folder_reader.ts +17 -9
  27. package/src/util.ts +6 -0
  28. package/src/v2/build_dist.ts +2 -1
  29. package/src/v2/model/block_components.ts +10 -8
  30. package/src/v2/registry/registry.ts +3 -6
  31. package/src/v2/registry/registry_reader.ts +25 -15
  32. package/src/v2/registry/schema_public.ts +5 -1
  33. package/dist/config-B1U40s2a.js +0 -3
  34. package/dist/config-B1U40s2a.js.map +0 -1
  35. package/dist/config-YukCegnp.mjs.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,35 +1,35 @@
1
1
  var d = Object.defineProperty;
2
2
  var g = (t, e, a) => e in t ? d(t, e, { enumerable: !0, configurable: !0, writable: !0, value: a }) : t[e] = a;
3
3
  var i = (t, e, a) => g(t, typeof e != "symbol" ? e + "" : e, a);
4
- import { e as h, f as m, G as f, h as v, i as k, j as P, k as u, m as w, n as R, o as B, p as y, q as b, P as C, r as F, t as D, u as M } from "./config-YukCegnp.mjs";
5
- import { N as X, L as Z, U as ee, a5 as ae, Q as te, T as oe, J as se, a as re, B as ie, K as le, d as ne, F as ce, a4 as pe, a2 as de, a3 as ge, a1 as he, a7 as me, a6 as fe, M as ve, Z as ke, $ as Pe, X as ue, _ as we, O as Re, R as Be, v as ye, S as be, y as Ce, z as Fe, x as De, c as Me, A as Oe, b as Te, l as xe, w as Se, C as Ee, Y as Ge, a0 as Ue, V as Ae, E as je, H as Le, I as Ve, D as Ne, s as Je, W as ze } from "./config-YukCegnp.mjs";
6
- import { request as O, Agent as T } from "undici";
7
- import s from "node:path";
8
- import r from "node:path/posix";
9
- import x from "node:fs/promises";
10
- import S from "canonicalize";
4
+ import { e as f, f as m, G as h, h as v, p as k, M as P, i as R, j as u, k as w, m as B, n as y, o as C, q as F, r as b, t as M, P as O, u as S, v as x, w as D } from "./config-BbxbO3Iw.mjs";
5
+ import { Q as te, O as oe, W as re, a7 as se, U as ie, V as le, L as ne, a as ce, B as pe, N as de, d as ge, F as fe, a6 as me, a4 as he, a5 as ve, a3 as ke, a9 as Pe, a8 as Re, $ as ue, a1 as we, Z as Be, a0 as ye, T as Ce, R as Fe, x as be, S as Me, A as Oe, C as Se, z as xe, c as De, D as Te, b as Ue, l as Ee, y as Ge, E as Ae, _ as Le, a2 as Ve, X as je, I as Ne, J as Je, K as ze, H as _e, s as $e, Y as qe } from "./config-BbxbO3Iw.mjs";
6
+ import { Agent as T, request as U } from "undici";
7
+ import r from "node:path";
8
+ import s from "node:path/posix";
9
+ import E from "node:fs/promises";
10
+ import { BlockPackManifest as G } from "@milaboratories/pl-model-middle-layer";
11
+ import A from "canonicalize";
11
12
  import "zod";
12
13
  import "mime-types";
13
14
  import "tar";
14
15
  import "@milaboratories/resolve-helper";
15
- import "@milaboratories/pl-model-middle-layer";
16
- class H {
17
- constructor(e, a) {
16
+ class Q {
17
+ constructor(e) {
18
18
  i(this, "metaCache", /* @__PURE__ */ new Map());
19
- i(this, "rootFolderReader");
20
- this.url = e, this.rootFolderReader = a.relativeReader(h);
19
+ i(this, "v2RootFolderReader");
20
+ this.registryReader = e, this.v2RootFolderReader = e.relativeReader(f);
21
21
  }
22
22
  async embedMetaContent(e) {
23
- const a = S(e.id), o = this.metaCache.get(a);
23
+ const a = A(e.id), o = this.metaCache.get(a);
24
24
  if (o && o.sha256 === e.latestManifestSha256) return o.meta;
25
- const p = this.rootFolderReader.getContentReader(), c = await m(p).parseAsync(e.latest.meta);
25
+ const p = this.v2RootFolderReader.getContentReader(), c = await m(p).parseAsync(e.latest.meta);
26
26
  return this.metaCache.set(a, { sha256: e.latestManifestSha256, meta: c }), c;
27
27
  }
28
28
  async listBlockPacks() {
29
- this.rootFolderReader.getContentReader();
30
- const e = f.parse(
29
+ this.v2RootFolderReader.getContentReader();
30
+ const e = h.parse(
31
31
  JSON.parse(
32
- Buffer.from(await this.rootFolderReader.readFile(v)).toString()
32
+ Buffer.from(await this.v2RootFolderReader.readFile(v)).toString()
33
33
  )
34
34
  );
35
35
  return await Promise.all(
@@ -40,41 +40,51 @@ class H {
40
40
  spec: {
41
41
  type: "from-registry-v2",
42
42
  id: a.latest.id,
43
- registryUrl: this.url
43
+ registryUrl: this.registryReader.rootUrl.toString()
44
44
  },
45
45
  otherVersions: a.allVersions
46
46
  })
47
47
  )
48
48
  );
49
49
  }
50
+ async getComponents(e) {
51
+ const a = this.v2RootFolderReader.relativeReader(
52
+ k(e)
53
+ ), o = G.parse(
54
+ JSON.parse(Buffer.from(await a.readFile(P)).toString())
55
+ );
56
+ return R(a.rootUrl.toString()).parse(
57
+ o.description.components
58
+ );
59
+ }
50
60
  }
51
- const I = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
61
+ const X = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
52
62
  __proto__: null,
53
- GlobalOverviewPath: k,
54
- MetaFile: P,
55
- PlPackageConfigData: u,
56
- PlPackageJsonConfigFile: w,
57
- PlPackageYamlConfigFile: R,
58
- PlRegCommonConfigData: B,
59
- PlRegFullPackageConfigData: y,
60
- PlRegPackageConfig: b,
61
- PlRegPackageConfigDataShard: C,
62
- packageContentPrefix: F,
63
- packageOverviewPath: D,
64
- payloadFilePath: M
63
+ GlobalOverviewPath: u,
64
+ MetaFile: w,
65
+ PlPackageConfigData: B,
66
+ PlPackageJsonConfigFile: y,
67
+ PlPackageYamlConfigFile: C,
68
+ PlRegCommonConfigData: F,
69
+ PlRegFullPackageConfigData: b,
70
+ PlRegPackageConfig: M,
71
+ PlRegPackageConfigDataShard: O,
72
+ packageContentPrefix: S,
73
+ packageOverviewPath: x,
74
+ payloadFilePath: D
65
75
  }, Symbol.toStringTag, { value: "Module" }));
66
76
  class l {
67
77
  constructor(e, a) {
68
- this.root = e, this.httpDispatcher = a;
78
+ this.rootUrl = e, this.httpDispatcher = a;
69
79
  }
70
80
  async readFile(e) {
71
- const a = new URL(e, this.root), o = await O(a, {
81
+ const a = new URL(e, this.rootUrl), o = await U(a, {
72
82
  dispatcher: this.httpDispatcher
73
83
  });
74
84
  return Buffer.from(await o.body.arrayBuffer());
75
85
  }
76
86
  relativeReader(e) {
77
- return new l(new URL(e, this.root), this.httpDispatcher);
87
+ return new l(new URL(e, this.rootUrl), this.httpDispatcher);
78
88
  }
79
89
  getContentReader(e) {
80
90
  let a = this;
@@ -82,33 +92,37 @@ class l {
82
92
  }
83
93
  }
84
94
  class n {
85
- constructor(e) {
86
- this.root = e;
95
+ constructor(e, a) {
96
+ this.rootUrl = e, this.root = a;
87
97
  }
88
98
  async readFile(e) {
89
- const a = s.join(this.root, ...e.split(r.sep));
90
- return await x.readFile(a);
99
+ const a = r.join(this.root, ...e.split(s.sep));
100
+ return await E.readFile(a);
91
101
  }
92
102
  relativeReader(e) {
93
- return new n(s.join(this.root, ...e.split(r.sep)));
103
+ return new n(
104
+ new URL(e, this.rootUrl),
105
+ r.join(this.root, ...e.split(s.sep))
106
+ );
94
107
  }
95
108
  getContentReader(e) {
96
109
  let a = this;
97
110
  return e !== void 0 && (a = a.relativeReader(e)), (o) => a.readFile(o);
98
111
  }
99
112
  }
100
- function E(t) {
101
- return t.split(r.sep).join(s.sep);
102
- }
103
- function G(t) {
113
+ function L(t) {
104
114
  return t.split(s.sep).join(r.sep);
105
115
  }
106
- function K(t, e) {
107
- const a = new URL(t, `file:${G(s.resolve("."))}/`);
116
+ function V(t) {
117
+ return t.split(r.sep).join(s.sep);
118
+ }
119
+ function Z(t, e) {
120
+ t.endsWith("/") || (t = t + "/");
121
+ const a = new URL(t, `file:${V(r.resolve("."))}/`);
108
122
  switch (a.protocol) {
109
123
  case "file:":
110
- const o = E(a.pathname);
111
- return new n(o);
124
+ const o = L(a.pathname);
125
+ return new n(a, o);
112
126
  case "https:":
113
127
  case "http:":
114
128
  return new l(a, e ?? new T());
@@ -117,59 +131,59 @@ function K(t, e) {
117
131
  }
118
132
  }
119
133
  export {
120
- X as BlockComponentsConsolidate,
121
- Z as BlockComponentsDescription,
122
- ee as BlockDescriptionPackageJsonField,
123
- ae as BlockDescriptionToExplicitBinaryBytes,
124
- te as BlockPackDescriptionConsolidateToFolder,
125
- oe as BlockPackDescriptionManifestAddRelativePathPrefix,
126
- se as BlockPackMetaConsolidate,
127
- re as BlockPackMetaDescription,
128
- ie as BlockPackMetaEmbedAbsoluteBase64,
129
- le as BlockPackMetaEmbedAbsoluteBytes,
134
+ R as BlockComponentsAbsoluteUrl,
135
+ te as BlockComponentsConsolidate,
136
+ oe as BlockComponentsDescription,
137
+ re as BlockDescriptionPackageJsonField,
138
+ se as BlockDescriptionToExplicitBinaryBytes,
139
+ ie as BlockPackDescriptionConsolidateToFolder,
140
+ le as BlockPackDescriptionManifestAddRelativePathPrefix,
141
+ ne as BlockPackMetaConsolidate,
142
+ ce as BlockPackMetaDescription,
143
+ pe as BlockPackMetaEmbedAbsoluteBase64,
144
+ de as BlockPackMetaEmbedAbsoluteBytes,
130
145
  m as BlockPackMetaEmbedBytes,
131
- ne as BlockRegistryV2,
132
- n as FSFolderReader,
133
- ce as FSStorage,
134
- pe as GlobalOverview,
135
- de as GlobalOverviewEntry,
136
- ge as GlobalOverviewEntryReg,
146
+ ge as BlockRegistryV2,
147
+ fe as FSStorage,
148
+ me as GlobalOverview,
149
+ he as GlobalOverviewEntry,
150
+ ve as GlobalOverviewEntryReg,
137
151
  v as GlobalOverviewFileName,
138
- he as GlobalOverviewPath,
139
- f as GlobalOverviewReg,
140
- me as GlobalOverviewToExplicitBinaryBase64,
141
- fe as GlobalOverviewToExplicitBinaryBytes,
142
- l as HttpFolderReader,
143
- h as MainPrefix,
144
- ve as ManifestFileName,
145
- ke as ManifestSuffix,
146
- Pe as PackageOverview,
147
- ue as PackageOverviewFileName,
148
- we as PackageOverviewVersionEntry,
149
- I as RegistryV1,
150
- H as RegistryV2Reader,
151
- Re as ResolvedBlockPackDescriptionFromPackageJson,
152
- Be as ResolvedModuleFile,
153
- ye as ResolvedModuleFolder,
154
- be as S3Storage,
155
- Ce as absoluteToBase64,
156
- Fe as absoluteToBytes,
157
- De as absoluteToString,
158
- Me as buildBlockPackDist,
159
- Oe as cpAbsoluteToRelative,
160
- K as folderReaderByUrl,
161
- Te as loadPackDescription,
162
- xe as loadPackDescriptionRaw,
163
- Se as mapLocalToAbsolute,
164
- Ee as packFolderToRelativeTgz,
165
- Ge as packageContentPrefix,
166
- Ue as packageOverviewPath,
167
- Ae as parsePackageName,
168
- je as relativeToContentString,
169
- Le as relativeToExplicitBinary64,
170
- Ve as relativeToExplicitBytes,
171
- Ne as relativeToExplicitString,
172
- Je as storageByUrl,
173
- ze as tryLoadPackDescription
152
+ ke as GlobalOverviewPath,
153
+ h as GlobalOverviewReg,
154
+ Pe as GlobalOverviewToExplicitBinaryBase64,
155
+ Re as GlobalOverviewToExplicitBinaryBytes,
156
+ f as MainPrefix,
157
+ P as ManifestFileName,
158
+ ue as ManifestSuffix,
159
+ we as PackageOverview,
160
+ Be as PackageOverviewFileName,
161
+ ye as PackageOverviewVersionEntry,
162
+ X as RegistryV1,
163
+ Q as RegistryV2Reader,
164
+ Ce as ResolvedBlockPackDescriptionFromPackageJson,
165
+ Fe as ResolvedModuleFile,
166
+ be as ResolvedModuleFolder,
167
+ Me as S3Storage,
168
+ Oe as absoluteToBase64,
169
+ Se as absoluteToBytes,
170
+ xe as absoluteToString,
171
+ De as buildBlockPackDist,
172
+ Te as cpAbsoluteToRelative,
173
+ Z as folderReaderByUrl,
174
+ Ue as loadPackDescription,
175
+ Ee as loadPackDescriptionRaw,
176
+ Ge as mapLocalToAbsolute,
177
+ Ae as packFolderToRelativeTgz,
178
+ Le as packageContentPrefix,
179
+ k as packageContentPrefixInsideV2,
180
+ Ve as packageOverviewPath,
181
+ je as parsePackageName,
182
+ Ne as relativeToContentString,
183
+ Je as relativeToExplicitBinary64,
184
+ ze as relativeToExplicitBytes,
185
+ _e as relativeToExplicitString,
186
+ $e as storageByUrl,
187
+ qe as tryLoadPackDescription
174
188
  };
175
189
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/v2/registry/registry_reader.ts","../src/io/folder_reader.ts"],"sourcesContent":["import {\n BlockPackDescriptionManifest,\n BlockPackMetaEmbeddedBytes,\n BlockPackMetaManifest,\n BlockPackOverview\n} from '@milaboratories/pl-model-middle-layer';\nimport { FolderReader } from '../../io';\nimport canonicalize from 'canonicalize';\nimport {\n GlobalOverview,\n GlobalOverviewEntryReg,\n GlobalOverviewFileName,\n GlobalOverviewReg,\n MainPrefix,\n ManifestFileName\n} from './schema_public';\nimport { BlockPackMetaEmbedBytes } from '../model';\n\nexport type BlockPackOverviewNoRegLabel = Omit<BlockPackOverview, 'registryId'>;\n\nexport class RegistryV2Reader {\n private readonly metaCache = new Map<\n string,\n { sha256: string; meta: BlockPackMetaEmbeddedBytes }\n >();\n\n private readonly rootFolderReader: FolderReader;\n\n constructor(\n private readonly url: string,\n reader: FolderReader\n ) {\n this.rootFolderReader = reader.relativeReader(MainPrefix);\n }\n\n private async embedMetaContent(\n entry: GlobalOverviewEntryReg\n ): Promise<BlockPackMetaEmbeddedBytes> {\n const id = canonicalize(entry.id)!;\n const fromCache = this.metaCache.get(id);\n if (fromCache && fromCache.sha256 === entry.latestManifestSha256) return fromCache.meta;\n const rootContentReader = this.rootFolderReader.getContentReader();\n const meta = await BlockPackMetaEmbedBytes(rootContentReader).parseAsync(entry.latest.meta);\n this.metaCache.set(id, { sha256: entry.latestManifestSha256, meta });\n return meta;\n }\n\n public async listBlockPacks(): Promise<BlockPackOverviewNoRegLabel[]> {\n const rootContentReader = this.rootFolderReader.getContentReader();\n const globalOverview = GlobalOverviewReg.parse(\n JSON.parse(\n Buffer.from(await this.rootFolderReader.readFile(GlobalOverviewFileName)).toString()\n )\n );\n return await Promise.all(\n globalOverview.packages.map(\n async (p) =>\n ({\n id: p.latest.id,\n meta: await this.embedMetaContent(p),\n spec: {\n type: 'from-registry-v2',\n id: p.latest.id,\n registryUrl: this.url\n },\n otherVersions: p.allVersions\n }) satisfies BlockPackOverviewNoRegLabel\n )\n );\n }\n}\n","import { Agent, Dispatcher, request } from 'undici';\nimport { RelativeContentReader } from '../v2';\nimport path from 'node:path';\nimport pathPosix from 'node:path/posix';\nimport fsp from 'node:fs/promises';\n\nexport interface FolderReader {\n relativeReader(relativePath: string): FolderReader;\n readFile(file: string): Promise<Buffer>;\n getContentReader(relativePath?: string): RelativeContentReader;\n}\n\nexport class HttpFolderReader implements FolderReader {\n constructor(\n private readonly root: URL,\n private readonly httpDispatcher: Dispatcher\n ) {}\n\n public async readFile(file: string): Promise<Buffer> {\n const targetUrl = new URL(file, this.root);\n const response = await request(targetUrl, {\n dispatcher: this.httpDispatcher\n });\n return Buffer.from(await response.body.arrayBuffer());\n }\n\n public relativeReader(relativePath: string): HttpFolderReader {\n return new HttpFolderReader(new URL(relativePath, this.root), this.httpDispatcher);\n }\n\n public getContentReader(relativePath?: string): RelativeContentReader {\n let reader: HttpFolderReader = this;\n if (relativePath !== undefined) reader = reader.relativeReader(relativePath);\n return (path) => reader.readFile(path);\n }\n}\n\nexport class FSFolderReader implements FolderReader {\n constructor(private readonly root: string) {}\n\n public async readFile(file: string): Promise<Buffer> {\n const targetPath = path.join(this.root, ...file.split(pathPosix.sep));\n return await fsp.readFile(targetPath);\n }\n\n public relativeReader(relativePath: string): FSFolderReader {\n return new FSFolderReader(path.join(this.root, ...relativePath.split(pathPosix.sep)));\n }\n\n public getContentReader(relativePath?: string): RelativeContentReader {\n let reader: FSFolderReader = this;\n if (relativePath !== undefined) reader = reader.relativeReader(relativePath);\n return (path) => reader.readFile(path);\n }\n}\n\nfunction posixToLocalPath(p: string): string {\n return p.split(pathPosix.sep).join(path.sep);\n}\n\nfunction localToPosix(p: string): string {\n return p.split(path.sep).join(pathPosix.sep);\n}\n\nexport function folderReaderByUrl(address: string, httpDispatcher?: Dispatcher): FolderReader {\n const url = new URL(address, `file:${localToPosix(path.resolve('.'))}/`);\n switch (url.protocol) {\n case 'file:':\n const root = posixToLocalPath(url.pathname);\n return new FSFolderReader(root);\n case 'https:':\n case 'http:':\n return new HttpFolderReader(url, httpDispatcher ?? new Agent());\n default:\n throw new Error(`Unknown protocol: ${url.protocol}`);\n }\n}\n"],"names":["RegistryV2Reader","url","reader","__publicField","MainPrefix","entry","id","canonicalize","fromCache","rootContentReader","meta","BlockPackMetaEmbedBytes","globalOverview","GlobalOverviewReg","GlobalOverviewFileName","p","HttpFolderReader","root","httpDispatcher","file","targetUrl","response","request","relativePath","path","FSFolderReader","targetPath","pathPosix","fsp","posixToLocalPath","localToPosix","folderReaderByUrl","address","Agent"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/v2/registry/registry_reader.ts","../src/io/folder_reader.ts"],"sourcesContent":["import {\n BlockPackId,\n BlockPackManifest,\n BlockPackMetaEmbeddedBytes,\n BlockPackOverview\n} from '@milaboratories/pl-model-middle-layer';\nimport { FolderReader } from '../../io';\nimport canonicalize from 'canonicalize';\nimport {\n GlobalOverviewEntryReg,\n GlobalOverviewFileName,\n GlobalOverviewReg,\n MainPrefix,\n ManifestFileName,\n packageContentPrefix,\n packageContentPrefixInsideV2\n} from './schema_public';\nimport { BlockComponentsAbsoluteUrl, BlockPackMetaEmbedBytes } from '../model';\n\nexport type BlockPackOverviewNoRegLabel = Omit<BlockPackOverview, 'registryId'>;\n\nexport class RegistryV2Reader {\n private readonly metaCache = new Map<\n string,\n { sha256: string; meta: BlockPackMetaEmbeddedBytes }\n >();\n\n private readonly v2RootFolderReader: FolderReader;\n\n constructor(private readonly registryReader: FolderReader) {\n this.v2RootFolderReader = registryReader.relativeReader(MainPrefix);\n }\n\n private async embedMetaContent(\n entry: GlobalOverviewEntryReg\n ): Promise<BlockPackMetaEmbeddedBytes> {\n const id = canonicalize(entry.id)!;\n const fromCache = this.metaCache.get(id);\n if (fromCache && fromCache.sha256 === entry.latestManifestSha256) return fromCache.meta;\n const rootContentReader = this.v2RootFolderReader.getContentReader();\n const meta = await BlockPackMetaEmbedBytes(rootContentReader).parseAsync(entry.latest.meta);\n this.metaCache.set(id, { sha256: entry.latestManifestSha256, meta });\n return meta;\n }\n\n public async listBlockPacks(): Promise<BlockPackOverviewNoRegLabel[]> {\n const rootContentReader = this.v2RootFolderReader.getContentReader();\n const globalOverview = GlobalOverviewReg.parse(\n JSON.parse(\n Buffer.from(await this.v2RootFolderReader.readFile(GlobalOverviewFileName)).toString()\n )\n );\n return await Promise.all(\n globalOverview.packages.map(\n async (p) =>\n ({\n id: p.latest.id,\n meta: await this.embedMetaContent(p),\n spec: {\n type: 'from-registry-v2',\n id: p.latest.id,\n registryUrl: this.registryReader.rootUrl.toString()\n },\n otherVersions: p.allVersions\n }) satisfies BlockPackOverviewNoRegLabel\n )\n );\n }\n\n public async getComponents(id: BlockPackId): Promise<BlockComponentsAbsoluteUrl> {\n const packageFolderReader = this.v2RootFolderReader.relativeReader(\n packageContentPrefixInsideV2(id)\n );\n const manifest = BlockPackManifest.parse(\n JSON.parse(Buffer.from(await packageFolderReader.readFile(ManifestFileName)).toString())\n );\n return BlockComponentsAbsoluteUrl(packageFolderReader.rootUrl.toString()).parse(\n manifest.description.components\n );\n }\n}\n","import { Agent, Dispatcher, request } from 'undici';\nimport { RelativeContentReader } from '../v2';\nimport path from 'node:path';\nimport pathPosix from 'node:path/posix';\nimport fsp from 'node:fs/promises';\n\nexport interface FolderReader {\n readonly rootUrl: URL;\n relativeReader(relativePath: string): FolderReader;\n readFile(file: string): Promise<Buffer>;\n getContentReader(relativePath?: string): RelativeContentReader;\n}\n\nclass HttpFolderReader implements FolderReader {\n constructor(\n public readonly rootUrl: URL,\n private readonly httpDispatcher: Dispatcher\n ) {}\n\n public async readFile(file: string): Promise<Buffer> {\n const targetUrl = new URL(file, this.rootUrl);\n const response = await request(targetUrl, {\n dispatcher: this.httpDispatcher\n });\n return Buffer.from(await response.body.arrayBuffer());\n }\n\n public relativeReader(relativePath: string): HttpFolderReader {\n return new HttpFolderReader(new URL(relativePath, this.rootUrl), this.httpDispatcher);\n }\n\n public getContentReader(relativePath?: string): RelativeContentReader {\n let reader: HttpFolderReader = this;\n if (relativePath !== undefined) reader = reader.relativeReader(relativePath);\n return (path) => reader.readFile(path);\n }\n}\n\nclass FSFolderReader implements FolderReader {\n constructor(\n public readonly rootUrl: URL,\n private readonly root: string\n ) {}\n\n public async readFile(file: string): Promise<Buffer> {\n const targetPath = path.join(this.root, ...file.split(pathPosix.sep));\n return await fsp.readFile(targetPath);\n }\n\n public relativeReader(relativePath: string): FSFolderReader {\n return new FSFolderReader(\n new URL(relativePath, this.rootUrl),\n path.join(this.root, ...relativePath.split(pathPosix.sep))\n );\n }\n\n public getContentReader(relativePath?: string): RelativeContentReader {\n let reader: FSFolderReader = this;\n if (relativePath !== undefined) reader = reader.relativeReader(relativePath);\n return (path) => reader.readFile(path);\n }\n}\n\nfunction posixToLocalPath(p: string): string {\n return p.split(pathPosix.sep).join(path.sep);\n}\n\nfunction localToPosix(p: string): string {\n return p.split(path.sep).join(pathPosix.sep);\n}\n\nexport function folderReaderByUrl(address: string, httpDispatcher?: Dispatcher): FolderReader {\n if (!address.endsWith('/')) address = address + '/';\n const url = new URL(address, `file:${localToPosix(path.resolve('.'))}/`);\n switch (url.protocol) {\n case 'file:':\n const rootPath = posixToLocalPath(url.pathname);\n return new FSFolderReader(url, rootPath);\n case 'https:':\n case 'http:':\n return new HttpFolderReader(url, httpDispatcher ?? new Agent());\n default:\n throw new Error(`Unknown protocol: ${url.protocol}`);\n }\n}\n"],"names":["RegistryV2Reader","registryReader","__publicField","MainPrefix","entry","id","canonicalize","fromCache","rootContentReader","meta","BlockPackMetaEmbedBytes","globalOverview","GlobalOverviewReg","GlobalOverviewFileName","p","packageFolderReader","packageContentPrefixInsideV2","manifest","BlockPackManifest","ManifestFileName","BlockComponentsAbsoluteUrl","HttpFolderReader","rootUrl","httpDispatcher","file","targetUrl","response","request","relativePath","reader","path","FSFolderReader","root","targetPath","pathPosix","fsp","posixToLocalPath","localToPosix","folderReaderByUrl","address","url","rootPath","Agent"],"mappings":"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"}
@@ -1,24 +1,10 @@
1
1
  import { Dispatcher } from 'undici';
2
2
  import { RelativeContentReader } from '../v2';
3
3
  export interface FolderReader {
4
+ readonly rootUrl: URL;
4
5
  relativeReader(relativePath: string): FolderReader;
5
6
  readFile(file: string): Promise<Buffer>;
6
7
  getContentReader(relativePath?: string): RelativeContentReader;
7
8
  }
8
- export declare class HttpFolderReader implements FolderReader {
9
- private readonly root;
10
- private readonly httpDispatcher;
11
- constructor(root: URL, httpDispatcher: Dispatcher);
12
- readFile(file: string): Promise<Buffer>;
13
- relativeReader(relativePath: string): HttpFolderReader;
14
- getContentReader(relativePath?: string): RelativeContentReader;
15
- }
16
- export declare class FSFolderReader implements FolderReader {
17
- private readonly root;
18
- constructor(root: string);
19
- readFile(file: string): Promise<Buffer>;
20
- relativeReader(relativePath: string): FSFolderReader;
21
- getContentReader(relativePath?: string): RelativeContentReader;
22
- }
23
9
  export declare function folderReaderByUrl(address: string, httpDispatcher?: Dispatcher): FolderReader;
24
10
  //# sourceMappingURL=folder_reader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"folder_reader.d.ts","sourceRoot":"","sources":["../../src/io/folder_reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,UAAU,EAAW,MAAM,QAAQ,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAK9C,MAAM,WAAW,YAAY;IAC3B,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,YAAY,CAAC;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,gBAAgB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,qBAAqB,CAAC;CAChE;AAED,qBAAa,gBAAiB,YAAW,YAAY;IAEjD,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,cAAc;gBADd,IAAI,EAAE,GAAG,EACT,cAAc,EAAE,UAAU;IAGhC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ7C,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,gBAAgB;IAItD,gBAAgB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,qBAAqB;CAKtE;AAED,qBAAa,cAAe,YAAW,YAAY;IACrC,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,MAAM;IAE5B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK7C,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,cAAc;IAIpD,gBAAgB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,qBAAqB;CAKtE;AAUD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,UAAU,GAAG,YAAY,CAY5F"}
1
+ {"version":3,"file":"folder_reader.d.ts","sourceRoot":"","sources":["../../src/io/folder_reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,UAAU,EAAW,MAAM,QAAQ,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAK9C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC;IACtB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,YAAY,CAAC;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,gBAAgB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,qBAAqB,CAAC;CAChE;AA4DD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,UAAU,GAAG,YAAY,CAa5F"}
package/dist/util.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { BigIntStats } from 'node:fs';
2
2
  export declare function tryLoadFile<T>(file: string, map: (buf: Buffer) => T): Promise<T | undefined>;
3
3
  export declare function tryStat(path: string): Promise<BigIntStats | undefined>;
4
+ export declare function calculateSha256(bytes: ArrayBuffer): Promise<string>;
4
5
  //# sourceMappingURL=util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGtC,wBAAsB,WAAW,CAAC,CAAC,EACjC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC,GACtB,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAOxB;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAS5E"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGtC,wBAAsB,WAAW,CAAC,CAAC,EACjC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC,GACtB,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAOxB;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAS5E;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,WAAW,mBAIvD"}
@@ -1 +1 @@
1
- {"version":3,"file":"build_dist.d.ts","sourceRoot":"","sources":["../../src/v2/build_dist.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,iBAAiB,EAGlB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,4BAA4B,EAA2C,MAAM,SAAS,CAAC;AAIhG,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,4BAA4B,EACzC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,iBAAiB,CAAC,CAmB5B"}
1
+ {"version":3,"file":"build_dist.d.ts","sourceRoot":"","sources":["../../src/v2/build_dist.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,iBAAiB,EAGlB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,4BAA4B,EAA2C,MAAM,SAAS,CAAC;AAKhG,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,4BAA4B,EACzC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,iBAAiB,CAAC,CAmB5B"}