@platforma-sdk/block-tools 2.6.27 → 2.6.29
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/cli.js +3 -3
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +15 -13
- package/dist/cli.mjs.map +1 -1
- package/dist/{config-XBQ2O39y.mjs → config-DKBY0B2u.mjs} +272 -273
- package/dist/config-DKBY0B2u.mjs.map +1 -0
- package/dist/config-Ycas5fbX.js +3 -0
- package/dist/config-Ycas5fbX.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +18 -17
- package/dist/index.mjs.map +1 -1
- package/dist/registry_v1/v1_repo_schema.d.ts +2 -2
- package/package.json +18 -15
- package/src/cmd/build-meta.ts +9 -9
- package/src/cmd/build-model.ts +20 -16
- package/src/cmd/index.ts +0 -1
- package/src/cmd/list-overview-snapshots.ts +5 -5
- package/src/cmd/mark-stable.ts +14 -15
- package/src/cmd/pack.ts +7 -7
- package/src/cmd/publish.ts +16 -16
- package/src/cmd/refresh-registry.ts +4 -10
- package/src/cmd/restore-overview-from-snapshot.ts +16 -16
- package/src/cmd/update-deps.ts +3 -2
- package/src/cmd/upload-package-v1.ts +12 -12
- package/src/io/folder_reader.ts +15 -11
- package/src/io/storage.ts +25 -23
- package/src/registry_v1/config.ts +11 -10
- package/src/registry_v1/config_schema.ts +5 -5
- package/src/registry_v1/flags.ts +3 -2
- package/src/registry_v1/registry.ts +34 -35
- package/src/registry_v1/v1_repo_schema.ts +2 -2
- package/src/util.ts +15 -11
- package/src/v2/build_dist.ts +12 -9
- package/src/v2/model/block_components.ts +6 -6
- package/src/v2/model/block_description.ts +13 -13
- package/src/v2/model/block_meta.ts +10 -9
- package/src/v2/model/content_conversion.ts +28 -26
- package/src/v2/registry/index.ts +3 -3
- package/src/v2/registry/registry.test.ts +1 -1
- package/src/v2/registry/registry.ts +64 -63
- package/src/v2/registry/registry_reader.ts +47 -46
- package/src/v2/registry/schema_internal.ts +3 -3
- package/src/v2/registry/schema_public.ts +29 -26
- package/src/v2/source_package.ts +26 -23
- package/dist/config-DjpRXRy9.js +0 -3
- package/dist/config-DjpRXRy9.js.map +0 -1
- package/dist/config-XBQ2O39y.mjs.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/v2/registry/registry_reader.ts","../src/io/folder_reader.ts"],"sourcesContent":["import {\n BlockPackId,\n BlockPackIdNoVersion,\n blockPackIdNoVersionEquals,\n BlockPackManifest,\n BlockPackMetaEmbeddedBytes,\n BlockPackMetaManifest,\n BlockPackOverview,\n UpdateSuggestions,\n SingleBlockPackOverview,\n AnyChannel,\n BlockPackOverviewNoRegistryId\n} from '@milaboratories/pl-model-middle-layer';\nimport { FolderReader } from '../../io';\nimport canonicalize from 'canonicalize';\nimport {\n GlobalOverviewFileName,\n GlobalOverviewReg,\n MainPrefix,\n ManifestFileName,\n ManifestSuffix,\n packageContentPrefixInsideV2\n} from './schema_public';\nimport { BlockComponentsAbsoluteUrl, BlockPackMetaEmbedBytes } from '../model';\nimport { LRUCache } from 'lru-cache';\nimport semver from 'semver';\nimport { calculateSha256 } from '../../util';\nimport { retry, Retry2TimesWithDelay } from '@milaboratories/ts-helpers';\n\nexport type RegistryV2ReaderOps = {\n /** Number of milliseconds to cache retrieved block list for */\n cacheBlockListFor: number;\n /** Number of milliseconds to keep cached retrieved block list for, if new requests returns error */\n keepStaleBlockListFor: number;\n};\n\nconst DefaultRegistryV2ReaderOps: RegistryV2ReaderOps = {\n cacheBlockListFor: 45e3, // 45 seconds\n keepStaleBlockListFor: 300e3 // 5 minutes\n};\n\n/** @param availableVersions must be reverse sorted (from highest version to lowest) */\nexport function inferUpdateSuggestions(currentVersion: string, availableVersions: string[]) {\n const nextMinor = semver.inc(currentVersion, 'minor')!;\n const nextMajor = semver.inc(currentVersion, 'major')!;\n\n // first found = the highest (given the search criteria)\n\n const suggestions: UpdateSuggestions<string> = [];\n\n const patch = availableVersions.find(\n (v) => semver.gt(v, currentVersion) && semver.lt(v, nextMinor)\n );\n const minor = availableVersions.find((v) => semver.gte(v, nextMinor) && semver.lt(v, nextMajor));\n const major = availableVersions.find((v) => semver.gte(v, nextMajor));\n\n if (patch) suggestions.push({ type: 'patch', update: patch });\n if (minor) suggestions.push({ type: 'minor', update: minor });\n if (major) suggestions.push({ type: 'major', update: major });\n\n return suggestions;\n}\n\nexport class RegistryV2Reader {\n private readonly v2RootFolderReader: FolderReader;\n private readonly ops: RegistryV2ReaderOps;\n\n constructor(\n private readonly registryReader: FolderReader,\n ops?: Partial<RegistryV2ReaderOps>\n ) {\n this.v2RootFolderReader = registryReader.relativeReader(MainPrefix);\n this.ops = { ...DefaultRegistryV2ReaderOps, ...(ops ?? {}) };\n }\n\n /**\n * Embeds meta infromation relative to registry root.\n * Meta information that looks like:\n *\n * */\n private readonly embeddedGlobalMetaCache = new LRUCache<\n string,\n BlockPackMetaEmbeddedBytes,\n { meta: BlockPackMetaManifest; relativeTo?: BlockPackId }\n >({\n max: 500,\n fetchMethod: async (_key, _staleValue, options) =>\n await retry(async () => {\n const contentReader =\n options.context.relativeTo !== undefined\n ? this.v2RootFolderReader\n .relativeReader(packageContentPrefixInsideV2(options.context.relativeTo))\n .getContentReader()\n : this.v2RootFolderReader.getContentReader();\n return await BlockPackMetaEmbedBytes(contentReader).parseAsync(options.context.meta);\n }, Retry2TimesWithDelay)\n });\n\n private async embedMetaContent(\n id: BlockPackId,\n sha256: string,\n absolutePath: boolean,\n meta: BlockPackMetaManifest\n ): Promise<BlockPackMetaEmbeddedBytes> {\n return await this.embeddedGlobalMetaCache.forceFetch(\n canonicalize({ id, sha256, absolutePath })!,\n { context: { meta, relativeTo: absolutePath ? undefined : id } }\n );\n }\n\n private listCacheTimestamp: number = 0;\n private listCache: BlockPackOverviewNoRegistryId[] | undefined = undefined;\n\n public async listBlockPacks(): Promise<BlockPackOverviewNoRegistryId[]> {\n if (\n this.listCache !== undefined &&\n Date.now() - this.listCacheTimestamp <= this.ops.cacheBlockListFor\n )\n return this.listCache;\n try {\n return await retry(async () => {\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\n const result = await Promise.all(\n globalOverview.packages.map(async (p) => {\n const byChannelEntries = await Promise.all(\n Object.entries(p.latestByChannel).map(async ([channel, data]) => [\n channel,\n {\n id: data.description.id,\n meta: await this.embedMetaContent(\n data.description.id,\n data.manifestSha256,\n true,\n data.description.meta\n ),\n featureFlags: data.description.featureFlags,\n spec: {\n type: 'from-registry-v2',\n id: data.description.id,\n registryUrl: this.registryReader.rootUrl.toString(),\n channel\n }\n }\n ])\n );\n return {\n id: p.id,\n latestByChannel: Object.fromEntries(byChannelEntries),\n allVersions: p.allVersionsWithChannels\n } satisfies BlockPackOverviewNoRegistryId;\n })\n );\n\n this.listCache = result;\n this.listCacheTimestamp = Date.now();\n\n return result;\n }, Retry2TimesWithDelay);\n } catch (e: unknown) {\n if (\n this.listCache !== undefined &&\n Date.now() - this.listCacheTimestamp <= this.ops.keepStaleBlockListFor\n )\n return this.listCache;\n throw e;\n }\n }\n\n public async getLatestOverview(\n id: BlockPackIdNoVersion,\n channel: string\n ): Promise<SingleBlockPackOverview | undefined> {\n const overview = (await this.listBlockPacks()).find((e) =>\n blockPackIdNoVersionEquals(id, e.id)\n );\n if (overview === undefined) return undefined;\n return overview.latestByChannel[channel];\n }\n\n public async getUpdateSuggestions(\n id: BlockPackId,\n channel: string\n ): Promise<UpdateSuggestions<string> | undefined> {\n const overview = (await this.listBlockPacks()).find((e) =>\n blockPackIdNoVersionEquals(id, e.id)\n );\n if (overview === undefined) return undefined;\n\n const versionCandidates = overview.allVersions\n .filter((v) => channel === AnyChannel || v.channels.indexOf(channel) >= 0)\n .map((v) => v.version);\n\n // versions are sorted\n versionCandidates.reverse(); // changing sorting order to opposite\n\n return inferUpdateSuggestions(id.version, versionCandidates);\n }\n\n public async getSpecificOverview(\n id: BlockPackId,\n channel: string\n ): Promise<SingleBlockPackOverview> {\n return await retry(async () => {\n const manifestContent = await this.v2RootFolderReader.readFile(\n packageContentPrefixInsideV2(id) + ManifestSuffix\n );\n const overview = BlockPackManifest.parse(JSON.parse(Buffer.from(manifestContent).toString()));\n return {\n id: id,\n meta: await this.embedMetaContent(\n id,\n await calculateSha256(manifestContent),\n false,\n overview.description.meta\n ),\n spec: {\n type: 'from-registry-v2',\n id,\n registryUrl: this.registryReader.rootUrl.toString(),\n channel\n }\n };\n }, Retry2TimesWithDelay);\n }\n\n private readonly componentsCache = new LRUCache<string, BlockComponentsAbsoluteUrl, BlockPackId>({\n max: 500,\n fetchMethod: async (key, staleValue, { context: id }) =>\n await retry(async () => {\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 }, Retry2TimesWithDelay)\n });\n\n public async getComponents(id: BlockPackId): Promise<BlockComponentsAbsoluteUrl> {\n return await this.componentsCache.forceFetch(canonicalize(id)!, { context: id });\n }\n}\n","import { 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';\nimport { defaultHttpDispatcher } from '@milaboratories/pl-http';\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 if (!relativePath.endsWith('/')) relativePath = relativePath + '/';\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 if (!relativePath.endsWith('/')) relativePath = relativePath + '/';\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 ?? defaultHttpDispatcher());\n default:\n throw new Error(`Unknown protocol: ${url.protocol}`);\n }\n}\n"],"names":["DefaultRegistryV2ReaderOps","inferUpdateSuggestions","currentVersion","availableVersions","nextMinor","semver","nextMajor","suggestions","patch","v","minor","major","RegistryV2Reader","registryReader","ops","__publicField","LRUCache","_key","_staleValue","options","retry","contentReader","packageContentPrefixInsideV2","BlockPackMetaEmbedBytes","Retry2TimesWithDelay","key","staleValue","id","packageFolderReader","manifest","BlockPackManifest","ManifestFileName","BlockComponentsAbsoluteUrl","MainPrefix","sha256","absolutePath","meta","canonicalize","globalOverview","GlobalOverviewReg","GlobalOverviewFileName","result","p","byChannelEntries","channel","data","e","overview","blockPackIdNoVersionEquals","versionCandidates","AnyChannel","manifestContent","ManifestSuffix","calculateSha256","HttpFolderReader","rootUrl","httpDispatcher","file","targetUrl","response","request","relativePath","reader","path","FSFolderReader","root","targetPath","pathPosix","fsp","posixToLocalPath","localToPosix","folderReaderByUrl","address","url","rootPath","defaultHttpDispatcher"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/v2/registry/registry_reader.ts","../src/io/folder_reader.ts"],"sourcesContent":["import type {\n BlockPackId,\n BlockPackIdNoVersion,\n BlockPackMetaEmbeddedBytes,\n BlockPackMetaManifest,\n UpdateSuggestions,\n SingleBlockPackOverview,\n BlockPackOverviewNoRegistryId,\n} from '@milaboratories/pl-model-middle-layer';\nimport {\n blockPackIdNoVersionEquals,\n BlockPackManifest,\n AnyChannel,\n} from '@milaboratories/pl-model-middle-layer';\nimport type { FolderReader } from '../../io';\nimport canonicalize from 'canonicalize';\nimport {\n GlobalOverviewFileName,\n GlobalOverviewReg,\n MainPrefix,\n ManifestFileName,\n ManifestSuffix,\n packageContentPrefixInsideV2,\n} from './schema_public';\nimport { BlockComponentsAbsoluteUrl, BlockPackMetaEmbedBytes } from '../model';\nimport { LRUCache } from 'lru-cache';\nimport * as semver from 'semver';\nimport { calculateSha256 } from '../../util';\nimport { retry, Retry2TimesWithDelay } from '@milaboratories/ts-helpers';\n\nexport type RegistryV2ReaderOps = {\n /** Number of milliseconds to cache retrieved block list for */\n cacheBlockListFor: number;\n /** Number of milliseconds to keep cached retrieved block list for, if new requests returns error */\n keepStaleBlockListFor: number;\n};\n\nconst DefaultRegistryV2ReaderOps: RegistryV2ReaderOps = {\n cacheBlockListFor: 45e3, // 45 seconds\n keepStaleBlockListFor: 300e3, // 5 minutes\n};\n\n/** @param availableVersions must be reverse sorted (from highest version to lowest) */\nexport function inferUpdateSuggestions(currentVersion: string, availableVersions: string[]) {\n const nextMinor = semver.inc(currentVersion, 'minor')!;\n const nextMajor = semver.inc(currentVersion, 'major')!;\n\n // first found = the highest (given the search criteria)\n\n const suggestions: UpdateSuggestions<string> = [];\n\n const patch = availableVersions.find(\n (v) => semver.gt(v, currentVersion) && semver.lt(v, nextMinor),\n );\n const minor = availableVersions.find((v) => semver.gte(v, nextMinor) && semver.lt(v, nextMajor));\n const major = availableVersions.find((v) => semver.gte(v, nextMajor));\n\n if (patch) suggestions.push({ type: 'patch', update: patch });\n if (minor) suggestions.push({ type: 'minor', update: minor });\n if (major) suggestions.push({ type: 'major', update: major });\n\n return suggestions;\n}\n\nexport class RegistryV2Reader {\n private readonly v2RootFolderReader: FolderReader;\n private readonly ops: RegistryV2ReaderOps;\n\n constructor(\n private readonly registryReader: FolderReader,\n ops?: Partial<RegistryV2ReaderOps>,\n ) {\n this.v2RootFolderReader = registryReader.relativeReader(MainPrefix);\n this.ops = { ...DefaultRegistryV2ReaderOps, ...(ops ?? {}) };\n }\n\n /**\n * Embeds meta infromation relative to registry root.\n * Meta information that looks like:\n *\n * */\n private readonly embeddedGlobalMetaCache = new LRUCache<\n string,\n BlockPackMetaEmbeddedBytes,\n { meta: BlockPackMetaManifest; relativeTo?: BlockPackId }\n >({\n max: 500,\n fetchMethod: async (_key, _staleValue, options) =>\n await retry(async () => {\n const contentReader\n = options.context.relativeTo !== undefined\n ? this.v2RootFolderReader\n .relativeReader(packageContentPrefixInsideV2(options.context.relativeTo))\n .getContentReader()\n : this.v2RootFolderReader.getContentReader();\n return await BlockPackMetaEmbedBytes(contentReader).parseAsync(options.context.meta);\n }, Retry2TimesWithDelay),\n });\n\n private async embedMetaContent(\n id: BlockPackId,\n sha256: string,\n absolutePath: boolean,\n meta: BlockPackMetaManifest,\n ): Promise<BlockPackMetaEmbeddedBytes> {\n return await this.embeddedGlobalMetaCache.forceFetch(\n canonicalize({ id, sha256, absolutePath })!,\n { context: { meta, relativeTo: absolutePath ? undefined : id } },\n );\n }\n\n private listCacheTimestamp: number = 0;\n private listCache: BlockPackOverviewNoRegistryId[] | undefined = undefined;\n\n public async listBlockPacks(): Promise<BlockPackOverviewNoRegistryId[]> {\n if (\n this.listCache !== undefined\n && Date.now() - this.listCacheTimestamp <= this.ops.cacheBlockListFor\n )\n return this.listCache;\n try {\n return await retry(async () => {\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\n const result = await Promise.all(\n globalOverview.packages.map(async (p) => {\n const byChannelEntries = await Promise.all(\n Object.entries(p.latestByChannel).map(async ([channel, data]) => [\n channel,\n {\n id: data.description.id,\n meta: await this.embedMetaContent(\n data.description.id,\n data.manifestSha256,\n true,\n data.description.meta,\n ),\n featureFlags: data.description.featureFlags,\n spec: {\n type: 'from-registry-v2',\n id: data.description.id,\n registryUrl: this.registryReader.rootUrl.toString(),\n channel,\n },\n },\n ]),\n );\n return {\n id: p.id,\n latestByChannel: Object.fromEntries(byChannelEntries) as BlockPackOverviewNoRegistryId['latestByChannel'],\n allVersions: p.allVersionsWithChannels,\n } satisfies BlockPackOverviewNoRegistryId;\n }),\n );\n\n this.listCache = result;\n this.listCacheTimestamp = Date.now();\n\n return result;\n }, Retry2TimesWithDelay);\n } catch (e: unknown) {\n if (\n this.listCache !== undefined\n && Date.now() - this.listCacheTimestamp <= this.ops.keepStaleBlockListFor\n )\n return this.listCache;\n throw e;\n }\n }\n\n public async getLatestOverview(\n id: BlockPackIdNoVersion,\n channel: string,\n ): Promise<SingleBlockPackOverview | undefined> {\n const overview = (await this.listBlockPacks()).find((e) =>\n blockPackIdNoVersionEquals(id, e.id),\n );\n if (overview === undefined) return undefined;\n return overview.latestByChannel[channel];\n }\n\n public async getUpdateSuggestions(\n id: BlockPackId,\n channel: string,\n ): Promise<UpdateSuggestions<string> | undefined> {\n const overview = (await this.listBlockPacks()).find((e) =>\n blockPackIdNoVersionEquals(id, e.id),\n );\n if (overview === undefined) return undefined;\n\n const versionCandidates = overview.allVersions\n .filter((v) => channel === AnyChannel || v.channels.indexOf(channel) >= 0)\n .map((v) => v.version);\n\n // versions are sorted\n versionCandidates.reverse(); // changing sorting order to opposite\n\n return inferUpdateSuggestions(id.version, versionCandidates);\n }\n\n public async getSpecificOverview(\n id: BlockPackId,\n channel: string,\n ): Promise<SingleBlockPackOverview> {\n return await retry(async () => {\n const manifestContent = await this.v2RootFolderReader.readFile(\n packageContentPrefixInsideV2(id) + ManifestSuffix,\n );\n const overview = BlockPackManifest.parse(JSON.parse(Buffer.from(manifestContent).toString()));\n return {\n id: id,\n meta: await this.embedMetaContent(\n id,\n await calculateSha256(manifestContent),\n false,\n overview.description.meta,\n ),\n spec: {\n type: 'from-registry-v2',\n id,\n registryUrl: this.registryReader.rootUrl.toString(),\n channel,\n },\n };\n }, Retry2TimesWithDelay);\n }\n\n private readonly componentsCache = new LRUCache<string, BlockComponentsAbsoluteUrl, BlockPackId>({\n max: 500,\n fetchMethod: async (_key, _staleValue, { context: id }) =>\n await retry(async () => {\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 }, Retry2TimesWithDelay),\n });\n\n public async getComponents(id: BlockPackId): Promise<BlockComponentsAbsoluteUrl> {\n return await this.componentsCache.forceFetch(canonicalize(id)!, { context: id });\n }\n}\n","import type { Dispatcher } from 'undici';\nimport { request } from 'undici';\nimport type { RelativeContentReader } from '../v2';\nimport path from 'node:path';\nimport pathPosix from 'node:path/posix';\nimport fsp from 'node:fs/promises';\nimport { defaultHttpDispatcher } from '@milaboratories/pl-http';\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 if (!relativePath.endsWith('/')) relativePath = relativePath + '/';\n return new HttpFolderReader(new URL(relativePath, this.rootUrl), this.httpDispatcher);\n }\n\n public getContentReader(relativePath?: string): RelativeContentReader {\n const reader: HttpFolderReader = relativePath !== undefined\n ? this.relativeReader(relativePath)\n : this;\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 if (!relativePath.endsWith('/')) relativePath = relativePath + '/';\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 const reader: FSFolderReader = relativePath !== undefined\n ? this.relativeReader(relativePath)\n : this;\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 }\n case 'https:':\n case 'http:':\n return new HttpFolderReader(url, httpDispatcher ?? defaultHttpDispatcher());\n default:\n throw new Error(`Unknown protocol: ${url.protocol}`);\n }\n}\n"],"names":["DefaultRegistryV2ReaderOps","inferUpdateSuggestions","currentVersion","availableVersions","nextMinor","semver.inc","nextMajor","suggestions","patch","v","semver.gt","semver.lt","minor","semver.gte","major","RegistryV2Reader","registryReader","ops","__publicField","LRUCache","_key","_staleValue","options","retry","contentReader","packageContentPrefixInsideV2","BlockPackMetaEmbedBytes","Retry2TimesWithDelay","id","packageFolderReader","manifest","BlockPackManifest","ManifestFileName","BlockComponentsAbsoluteUrl","MainPrefix","sha256","absolutePath","meta","canonicalize","globalOverview","GlobalOverviewReg","GlobalOverviewFileName","result","p","byChannelEntries","channel","data","e","overview","blockPackIdNoVersionEquals","versionCandidates","AnyChannel","manifestContent","ManifestSuffix","calculateSha256","HttpFolderReader","rootUrl","httpDispatcher","file","targetUrl","response","request","relativePath","reader","path","FSFolderReader","root","targetPath","pathPosix","fsp","posixToLocalPath","localToPosix","folderReaderByUrl","address","url","rootPath","defaultHttpDispatcher"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
var C = Object.defineProperty;
|
|
2
2
|
var P = (s, e, t) => e in s ? C(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
|
|
3
3
|
var l = (s, e, t) => P(s, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
-
import { e as c, f as B, p as m, h as F, G as b, i as x, j as O, k as S, M as T, m as D, n as M, o as U, q as E, r as G, t as j, u as L, v as N, w as V, P as A, x as J, y as
|
|
5
|
-
import { V as ye, U as we, Z as Re, ah as Ce, X as Pe, Y as Be, Q as Fe, a as be, B as xe, T as Oe, b as Se, a3 as Te, a2 as De, F as Me, ag as Ue, ae as Ee, af as Ge, a0 as je, ad as Le, ac as Ne, aj as Ve, ai as Ae, ab as Je, a6 as
|
|
6
|
-
import { request as
|
|
4
|
+
import { e as c, f as B, p as m, h as F, G as b, i as x, j as O, k as S, M as T, m as D, n as M, o as U, q as E, r as G, t as j, u as L, v as N, w as V, P as A, x as J, y as _, z } from "./config-DKBY0B2u.mjs";
|
|
5
|
+
import { V as ye, U as we, Z as Re, ah as Ce, X as Pe, Y as Be, Q as Fe, a as be, B as xe, T as Oe, b as Se, a3 as Te, a2 as De, F as Me, ag as Ue, ae as Ee, af as Ge, a0 as je, ad as Le, ac as Ne, aj as Ve, ai as Ae, ab as Je, a6 as _e, a1 as ze, a5 as We, W as Ie, R as qe, A as $e, S as He, E as Ye, H as Ke, D as Qe, d as Xe, I as Ze, c as et, l as tt, C as at, J as ot, aa as st, a9 as it, a4 as rt, a8 as nt, a7 as lt, _ as ct, L as pt, N as dt, O as ht, K as ft, s as mt, $ as gt } from "./config-DKBY0B2u.mjs";
|
|
6
|
+
import { request as W } from "undici";
|
|
7
7
|
import p from "node:path";
|
|
8
8
|
import f from "node:path/posix";
|
|
9
|
-
import
|
|
9
|
+
import I from "node:fs/promises";
|
|
10
10
|
import { defaultHttpDispatcher as q } from "@milaboratories/pl-http";
|
|
11
11
|
import { blockPackIdNoVersionEquals as k, AnyChannel as $, BlockPackManifest as y } from "@milaboratories/pl-model-middle-layer";
|
|
12
12
|
import w from "canonicalize";
|
|
@@ -161,7 +161,7 @@ class g {
|
|
|
161
161
|
this.rootUrl = e, this.httpDispatcher = t;
|
|
162
162
|
}
|
|
163
163
|
async readFile(e) {
|
|
164
|
-
const t = new URL(e, this.rootUrl), a = await
|
|
164
|
+
const t = new URL(e, this.rootUrl), a = await W(t, {
|
|
165
165
|
dispatcher: this.httpDispatcher
|
|
166
166
|
});
|
|
167
167
|
return Buffer.from(await a.body.arrayBuffer());
|
|
@@ -170,8 +170,8 @@ class g {
|
|
|
170
170
|
return e.endsWith("/") || (e = e + "/"), new g(new URL(e, this.rootUrl), this.httpDispatcher);
|
|
171
171
|
}
|
|
172
172
|
getContentReader(e) {
|
|
173
|
-
|
|
174
|
-
return
|
|
173
|
+
const t = e !== void 0 ? this.relativeReader(e) : this;
|
|
174
|
+
return (a) => t.readFile(a);
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
class v {
|
|
@@ -180,7 +180,7 @@ class v {
|
|
|
180
180
|
}
|
|
181
181
|
async readFile(e) {
|
|
182
182
|
const t = p.join(this.root, ...e.split(f.sep));
|
|
183
|
-
return await
|
|
183
|
+
return await I.readFile(t);
|
|
184
184
|
}
|
|
185
185
|
relativeReader(e) {
|
|
186
186
|
return e.endsWith("/") || (e = e + "/"), new v(
|
|
@@ -189,8 +189,8 @@ class v {
|
|
|
189
189
|
);
|
|
190
190
|
}
|
|
191
191
|
getContentReader(e) {
|
|
192
|
-
|
|
193
|
-
return
|
|
192
|
+
const t = e !== void 0 ? this.relativeReader(e) : this;
|
|
193
|
+
return (a) => t.readFile(a);
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
function K(s) {
|
|
@@ -203,9 +203,10 @@ function ge(s, e) {
|
|
|
203
203
|
s.endsWith("/") || (s = s + "/");
|
|
204
204
|
const t = new URL(s, `file:${Q(p.resolve("."))}/`);
|
|
205
205
|
switch (t.protocol) {
|
|
206
|
-
case "file:":
|
|
206
|
+
case "file:": {
|
|
207
207
|
const a = K(t.pathname);
|
|
208
208
|
return new v(t, a);
|
|
209
|
+
}
|
|
209
210
|
case "https:":
|
|
210
211
|
case "http:":
|
|
211
212
|
return new g(t, e ?? q());
|
|
@@ -225,8 +226,8 @@ const ve = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
|
225
226
|
PlRegPackageConfig: V,
|
|
226
227
|
PlRegPackageConfigDataShard: A,
|
|
227
228
|
packageContentPrefix: J,
|
|
228
|
-
packageOverviewPath:
|
|
229
|
-
payloadFilePath:
|
|
229
|
+
packageOverviewPath: _,
|
|
230
|
+
payloadFilePath: z
|
|
230
231
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
231
232
|
export {
|
|
232
233
|
D as BlockComponentsAbsoluteUrl,
|
|
@@ -259,12 +260,12 @@ export {
|
|
|
259
260
|
T as ManifestFileName,
|
|
260
261
|
O as ManifestSuffix,
|
|
261
262
|
Je as PackageManifestPattern,
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
263
|
+
_e as PackageOverview,
|
|
264
|
+
ze as PackageOverviewFileName,
|
|
265
|
+
We as PackageOverviewVersionEntry,
|
|
265
266
|
ve as RegistryV1,
|
|
266
267
|
me as RegistryV2Reader,
|
|
267
|
-
|
|
268
|
+
Ie as ResolvedBlockPackDescriptionFromPackageJson,
|
|
268
269
|
qe as ResolvedModuleFile,
|
|
269
270
|
$e as ResolvedModuleFolder,
|
|
270
271
|
He as S3Storage,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/v2/registry/registry_reader.ts","../src/io/folder_reader.ts"],"sourcesContent":["import {\n BlockPackId,\n BlockPackIdNoVersion,\n blockPackIdNoVersionEquals,\n BlockPackManifest,\n BlockPackMetaEmbeddedBytes,\n BlockPackMetaManifest,\n BlockPackOverview,\n UpdateSuggestions,\n SingleBlockPackOverview,\n AnyChannel,\n BlockPackOverviewNoRegistryId\n} from '@milaboratories/pl-model-middle-layer';\nimport { FolderReader } from '../../io';\nimport canonicalize from 'canonicalize';\nimport {\n GlobalOverviewFileName,\n GlobalOverviewReg,\n MainPrefix,\n ManifestFileName,\n ManifestSuffix,\n packageContentPrefixInsideV2\n} from './schema_public';\nimport { BlockComponentsAbsoluteUrl, BlockPackMetaEmbedBytes } from '../model';\nimport { LRUCache } from 'lru-cache';\nimport semver from 'semver';\nimport { calculateSha256 } from '../../util';\nimport { retry, Retry2TimesWithDelay } from '@milaboratories/ts-helpers';\n\nexport type RegistryV2ReaderOps = {\n /** Number of milliseconds to cache retrieved block list for */\n cacheBlockListFor: number;\n /** Number of milliseconds to keep cached retrieved block list for, if new requests returns error */\n keepStaleBlockListFor: number;\n};\n\nconst DefaultRegistryV2ReaderOps: RegistryV2ReaderOps = {\n cacheBlockListFor: 45e3, // 45 seconds\n keepStaleBlockListFor: 300e3 // 5 minutes\n};\n\n/** @param availableVersions must be reverse sorted (from highest version to lowest) */\nexport function inferUpdateSuggestions(currentVersion: string, availableVersions: string[]) {\n const nextMinor = semver.inc(currentVersion, 'minor')!;\n const nextMajor = semver.inc(currentVersion, 'major')!;\n\n // first found = the highest (given the search criteria)\n\n const suggestions: UpdateSuggestions<string> = [];\n\n const patch = availableVersions.find(\n (v) => semver.gt(v, currentVersion) && semver.lt(v, nextMinor)\n );\n const minor = availableVersions.find((v) => semver.gte(v, nextMinor) && semver.lt(v, nextMajor));\n const major = availableVersions.find((v) => semver.gte(v, nextMajor));\n\n if (patch) suggestions.push({ type: 'patch', update: patch });\n if (minor) suggestions.push({ type: 'minor', update: minor });\n if (major) suggestions.push({ type: 'major', update: major });\n\n return suggestions;\n}\n\nexport class RegistryV2Reader {\n private readonly v2RootFolderReader: FolderReader;\n private readonly ops: RegistryV2ReaderOps;\n\n constructor(\n private readonly registryReader: FolderReader,\n ops?: Partial<RegistryV2ReaderOps>\n ) {\n this.v2RootFolderReader = registryReader.relativeReader(MainPrefix);\n this.ops = { ...DefaultRegistryV2ReaderOps, ...(ops ?? {}) };\n }\n\n /**\n * Embeds meta infromation relative to registry root.\n * Meta information that looks like:\n *\n * */\n private readonly embeddedGlobalMetaCache = new LRUCache<\n string,\n BlockPackMetaEmbeddedBytes,\n { meta: BlockPackMetaManifest; relativeTo?: BlockPackId }\n >({\n max: 500,\n fetchMethod: async (_key, _staleValue, options) =>\n await retry(async () => {\n const contentReader =\n options.context.relativeTo !== undefined\n ? this.v2RootFolderReader\n .relativeReader(packageContentPrefixInsideV2(options.context.relativeTo))\n .getContentReader()\n : this.v2RootFolderReader.getContentReader();\n return await BlockPackMetaEmbedBytes(contentReader).parseAsync(options.context.meta);\n }, Retry2TimesWithDelay)\n });\n\n private async embedMetaContent(\n id: BlockPackId,\n sha256: string,\n absolutePath: boolean,\n meta: BlockPackMetaManifest\n ): Promise<BlockPackMetaEmbeddedBytes> {\n return await this.embeddedGlobalMetaCache.forceFetch(\n canonicalize({ id, sha256, absolutePath })!,\n { context: { meta, relativeTo: absolutePath ? undefined : id } }\n );\n }\n\n private listCacheTimestamp: number = 0;\n private listCache: BlockPackOverviewNoRegistryId[] | undefined = undefined;\n\n public async listBlockPacks(): Promise<BlockPackOverviewNoRegistryId[]> {\n if (\n this.listCache !== undefined &&\n Date.now() - this.listCacheTimestamp <= this.ops.cacheBlockListFor\n )\n return this.listCache;\n try {\n return await retry(async () => {\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\n const result = await Promise.all(\n globalOverview.packages.map(async (p) => {\n const byChannelEntries = await Promise.all(\n Object.entries(p.latestByChannel).map(async ([channel, data]) => [\n channel,\n {\n id: data.description.id,\n meta: await this.embedMetaContent(\n data.description.id,\n data.manifestSha256,\n true,\n data.description.meta\n ),\n featureFlags: data.description.featureFlags,\n spec: {\n type: 'from-registry-v2',\n id: data.description.id,\n registryUrl: this.registryReader.rootUrl.toString(),\n channel\n }\n }\n ])\n );\n return {\n id: p.id,\n latestByChannel: Object.fromEntries(byChannelEntries),\n allVersions: p.allVersionsWithChannels\n } satisfies BlockPackOverviewNoRegistryId;\n })\n );\n\n this.listCache = result;\n this.listCacheTimestamp = Date.now();\n\n return result;\n }, Retry2TimesWithDelay);\n } catch (e: unknown) {\n if (\n this.listCache !== undefined &&\n Date.now() - this.listCacheTimestamp <= this.ops.keepStaleBlockListFor\n )\n return this.listCache;\n throw e;\n }\n }\n\n public async getLatestOverview(\n id: BlockPackIdNoVersion,\n channel: string\n ): Promise<SingleBlockPackOverview | undefined> {\n const overview = (await this.listBlockPacks()).find((e) =>\n blockPackIdNoVersionEquals(id, e.id)\n );\n if (overview === undefined) return undefined;\n return overview.latestByChannel[channel];\n }\n\n public async getUpdateSuggestions(\n id: BlockPackId,\n channel: string\n ): Promise<UpdateSuggestions<string> | undefined> {\n const overview = (await this.listBlockPacks()).find((e) =>\n blockPackIdNoVersionEquals(id, e.id)\n );\n if (overview === undefined) return undefined;\n\n const versionCandidates = overview.allVersions\n .filter((v) => channel === AnyChannel || v.channels.indexOf(channel) >= 0)\n .map((v) => v.version);\n\n // versions are sorted\n versionCandidates.reverse(); // changing sorting order to opposite\n\n return inferUpdateSuggestions(id.version, versionCandidates);\n }\n\n public async getSpecificOverview(\n id: BlockPackId,\n channel: string\n ): Promise<SingleBlockPackOverview> {\n return await retry(async () => {\n const manifestContent = await this.v2RootFolderReader.readFile(\n packageContentPrefixInsideV2(id) + ManifestSuffix\n );\n const overview = BlockPackManifest.parse(JSON.parse(Buffer.from(manifestContent).toString()));\n return {\n id: id,\n meta: await this.embedMetaContent(\n id,\n await calculateSha256(manifestContent),\n false,\n overview.description.meta\n ),\n spec: {\n type: 'from-registry-v2',\n id,\n registryUrl: this.registryReader.rootUrl.toString(),\n channel\n }\n };\n }, Retry2TimesWithDelay);\n }\n\n private readonly componentsCache = new LRUCache<string, BlockComponentsAbsoluteUrl, BlockPackId>({\n max: 500,\n fetchMethod: async (key, staleValue, { context: id }) =>\n await retry(async () => {\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 }, Retry2TimesWithDelay)\n });\n\n public async getComponents(id: BlockPackId): Promise<BlockComponentsAbsoluteUrl> {\n return await this.componentsCache.forceFetch(canonicalize(id)!, { context: id });\n }\n}\n","import { 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';\nimport { defaultHttpDispatcher } from '@milaboratories/pl-http';\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 if (!relativePath.endsWith('/')) relativePath = relativePath + '/';\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 if (!relativePath.endsWith('/')) relativePath = relativePath + '/';\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 ?? defaultHttpDispatcher());\n default:\n throw new Error(`Unknown protocol: ${url.protocol}`);\n }\n}\n"],"names":["DefaultRegistryV2ReaderOps","inferUpdateSuggestions","currentVersion","availableVersions","nextMinor","semver","nextMajor","suggestions","patch","v","minor","major","RegistryV2Reader","registryReader","ops","__publicField","LRUCache","_key","_staleValue","options","retry","contentReader","packageContentPrefixInsideV2","BlockPackMetaEmbedBytes","Retry2TimesWithDelay","key","staleValue","id","packageFolderReader","manifest","BlockPackManifest","ManifestFileName","BlockComponentsAbsoluteUrl","MainPrefix","sha256","absolutePath","meta","canonicalize","globalOverview","GlobalOverviewReg","GlobalOverviewFileName","result","p","byChannelEntries","channel","data","overview","e","blockPackIdNoVersionEquals","versionCandidates","AnyChannel","manifestContent","ManifestSuffix","calculateSha256","HttpFolderReader","rootUrl","httpDispatcher","file","targetUrl","response","request","relativePath","reader","path","FSFolderReader","root","targetPath","pathPosix","fsp","posixToLocalPath","localToPosix","folderReaderByUrl","address","url","rootPath","defaultHttpDispatcher"],"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 type {\n BlockPackId,\n BlockPackIdNoVersion,\n BlockPackMetaEmbeddedBytes,\n BlockPackMetaManifest,\n UpdateSuggestions,\n SingleBlockPackOverview,\n BlockPackOverviewNoRegistryId,\n} from '@milaboratories/pl-model-middle-layer';\nimport {\n blockPackIdNoVersionEquals,\n BlockPackManifest,\n AnyChannel,\n} from '@milaboratories/pl-model-middle-layer';\nimport type { FolderReader } from '../../io';\nimport canonicalize from 'canonicalize';\nimport {\n GlobalOverviewFileName,\n GlobalOverviewReg,\n MainPrefix,\n ManifestFileName,\n ManifestSuffix,\n packageContentPrefixInsideV2,\n} from './schema_public';\nimport { BlockComponentsAbsoluteUrl, BlockPackMetaEmbedBytes } from '../model';\nimport { LRUCache } from 'lru-cache';\nimport * as semver from 'semver';\nimport { calculateSha256 } from '../../util';\nimport { retry, Retry2TimesWithDelay } from '@milaboratories/ts-helpers';\n\nexport type RegistryV2ReaderOps = {\n /** Number of milliseconds to cache retrieved block list for */\n cacheBlockListFor: number;\n /** Number of milliseconds to keep cached retrieved block list for, if new requests returns error */\n keepStaleBlockListFor: number;\n};\n\nconst DefaultRegistryV2ReaderOps: RegistryV2ReaderOps = {\n cacheBlockListFor: 45e3, // 45 seconds\n keepStaleBlockListFor: 300e3, // 5 minutes\n};\n\n/** @param availableVersions must be reverse sorted (from highest version to lowest) */\nexport function inferUpdateSuggestions(currentVersion: string, availableVersions: string[]) {\n const nextMinor = semver.inc(currentVersion, 'minor')!;\n const nextMajor = semver.inc(currentVersion, 'major')!;\n\n // first found = the highest (given the search criteria)\n\n const suggestions: UpdateSuggestions<string> = [];\n\n const patch = availableVersions.find(\n (v) => semver.gt(v, currentVersion) && semver.lt(v, nextMinor),\n );\n const minor = availableVersions.find((v) => semver.gte(v, nextMinor) && semver.lt(v, nextMajor));\n const major = availableVersions.find((v) => semver.gte(v, nextMajor));\n\n if (patch) suggestions.push({ type: 'patch', update: patch });\n if (minor) suggestions.push({ type: 'minor', update: minor });\n if (major) suggestions.push({ type: 'major', update: major });\n\n return suggestions;\n}\n\nexport class RegistryV2Reader {\n private readonly v2RootFolderReader: FolderReader;\n private readonly ops: RegistryV2ReaderOps;\n\n constructor(\n private readonly registryReader: FolderReader,\n ops?: Partial<RegistryV2ReaderOps>,\n ) {\n this.v2RootFolderReader = registryReader.relativeReader(MainPrefix);\n this.ops = { ...DefaultRegistryV2ReaderOps, ...(ops ?? {}) };\n }\n\n /**\n * Embeds meta infromation relative to registry root.\n * Meta information that looks like:\n *\n * */\n private readonly embeddedGlobalMetaCache = new LRUCache<\n string,\n BlockPackMetaEmbeddedBytes,\n { meta: BlockPackMetaManifest; relativeTo?: BlockPackId }\n >({\n max: 500,\n fetchMethod: async (_key, _staleValue, options) =>\n await retry(async () => {\n const contentReader\n = options.context.relativeTo !== undefined\n ? this.v2RootFolderReader\n .relativeReader(packageContentPrefixInsideV2(options.context.relativeTo))\n .getContentReader()\n : this.v2RootFolderReader.getContentReader();\n return await BlockPackMetaEmbedBytes(contentReader).parseAsync(options.context.meta);\n }, Retry2TimesWithDelay),\n });\n\n private async embedMetaContent(\n id: BlockPackId,\n sha256: string,\n absolutePath: boolean,\n meta: BlockPackMetaManifest,\n ): Promise<BlockPackMetaEmbeddedBytes> {\n return await this.embeddedGlobalMetaCache.forceFetch(\n canonicalize({ id, sha256, absolutePath })!,\n { context: { meta, relativeTo: absolutePath ? undefined : id } },\n );\n }\n\n private listCacheTimestamp: number = 0;\n private listCache: BlockPackOverviewNoRegistryId[] | undefined = undefined;\n\n public async listBlockPacks(): Promise<BlockPackOverviewNoRegistryId[]> {\n if (\n this.listCache !== undefined\n && Date.now() - this.listCacheTimestamp <= this.ops.cacheBlockListFor\n )\n return this.listCache;\n try {\n return await retry(async () => {\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\n const result = await Promise.all(\n globalOverview.packages.map(async (p) => {\n const byChannelEntries = await Promise.all(\n Object.entries(p.latestByChannel).map(async ([channel, data]) => [\n channel,\n {\n id: data.description.id,\n meta: await this.embedMetaContent(\n data.description.id,\n data.manifestSha256,\n true,\n data.description.meta,\n ),\n featureFlags: data.description.featureFlags,\n spec: {\n type: 'from-registry-v2',\n id: data.description.id,\n registryUrl: this.registryReader.rootUrl.toString(),\n channel,\n },\n },\n ]),\n );\n return {\n id: p.id,\n latestByChannel: Object.fromEntries(byChannelEntries) as BlockPackOverviewNoRegistryId['latestByChannel'],\n allVersions: p.allVersionsWithChannels,\n } satisfies BlockPackOverviewNoRegistryId;\n }),\n );\n\n this.listCache = result;\n this.listCacheTimestamp = Date.now();\n\n return result;\n }, Retry2TimesWithDelay);\n } catch (e: unknown) {\n if (\n this.listCache !== undefined\n && Date.now() - this.listCacheTimestamp <= this.ops.keepStaleBlockListFor\n )\n return this.listCache;\n throw e;\n }\n }\n\n public async getLatestOverview(\n id: BlockPackIdNoVersion,\n channel: string,\n ): Promise<SingleBlockPackOverview | undefined> {\n const overview = (await this.listBlockPacks()).find((e) =>\n blockPackIdNoVersionEquals(id, e.id),\n );\n if (overview === undefined) return undefined;\n return overview.latestByChannel[channel];\n }\n\n public async getUpdateSuggestions(\n id: BlockPackId,\n channel: string,\n ): Promise<UpdateSuggestions<string> | undefined> {\n const overview = (await this.listBlockPacks()).find((e) =>\n blockPackIdNoVersionEquals(id, e.id),\n );\n if (overview === undefined) return undefined;\n\n const versionCandidates = overview.allVersions\n .filter((v) => channel === AnyChannel || v.channels.indexOf(channel) >= 0)\n .map((v) => v.version);\n\n // versions are sorted\n versionCandidates.reverse(); // changing sorting order to opposite\n\n return inferUpdateSuggestions(id.version, versionCandidates);\n }\n\n public async getSpecificOverview(\n id: BlockPackId,\n channel: string,\n ): Promise<SingleBlockPackOverview> {\n return await retry(async () => {\n const manifestContent = await this.v2RootFolderReader.readFile(\n packageContentPrefixInsideV2(id) + ManifestSuffix,\n );\n const overview = BlockPackManifest.parse(JSON.parse(Buffer.from(manifestContent).toString()));\n return {\n id: id,\n meta: await this.embedMetaContent(\n id,\n await calculateSha256(manifestContent),\n false,\n overview.description.meta,\n ),\n spec: {\n type: 'from-registry-v2',\n id,\n registryUrl: this.registryReader.rootUrl.toString(),\n channel,\n },\n };\n }, Retry2TimesWithDelay);\n }\n\n private readonly componentsCache = new LRUCache<string, BlockComponentsAbsoluteUrl, BlockPackId>({\n max: 500,\n fetchMethod: async (_key, _staleValue, { context: id }) =>\n await retry(async () => {\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 }, Retry2TimesWithDelay),\n });\n\n public async getComponents(id: BlockPackId): Promise<BlockComponentsAbsoluteUrl> {\n return await this.componentsCache.forceFetch(canonicalize(id)!, { context: id });\n }\n}\n","import type { Dispatcher } from 'undici';\nimport { request } from 'undici';\nimport type { RelativeContentReader } from '../v2';\nimport path from 'node:path';\nimport pathPosix from 'node:path/posix';\nimport fsp from 'node:fs/promises';\nimport { defaultHttpDispatcher } from '@milaboratories/pl-http';\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 if (!relativePath.endsWith('/')) relativePath = relativePath + '/';\n return new HttpFolderReader(new URL(relativePath, this.rootUrl), this.httpDispatcher);\n }\n\n public getContentReader(relativePath?: string): RelativeContentReader {\n const reader: HttpFolderReader = relativePath !== undefined\n ? this.relativeReader(relativePath)\n : this;\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 if (!relativePath.endsWith('/')) relativePath = relativePath + '/';\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 const reader: FSFolderReader = relativePath !== undefined\n ? this.relativeReader(relativePath)\n : this;\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 }\n case 'https:':\n case 'http:':\n return new HttpFolderReader(url, httpDispatcher ?? defaultHttpDispatcher());\n default:\n throw new Error(`Unknown protocol: ${url.protocol}`);\n }\n}\n"],"names":["DefaultRegistryV2ReaderOps","inferUpdateSuggestions","currentVersion","availableVersions","nextMinor","semver.inc","nextMajor","suggestions","patch","v","semver.gt","semver.lt","minor","semver.gte","major","RegistryV2Reader","registryReader","ops","__publicField","LRUCache","_key","_staleValue","options","retry","contentReader","packageContentPrefixInsideV2","BlockPackMetaEmbedBytes","Retry2TimesWithDelay","id","packageFolderReader","manifest","BlockPackManifest","ManifestFileName","BlockComponentsAbsoluteUrl","MainPrefix","sha256","absolutePath","meta","canonicalize","globalOverview","GlobalOverviewReg","GlobalOverviewFileName","result","p","byChannelEntries","channel","data","overview","e","blockPackIdNoVersionEquals","versionCandidates","AnyChannel","manifestContent","ManifestSuffix","calculateSha256","HttpFolderReader","rootUrl","httpDispatcher","file","targetUrl","response","request","relativePath","reader","path","FSFolderReader","root","targetPath","pathPosix","fsp","posixToLocalPath","localToPosix","folderReaderByUrl","address","url","rootPath","defaultHttpDispatcher"],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ export declare const GlobalOverviewPath = "v1/overview.json";
|
|
|
11
11
|
export declare const MetaFile = "meta.json";
|
|
12
12
|
export interface PackageOverviewEntry {
|
|
13
13
|
version: string;
|
|
14
|
-
meta:
|
|
14
|
+
meta: Record<string, unknown>;
|
|
15
15
|
}
|
|
16
16
|
export type PackageOverview = PackageOverviewEntry[];
|
|
17
17
|
export interface GlobalOverviewEntry {
|
|
@@ -19,6 +19,6 @@ export interface GlobalOverviewEntry {
|
|
|
19
19
|
package: string;
|
|
20
20
|
allVersions: string[];
|
|
21
21
|
latestVersion: string;
|
|
22
|
-
latestMeta:
|
|
22
|
+
latestMeta: Record<string, unknown>;
|
|
23
23
|
}
|
|
24
24
|
export type GlobalOverview = GlobalOverviewEntry[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/block-tools",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.29",
|
|
4
4
|
"description": "Utility to manipulate Platforma Blocks and Block Registry",
|
|
5
5
|
"types": "./dist/lib.d.ts",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -33,30 +33,32 @@
|
|
|
33
33
|
"tar": "^7.4.3",
|
|
34
34
|
"yaml": "^2.8.0",
|
|
35
35
|
"zod": "~3.23.8",
|
|
36
|
-
"@milaboratories/resolve-helper": "1.1.1",
|
|
37
|
-
"@platforma-sdk/blocks-deps-updater": "2.0.0",
|
|
38
36
|
"@milaboratories/pl-http": "1.2.0",
|
|
37
|
+
"@platforma-sdk/blocks-deps-updater": "2.0.0",
|
|
38
|
+
"@milaboratories/resolve-helper": "1.1.1",
|
|
39
39
|
"@milaboratories/ts-helpers": "1.5.4",
|
|
40
|
-
"@milaboratories/pl-model-common": "1.
|
|
41
|
-
"@milaboratories/pl-model-middle-layer": "1.
|
|
40
|
+
"@milaboratories/pl-model-common": "1.23.0",
|
|
41
|
+
"@milaboratories/pl-model-middle-layer": "1.9.1",
|
|
42
42
|
"@milaboratories/ts-helpers-oclif": "1.1.33"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"typescript": "~5.6.3",
|
|
46
|
-
"vite": "^6.3.5",
|
|
47
|
-
"rollup-plugin-node-externals": "^8.0.0",
|
|
48
45
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
49
|
-
"vite-plugin-dts": "^4.5.3",
|
|
50
|
-
"semver": "^7.7.2",
|
|
51
46
|
"@types/mime-types": "^2.1.4",
|
|
52
47
|
"@types/node": "~24.5.2",
|
|
53
48
|
"@types/semver": "^7.7.0",
|
|
54
|
-
"@vitest/coverage-
|
|
55
|
-
"
|
|
49
|
+
"@vitest/coverage-istanbul": "^4.0.16",
|
|
50
|
+
"eslint": "^9.25.1",
|
|
56
51
|
"oclif": "^4.16.2",
|
|
57
|
-
"
|
|
52
|
+
"rollup-plugin-node-externals": "^8.0.0",
|
|
53
|
+
"semver": "^7.7.2",
|
|
54
|
+
"typescript": "~5.6.3",
|
|
55
|
+
"vite": "^6.3.5",
|
|
56
|
+
"vite-plugin-dts": "^4.5.3",
|
|
57
|
+
"vitest": "^4.0.16",
|
|
58
|
+
"@milaboratories/build-configs": "1.2.1",
|
|
59
|
+
"@milaboratories/eslint-config": "1.0.5",
|
|
58
60
|
"@milaboratories/oclif-index": "1.1.1",
|
|
59
|
-
"@milaboratories/ts-configs": "1.0
|
|
61
|
+
"@milaboratories/ts-configs": "1.2.0"
|
|
60
62
|
},
|
|
61
63
|
"oclif": {
|
|
62
64
|
"bin": "block-tools",
|
|
@@ -74,6 +76,7 @@
|
|
|
74
76
|
"build": "vite build",
|
|
75
77
|
"readme": "oclif readme",
|
|
76
78
|
"test": "vitest run --coverage",
|
|
77
|
-
"do-pack": "rm -f *.tgz && pnpm pack && mv *.tgz package.tgz"
|
|
79
|
+
"do-pack": "rm -f *.tgz && pnpm pack && mv *.tgz package.tgz",
|
|
80
|
+
"lint": "eslint ."
|
|
78
81
|
}
|
|
79
82
|
}
|
package/src/cmd/build-meta.ts
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
import { Command, Flags } from '@oclif/core';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import fs from 'fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
4
|
import { loadPackDescriptionRaw } from '../v2';
|
|
5
5
|
import { BlockPackMetaDescription, BlockPackMetaEmbedAbsoluteBase64 } from '../v2/model/block_meta';
|
|
6
6
|
|
|
7
7
|
export default class BuildMeta extends Command {
|
|
8
|
-
static override description
|
|
9
|
-
'Extracts meta information from blocks package.json and outputs meta.json with embedded binary '
|
|
10
|
-
'and textual information linked from the meta section.';
|
|
8
|
+
static override description
|
|
9
|
+
= 'Extracts meta information from blocks package.json and outputs meta.json with embedded binary '
|
|
10
|
+
+ 'and textual information linked from the meta section.';
|
|
11
11
|
|
|
12
12
|
static flags = {
|
|
13
13
|
modulePath: Flags.string({
|
|
14
14
|
char: 'i',
|
|
15
15
|
summary: 'input module path',
|
|
16
16
|
helpValue: '<path>',
|
|
17
|
-
default: '.'
|
|
17
|
+
default: '.',
|
|
18
18
|
}),
|
|
19
19
|
|
|
20
20
|
destination: Flags.string({
|
|
21
21
|
char: 'o',
|
|
22
22
|
summary: 'output meta.json file',
|
|
23
23
|
helpValue: '<path>',
|
|
24
|
-
required: true
|
|
25
|
-
})
|
|
24
|
+
required: true,
|
|
25
|
+
}),
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
public async run(): Promise<void> {
|
|
@@ -30,7 +30,7 @@ export default class BuildMeta extends Command {
|
|
|
30
30
|
const modulePath = path.resolve(flags.modulePath);
|
|
31
31
|
const descriptionRaw = await loadPackDescriptionRaw(modulePath);
|
|
32
32
|
const metaEmbedded = await BlockPackMetaEmbedAbsoluteBase64.parseAsync(
|
|
33
|
-
BlockPackMetaDescription(modulePath).parse(descriptionRaw.meta)
|
|
33
|
+
BlockPackMetaDescription(modulePath).parse(descriptionRaw.meta),
|
|
34
34
|
);
|
|
35
35
|
|
|
36
36
|
await fs.promises.writeFile(path.resolve(flags.destination), JSON.stringify(metaEmbedded));
|
package/src/cmd/build-model.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Command, Flags } from '@oclif/core';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import path from 'path';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
4
|
|
|
5
5
|
async function getFileContent(path: string) {
|
|
6
6
|
try {
|
|
7
7
|
return await fs.promises.readFile(path, 'utf8');
|
|
8
|
-
} catch (error:
|
|
9
|
-
if (error.code === 'ENOENT') {
|
|
8
|
+
} catch (error: unknown) {
|
|
9
|
+
if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
|
|
10
10
|
return undefined;
|
|
11
11
|
}
|
|
12
12
|
throw error;
|
|
@@ -14,60 +14,64 @@ async function getFileContent(path: string) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export default class BuildModel extends Command {
|
|
17
|
-
static override description
|
|
18
|
-
'Extracts and outputs block model JSON from pre-built block model module';
|
|
17
|
+
static override description
|
|
18
|
+
= 'Extracts and outputs block model JSON from pre-built block model module';
|
|
19
19
|
|
|
20
20
|
static flags = {
|
|
21
21
|
modulePath: Flags.string({
|
|
22
22
|
char: 'i',
|
|
23
23
|
summary: 'input module path',
|
|
24
24
|
helpValue: '<path>',
|
|
25
|
-
default: '.'
|
|
25
|
+
default: '.',
|
|
26
26
|
}),
|
|
27
27
|
|
|
28
28
|
sourceBundle: Flags.string({
|
|
29
29
|
char: 'b',
|
|
30
30
|
summary: 'bundled model code to embed into the model for callback-based rendering to work',
|
|
31
31
|
helpValue: '<path>',
|
|
32
|
-
default: './dist/bundle.js'
|
|
32
|
+
default: './dist/bundle.js',
|
|
33
33
|
}),
|
|
34
34
|
|
|
35
35
|
destination: Flags.string({
|
|
36
36
|
char: 'o',
|
|
37
37
|
summary: 'output model file',
|
|
38
38
|
helpValue: '<path>',
|
|
39
|
-
default: './dist/model.json'
|
|
40
|
-
})
|
|
39
|
+
default: './dist/model.json',
|
|
40
|
+
}),
|
|
41
41
|
};
|
|
42
42
|
|
|
43
43
|
public async run(): Promise<void> {
|
|
44
44
|
const { flags } = await this.parse(BuildModel);
|
|
45
45
|
const modulePath = path.resolve(flags.modulePath); // i.e. folder with package.json file
|
|
46
|
+
// eslint-disable-next-line prefer-const, @typescript-eslint/no-unsafe-assignment
|
|
46
47
|
let { model, platforma } = require(modulePath);
|
|
47
48
|
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
48
50
|
if (!model) model = platforma;
|
|
49
51
|
if (!model) throw new Error('"model" export not found');
|
|
50
52
|
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
51
54
|
const { config } = model;
|
|
52
55
|
|
|
53
56
|
if (!config)
|
|
54
57
|
throw new Error(
|
|
55
|
-
'Malformed "model" object, check it is created with "BlockModel" '
|
|
56
|
-
|
|
58
|
+
'Malformed "model" object, check it is created with "BlockModel" '
|
|
59
|
+
+ 'and ".done()" is executed as the call in the chain.',
|
|
57
60
|
);
|
|
58
61
|
|
|
59
62
|
if (
|
|
60
|
-
!('canRun' in config || 'inputsValid' in config)
|
|
61
|
-
!('outputs' in config)
|
|
62
|
-
!('sections' in config)
|
|
63
|
+
!('canRun' in config || 'inputsValid' in config)
|
|
64
|
+
|| !('outputs' in config)
|
|
65
|
+
|| !('sections' in config)
|
|
63
66
|
)
|
|
64
67
|
throw new Error('"config" has unexpected structure');
|
|
65
68
|
|
|
66
69
|
const code = await getFileContent(flags.sourceBundle);
|
|
67
70
|
if (code !== undefined) {
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
68
72
|
config.code = {
|
|
69
73
|
type: 'plain',
|
|
70
|
-
content: code
|
|
74
|
+
content: code,
|
|
71
75
|
};
|
|
72
76
|
}
|
|
73
77
|
|
package/src/cmd/index.ts
CHANGED
|
@@ -12,22 +12,22 @@ export default class ListOverviewSnapshots extends Command {
|
|
|
12
12
|
summary: 'full address of the registry',
|
|
13
13
|
helpValue: '<address>',
|
|
14
14
|
env: 'PL_REGISTRY',
|
|
15
|
-
required: true
|
|
15
|
+
required: true,
|
|
16
16
|
}),
|
|
17
17
|
|
|
18
18
|
json: Flags.boolean({
|
|
19
19
|
summary: 'output in JSON format',
|
|
20
|
-
default: false
|
|
21
|
-
})
|
|
20
|
+
default: false,
|
|
21
|
+
}),
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
public async run(): Promise<void> {
|
|
25
25
|
const { flags } = await this.parse(ListOverviewSnapshots);
|
|
26
26
|
const storage = storageByUrl(flags.registry);
|
|
27
27
|
const registry = new BlockRegistryV2(storage, new OclifLoggerAdapter(this));
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
const snapshots = await registry.listGlobalOverviewSnapshots();
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
if (flags.json) {
|
|
32
32
|
this.log(JSON.stringify(snapshots, null, 2));
|
|
33
33
|
} else {
|
package/src/cmd/mark-stable.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { Command, Flags } from '@oclif/core';
|
|
2
2
|
import { BlockRegistryV2, loadPackDescriptionRaw } from '../v2';
|
|
3
|
-
import path from 'path';
|
|
3
|
+
import path from 'node:path';
|
|
4
4
|
import {
|
|
5
5
|
overrideDescriptionVersion,
|
|
6
|
-
|
|
7
|
-
StableChannel
|
|
6
|
+
StableChannel,
|
|
8
7
|
} from '@milaboratories/pl-model-middle-layer';
|
|
9
8
|
import { storageByUrl } from '../io';
|
|
10
9
|
import { OclifLoggerAdapter } from '@milaboratories/ts-helpers-oclif';
|
|
@@ -13,46 +12,46 @@ export default class MarkStable extends Command {
|
|
|
13
12
|
static description = 'Mark target block stable';
|
|
14
13
|
|
|
15
14
|
static flags = {
|
|
16
|
-
modulePath: Flags.string({
|
|
15
|
+
'modulePath': Flags.string({
|
|
17
16
|
char: 'i',
|
|
18
17
|
summary: 'input module path',
|
|
19
18
|
helpValue: '<path>',
|
|
20
|
-
default: '.'
|
|
19
|
+
default: '.',
|
|
21
20
|
}),
|
|
22
21
|
|
|
23
|
-
channel: Flags.string({
|
|
22
|
+
'channel': Flags.string({
|
|
24
23
|
char: 'c',
|
|
25
24
|
hidden: true,
|
|
26
25
|
summary: 'custom channel',
|
|
27
26
|
helpValue: '<channel name>',
|
|
28
|
-
default: StableChannel
|
|
27
|
+
default: StableChannel,
|
|
29
28
|
}),
|
|
30
29
|
|
|
31
30
|
'version-override': Flags.file({
|
|
32
31
|
char: 'v',
|
|
33
|
-
summary: 'override package version'
|
|
32
|
+
summary: 'override package version',
|
|
34
33
|
}),
|
|
35
34
|
|
|
36
|
-
registry: Flags.string({
|
|
35
|
+
'registry': Flags.string({
|
|
37
36
|
char: 'r',
|
|
38
37
|
summary: 'full address of the registry',
|
|
39
38
|
helpValue: '<address>',
|
|
40
39
|
env: 'PL_REGISTRY',
|
|
41
|
-
required: true
|
|
40
|
+
required: true,
|
|
42
41
|
}),
|
|
43
42
|
|
|
44
|
-
refresh: Flags.boolean({
|
|
43
|
+
'refresh': Flags.boolean({
|
|
45
44
|
summary: 'refresh repository after adding the package',
|
|
46
45
|
default: true,
|
|
47
46
|
allowNo: true,
|
|
48
|
-
env: 'PL_REGISTRY_REFRESH'
|
|
47
|
+
env: 'PL_REGISTRY_REFRESH',
|
|
49
48
|
}),
|
|
50
49
|
|
|
51
|
-
unmark: Flags.boolean({
|
|
50
|
+
'unmark': Flags.boolean({
|
|
52
51
|
summary:
|
|
53
52
|
'reverses meaning of this command, flag can be used to remove "stable" flag from the package',
|
|
54
|
-
default: false
|
|
55
|
-
})
|
|
53
|
+
default: false,
|
|
54
|
+
}),
|
|
56
55
|
};
|
|
57
56
|
|
|
58
57
|
public async run(): Promise<void> {
|