@holoscript/holosystem 0.2.1 → 0.2.2

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/catalog.mjs +20 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holoscript/holosystem",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Portable bootstrap, consumption catalog, lineage, and bounded-work contract for HoloSystem consumers.",
5
5
  "releaseLane": "v0-preview",
6
6
  "keywords": [
package/src/catalog.mjs CHANGED
@@ -179,6 +179,13 @@ export function buildSourceLineageReceipt({ portfolio, metadata = [], now = new
179
179
  const artifacts = list(portfolio?.packages).map((row) => {
180
180
  const source = metadataByArtifact.get(artifactKey(row.ecosystem, row.name)) || {};
181
181
  const sourceRepository = normalizeRepositoryUrl(source.sourceRepository || source.repository);
182
+ const deprecated = typeof source.deprecated === 'string' && source.deprecated.trim()
183
+ ? source.deprecated.trim()
184
+ : null;
185
+ const successor = typeof source.successor === 'string' && source.successor.trim()
186
+ ? source.successor.trim()
187
+ : null;
188
+ const migrationMapped = Boolean(deprecated && successor);
182
189
  return {
183
190
  ecosystem: row.ecosystem,
184
191
  name: row.name,
@@ -189,7 +196,10 @@ export function buildSourceLineageReceipt({ portfolio, metadata = [], now = new
189
196
  registryError: source.registryError ? String(source.registryError).slice(0, 240) : null,
190
197
  integrity: typeof source.integrity === 'string' ? source.integrity : null,
191
198
  sourceRevision: typeof source.sourceRevision === 'string' ? source.sourceRevision : null,
192
- mapped: Boolean(sourceRepository),
199
+ deprecated,
200
+ successor,
201
+ lineageKind: sourceRepository ? 'repository' : migrationMapped ? 'migration' : 'unknown',
202
+ mapped: Boolean(sourceRepository) || migrationMapped,
193
203
  };
194
204
  });
195
205
  const mapped = artifacts.filter((artifact) => artifact.mapped).length;
@@ -207,6 +217,7 @@ export function buildSourceLineageReceipt({ portfolio, metadata = [], now = new
207
217
  registryMetadataIsEvidence: true,
208
218
  localPathsForbidden: true,
209
219
  unknownLineageBlocksSourceClaims: true,
220
+ deprecatedPackagesRequireNamedSuccessors: true,
210
221
  },
211
222
  };
212
223
  receipt.receiptHash = hashReceipt({ ...receipt, generatedAt: null });
@@ -450,6 +461,12 @@ function pypiRepository(info) {
450
461
  return normalizeRepositoryUrl(info?.home_page);
451
462
  }
452
463
 
464
+ function npmMigrationSuccessor(message) {
465
+ if (typeof message !== 'string' || !message.trim()) return null;
466
+ const match = message.match(/\buse\s+(@[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._-]*|[a-z0-9][a-z0-9._-]*)\b/iu);
467
+ return match?.[1] || null;
468
+ }
469
+
453
470
  export async function discoverSourceLineage({
454
471
  portfolio,
455
472
  fetchImpl = globalThis.fetch,
@@ -472,6 +489,8 @@ export async function discoverSourceLineage({
472
489
  registryError: response.error || null,
473
490
  integrity: response.body?.dist?.integrity || null,
474
491
  sourceRevision: response.body?.gitHead || null,
492
+ deprecated: typeof response.body?.deprecated === 'string' ? response.body.deprecated : null,
493
+ successor: npmMigrationSuccessor(response.body?.deprecated),
475
494
  };
476
495
  }
477
496
  const suffix = version ? `/${encodeURIComponent(version)}` : '';