@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.
Files changed (48) hide show
  1. package/dist/cli.js +3 -3
  2. package/dist/cli.js.map +1 -1
  3. package/dist/cli.mjs +15 -13
  4. package/dist/cli.mjs.map +1 -1
  5. package/dist/{config-XBQ2O39y.mjs → config-DKBY0B2u.mjs} +272 -273
  6. package/dist/config-DKBY0B2u.mjs.map +1 -0
  7. package/dist/config-Ycas5fbX.js +3 -0
  8. package/dist/config-Ycas5fbX.js.map +1 -0
  9. package/dist/index.js +1 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/index.mjs +18 -17
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/registry_v1/v1_repo_schema.d.ts +2 -2
  14. package/package.json +18 -15
  15. package/src/cmd/build-meta.ts +9 -9
  16. package/src/cmd/build-model.ts +20 -16
  17. package/src/cmd/index.ts +0 -1
  18. package/src/cmd/list-overview-snapshots.ts +5 -5
  19. package/src/cmd/mark-stable.ts +14 -15
  20. package/src/cmd/pack.ts +7 -7
  21. package/src/cmd/publish.ts +16 -16
  22. package/src/cmd/refresh-registry.ts +4 -10
  23. package/src/cmd/restore-overview-from-snapshot.ts +16 -16
  24. package/src/cmd/update-deps.ts +3 -2
  25. package/src/cmd/upload-package-v1.ts +12 -12
  26. package/src/io/folder_reader.ts +15 -11
  27. package/src/io/storage.ts +25 -23
  28. package/src/registry_v1/config.ts +11 -10
  29. package/src/registry_v1/config_schema.ts +5 -5
  30. package/src/registry_v1/flags.ts +3 -2
  31. package/src/registry_v1/registry.ts +34 -35
  32. package/src/registry_v1/v1_repo_schema.ts +2 -2
  33. package/src/util.ts +15 -11
  34. package/src/v2/build_dist.ts +12 -9
  35. package/src/v2/model/block_components.ts +6 -6
  36. package/src/v2/model/block_description.ts +13 -13
  37. package/src/v2/model/block_meta.ts +10 -9
  38. package/src/v2/model/content_conversion.ts +28 -26
  39. package/src/v2/registry/index.ts +3 -3
  40. package/src/v2/registry/registry.test.ts +1 -1
  41. package/src/v2/registry/registry.ts +64 -63
  42. package/src/v2/registry/registry_reader.ts +47 -46
  43. package/src/v2/registry/schema_internal.ts +3 -3
  44. package/src/v2/registry/schema_public.ts +29 -26
  45. package/src/v2/source_package.ts +26 -23
  46. package/dist/config-DjpRXRy9.js +0 -3
  47. package/dist/config-DjpRXRy9.js.map +0 -1
  48. 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 z, z as W } from "./config-XBQ2O39y.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 ze, a1 as We, a5 as Ie, W as _e, 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-XBQ2O39y.mjs";
6
- import { request as I } from "undici";
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 _ from "node:fs/promises";
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 I(t, {
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
- let t = this;
174
- return e !== void 0 && (t = t.relativeReader(e)), (a) => t.readFile(a);
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 _.readFile(t);
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
- let t = this;
193
- return e !== void 0 && (t = t.relativeReader(e)), (a) => t.readFile(a);
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: z,
229
- payloadFilePath: W
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
- ze as PackageOverview,
263
- We as PackageOverviewFileName,
264
- Ie as PackageOverviewVersionEntry,
263
+ _e as PackageOverview,
264
+ ze as PackageOverviewFileName,
265
+ We as PackageOverviewVersionEntry,
265
266
  ve as RegistryV1,
266
267
  me as RegistryV2Reader,
267
- _e as ResolvedBlockPackDescriptionFromPackageJson,
268
+ Ie as ResolvedBlockPackDescriptionFromPackageJson,
268
269
  qe as ResolvedModuleFile,
269
270
  $e as ResolvedModuleFolder,
270
271
  He as S3Storage,
@@ -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: object;
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: any;
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.27",
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.21.10",
41
- "@milaboratories/pl-model-middle-layer": "1.8.45",
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-v8": "^4.0.7",
55
- "vitest": "^4.0.7",
49
+ "@vitest/coverage-istanbul": "^4.0.16",
50
+ "eslint": "^9.25.1",
56
51
  "oclif": "^4.16.2",
57
- "@milaboratories/build-configs": "1.0.9",
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.6"
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
  }
@@ -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));
@@ -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: any) {
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
- 'and ".done()" is executed as the call in the chain.'
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
@@ -11,7 +11,6 @@ import Cmd8 from './restore-overview-from-snapshot';
11
11
  import Cmd9 from './upload-package-v1';
12
12
  import Cmd10 from './update-deps';
13
13
 
14
- // prettier-ignore
15
14
  export const COMMANDS = {
16
15
  'build-meta': Cmd0,
17
16
  'build-model': Cmd1,
@@ -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 {
@@ -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
- overrideManifestVersion,
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> {