@longzai-intelligence-npm-registry/core 0.0.7 → 0.0.9

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/index.d.ts CHANGED
@@ -1,24 +1,23 @@
1
1
  import "./rolldown-runtime-BqT_7tdF.js";
2
2
  import * as z from "zod";
3
3
  import { DomainError } from "@longzai-intelligence-error/core";
4
- //#region src/contracts/package.schema.d.ts
5
4
  /**
6
5
  * 本地包摘要 DTO(引擎 listPackages 条目;`GET /api/packages` 数据)
7
6
  */
8
7
  declare const PackageSummarySchema: z.ZodObject<{
9
8
  name: z.ZodString;
10
- versionCount: z.ZodNumber;
9
+ versionCount: z.ZodInt;
11
10
  latest: z.ZodOptional<z.ZodString>;
12
- modified: z.ZodOptional<z.ZodString>;
11
+ modified: z.ZodOptional<z.ZodISODateTime>;
13
12
  }, z.core.$strip>;
14
13
  /**
15
14
  * 本地包详情 DTO(`GET /api/packages/:name` 数据)
16
15
  */
17
16
  declare const PackageDetailSchema: z.ZodObject<{
18
17
  name: z.ZodString;
19
- versionCount: z.ZodNumber;
18
+ versionCount: z.ZodInt;
20
19
  latest: z.ZodOptional<z.ZodString>;
21
- modified: z.ZodOptional<z.ZodString>;
20
+ modified: z.ZodOptional<z.ZodISODateTime>;
22
21
  distTags: z.ZodRecord<z.ZodString, z.ZodString>;
23
22
  versions: z.ZodArray<z.ZodString>;
24
23
  }, z.core.$strip>;
@@ -30,8 +29,6 @@ type PackageDetail = z.infer<typeof PackageDetailSchema>;
30
29
  * 本地包摘要 DTO 形态
31
30
  */
32
31
  type PackageSummary = z.infer<typeof PackageSummarySchema>;
33
- //#endregion
34
- //#region src/contracts/protocol.schema.d.ts
35
32
  /**
36
33
  * npm 包名合法形态(scoped `@scope/name` 或 unscoped;小写字母开头,允许 . _ - 与数字)
37
34
  */
@@ -62,9 +59,9 @@ declare const SemverSchema: z.ZodString;
62
59
  declare const DistMetaSchema: z.ZodObject<{
63
60
  shasum: z.ZodOptional<z.ZodString>;
64
61
  integrity: z.ZodOptional<z.ZodString>;
65
- tarball: z.ZodOptional<z.ZodString>;
66
- fileCount: z.ZodOptional<z.ZodNumber>;
67
- unpackedSize: z.ZodOptional<z.ZodNumber>;
62
+ tarball: z.ZodOptional<z.ZodURL>;
63
+ fileCount: z.ZodOptional<z.ZodInt>;
64
+ unpackedSize: z.ZodOptional<z.ZodInt>;
68
65
  }, z.core.$strip>;
69
66
  /**
70
67
  * 单版本 manifest(npm packument `versions[v]` 条目;客户端 manifest 字段全量透传,此处只约束必需键)
@@ -75,9 +72,9 @@ declare const VersionManifestSchema: z.ZodObject<{
75
72
  dist: z.ZodObject<{
76
73
  shasum: z.ZodOptional<z.ZodString>;
77
74
  integrity: z.ZodOptional<z.ZodString>;
78
- tarball: z.ZodOptional<z.ZodString>;
79
- fileCount: z.ZodOptional<z.ZodNumber>;
80
- unpackedSize: z.ZodOptional<z.ZodNumber>;
75
+ tarball: z.ZodOptional<z.ZodURL>;
76
+ fileCount: z.ZodOptional<z.ZodInt>;
77
+ unpackedSize: z.ZodOptional<z.ZodInt>;
81
78
  }, z.core.$strip>;
82
79
  }, z.core.$loose>;
83
80
  /**
@@ -99,9 +96,9 @@ declare const PackumentSchema: z.ZodObject<{
99
96
  dist: z.ZodObject<{
100
97
  shasum: z.ZodOptional<z.ZodString>;
101
98
  integrity: z.ZodOptional<z.ZodString>;
102
- tarball: z.ZodOptional<z.ZodString>;
103
- fileCount: z.ZodOptional<z.ZodNumber>;
104
- unpackedSize: z.ZodOptional<z.ZodNumber>;
99
+ tarball: z.ZodOptional<z.ZodURL>;
100
+ fileCount: z.ZodOptional<z.ZodInt>;
101
+ unpackedSize: z.ZodOptional<z.ZodInt>;
105
102
  }, z.core.$strip>;
106
103
  }, z.core.$loose>>;
107
104
  time: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
@@ -117,7 +114,7 @@ declare const PackumentSchema: z.ZodObject<{
117
114
  declare const PublishAttachmentSchema: z.ZodObject<{
118
115
  content_type: z.ZodString;
119
116
  data: z.ZodString;
120
- length: z.ZodNumber;
117
+ length: z.ZodInt;
121
118
  }, z.core.$strip>;
122
119
  /**
123
120
  * publish 请求载荷(`PUT /:package` 请求体;versions 仅含本次新版本)
@@ -133,9 +130,9 @@ declare const PublishPayloadSchema: z.ZodObject<{
133
130
  dist: z.ZodObject<{
134
131
  shasum: z.ZodOptional<z.ZodString>;
135
132
  integrity: z.ZodOptional<z.ZodString>;
136
- tarball: z.ZodOptional<z.ZodString>;
137
- fileCount: z.ZodOptional<z.ZodNumber>;
138
- unpackedSize: z.ZodOptional<z.ZodNumber>;
133
+ tarball: z.ZodOptional<z.ZodURL>;
134
+ fileCount: z.ZodOptional<z.ZodInt>;
135
+ unpackedSize: z.ZodOptional<z.ZodInt>;
139
136
  }, z.core.$strip>;
140
137
  }, z.core.$loose>>;
141
138
  access: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
@@ -146,7 +143,7 @@ declare const PublishPayloadSchema: z.ZodObject<{
146
143
  _attachments: z.ZodRecord<z.ZodString, z.ZodObject<{
147
144
  content_type: z.ZodString;
148
145
  data: z.ZodString;
149
- length: z.ZodNumber;
146
+ length: z.ZodInt;
150
147
  }, z.core.$strip>>;
151
148
  maintainers: z.ZodOptional<z.ZodArray<z.ZodObject<{
152
149
  name: z.ZodString;
@@ -233,8 +230,6 @@ type VersionManifest = z.infer<typeof VersionManifestSchema>;
233
230
  * whoami 响应形态
234
231
  */
235
232
  type WhoamiResponse = z.infer<typeof WhoamiResponseSchema>;
236
- //#endregion
237
- //#region src/contracts/store.schema.d.ts
238
233
  /**
239
234
  * 本地 token 前缀(签发明文形态 `lzi_local_<随机>`;存储只落 sha256 哈希)
240
235
  */
@@ -258,8 +253,8 @@ declare const TokenRecordSchema: z.ZodObject<{
258
253
  username: z.ZodString;
259
254
  tokenHash: z.ZodString;
260
255
  note: z.ZodOptional<z.ZodString>;
261
- createdAt: z.ZodString;
262
- revokedAt: z.ZodOptional<z.ZodString>;
256
+ createdAt: z.ZodISODateTime;
257
+ revokedAt: z.ZodOptional<z.ZodISODateTime>;
263
258
  }, z.core.$strip>;
264
259
  /**
265
260
  * auth store(`<DATA_ROOT>/auth.json` 落盘形状)
@@ -277,8 +272,8 @@ declare const AuthStoreSchema: z.ZodObject<{
277
272
  username: z.ZodString;
278
273
  tokenHash: z.ZodString;
279
274
  note: z.ZodOptional<z.ZodString>;
280
- createdAt: z.ZodString;
281
- revokedAt: z.ZodOptional<z.ZodString>;
275
+ createdAt: z.ZodISODateTime;
276
+ revokedAt: z.ZodOptional<z.ZodISODateTime>;
282
277
  }, z.core.$strip>>;
283
278
  }, z.core.$strip>;
284
279
  /**
@@ -288,7 +283,7 @@ declare const TokenCreateInfoSchema: z.ZodObject<{
288
283
  id: z.ZodString;
289
284
  token: z.ZodString;
290
285
  note: z.ZodOptional<z.ZodString>;
291
- createdAt: z.ZodString;
286
+ createdAt: z.ZodISODateTime;
292
287
  }, z.core.$strip>;
293
288
  /**
294
289
  * token 信息 DTO(不含明文)
@@ -296,7 +291,7 @@ declare const TokenCreateInfoSchema: z.ZodObject<{
296
291
  declare const TokenInfoSchema: z.ZodObject<{
297
292
  id: z.ZodString;
298
293
  note: z.ZodOptional<z.ZodString>;
299
- createdAt: z.ZodString;
294
+ createdAt: z.ZodISODateTime;
300
295
  revoked: z.ZodBoolean;
301
296
  }, z.core.$strip>;
302
297
  /**
@@ -319,8 +314,6 @@ type TokenInfo = z.infer<typeof TokenInfoSchema>;
319
314
  * token 记录形态
320
315
  */
321
316
  type TokenRecord = z.infer<typeof TokenRecordSchema>;
322
- //#endregion
323
- //#region src/auth.store.d.ts
324
317
  /**
325
318
  * auth store 工厂参数
326
319
  */
@@ -394,8 +387,6 @@ type AuthStoreHandle = {
394
387
  * @returns auth store 句柄
395
388
  */
396
389
  declare function createAuthStore(options: AuthStoreOptions): AuthStoreHandle;
397
- //#endregion
398
- //#region src/errors.d.ts
399
390
  /**
400
391
  * 包不存在(→ 404)
401
392
  */
@@ -521,8 +512,6 @@ declare class InvalidCredentialsError extends DomainError {
521
512
  */
522
513
  constructor();
523
514
  }
524
- //#endregion
525
- //#region src/package.operations.d.ts
526
515
  /**
527
516
  * publish 结果
528
517
  */
@@ -545,8 +534,6 @@ type UnpublishResult = {
545
534
  */
546
535
  rev: string;
547
536
  };
548
- //#endregion
549
- //#region src/registry.engine.d.ts
550
537
  /**
551
538
  * 引擎工厂参数
552
539
  */
@@ -679,8 +666,6 @@ type LocalNpmRegistry = {
679
666
  * @returns 引擎句柄
680
667
  */
681
668
  declare function createLocalNpmRegistry(options: LocalNpmRegistryOptions): LocalNpmRegistry;
682
- //#endregion
683
- //#region src/store.utils.d.ts
684
669
  /**
685
670
  * 存储布局与基础工具:目录布局 / 转义命名 / 原子写 / 哈希 / 语义化版本比较 / 修订号。
686
671
  *
@@ -787,5 +772,4 @@ declare function compareSemver(a: string, b: string): number;
787
772
  * @returns 新修订号
788
773
  */
789
774
  declare function nextRevision(current: string | undefined): string;
790
- //#endregion
791
775
  export { AUTH_STORE_VERSION, type AuthStore, type AuthStoreHandle, type AuthStoreOptions, AuthStoreSchema, COUCHDB_USER_ID_PREFIX, type CouchUserPayload, CouchUserPayloadSchema, DIST_TAG_PATTERN, type DistMeta, DistMetaSchema, type DistTagMap, DistTagMapSchema, InvalidCredentialsError, type LocalNpmRegistry, type LocalNpmRegistryOptions, type NpmErrorResponse, NpmErrorResponseSchema, PACKAGE_NAME_PATTERN, type PackageDetail, PackageDetailSchema, type PackageIdentifier, PackageIdentifierSchema, PackageNotFoundError, type PackageSummary, PackageSummarySchema, PackageVersionNotFoundError, type Packument, PackumentSchema, type PasswordRecord, PasswordRecordSchema, ProtocolPayloadError, type PublishAttachment, PublishAttachmentSchema, type PublishPayload, PublishPayloadError, PublishPayloadSchema, type PublishResponse, PublishResponseSchema, type PublishResult, RevisionMismatchError, SEMVER_PATTERN, ScopeNotAllowedError, type Semver, SemverSchema, ShasumMismatchError, TOKEN_PREFIX, type TokenCreateInfo, TokenCreateInfoSchema, type TokenInfo, TokenInfoSchema, TokenInvalidError, type TokenRecord, TokenRecordSchema, type UnpublishResult, UserAlreadyExistsError, VersionExistsError, type VersionManifest, VersionManifestSchema, type WhoamiResponse, WhoamiResponseSchema, atomicWriteBytes, atomicWriteJson, compareSemver, createAuthStore, createLocalNpmRegistry, escapePackageName, nextRevision, nowIso, packageDirPath, packumentPath, sha1Hex, sha256Hex, tarballFileName, tarballPath, unescapePackageName };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import"./rolldown-runtime-BqT_7tdF.js";import*as e from"zod";import{existsSync as t,mkdirSync as n,readFileSync as r,readdirSync as i,renameSync as a,rmSync as o,unlinkSync as s,writeFileSync as c}from"node:fs";import{join as l}from"node:path";import{DomainError as u}from"@longzai-intelligence-error/core";import{createHash as d,randomBytes as f}from"node:crypto";const p=/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/,m=/^\d+\.\d+\.\d+(-[0-9A-Za-z-.+]+)?(\+[0-9A-Za-z-.]+)?$/,h=/^[a-z][a-z0-9-._]*$/i,g=`org.couchdb.user:`,_=e.string().regex(p),v=e.string().regex(m),y=e.object({shasum:e.string().regex(/^[0-9a-f]{40}$/).optional(),integrity:e.string().optional(),tarball:e.string().url().optional(),fileCount:e.number().int().nonnegative().optional(),unpackedSize:e.number().int().nonnegative().optional()}),b=e.looseObject({name:_,version:v,dist:y}),x=e.record(e.string().regex(h),v),S=e.looseObject({_id:_,_rev:e.string().regex(/^\d+-[0-9a-f]+$/).optional(),name:_,description:e.string().optional(),"dist-tags":x,versions:e.record(v,b),time:e.record(e.string(),e.string()).optional(),maintainers:e.array(e.looseObject({name:e.string(),email:e.string().optional()})).optional(),readme:e.string().optional()}),C=e.object({content_type:e.string(),data:e.string(),length:e.number().int().nonnegative()}),w=e.looseObject({_id:_.optional(),name:_,description:e.string().optional(),"dist-tags":x,versions:e.record(v,b).refine(e=>Object.keys(e).length>=1,{error:`publish 载荷 versions 至少含一个新版本`}),access:e.enum([`public`,`restricted`]).nullish(),readme:e.string().optional(),_attachments:e.record(e.string(),C).refine(e=>Object.keys(e).length>=1,{error:`publish 载荷 _attachments 至少含一个 tarball`}),maintainers:e.array(e.looseObject({name:e.string(),email:e.string().optional()})).optional()}).refine(e=>e._id===void 0||e._id===e.name,{error:`publish 载荷 _id 与 name 不一致`,path:[`_id`]}),ee=e.object({ok:e.literal(!0),rev:e.string(),id:e.string().optional()}),te=e.object({username:e.string().min(1)}),ne=e.looseObject({_id:e.string().optional(),name:e.string().min(1).regex(/^[a-z][a-z0-9-]*$/i,{error:`用户名仅允许字母数字与中划线`}),password:e.string().min(1),email:e.email().optional(),type:e.literal(`user`).optional(),roles:e.array(e.string()).optional(),date:e.string().optional()}),re=e.object({error:e.string()}),ie=e.object({name:_,versionCount:e.number().int().positive(),latest:v.optional(),modified:e.string().datetime().optional()}),ae=e.object({name:_,versionCount:e.number().int().positive(),latest:v.optional(),modified:e.string().datetime().optional(),distTags:x,versions:e.array(v)}),T=`lzi_local_`,oe=1,E=e.object({salt:e.string().regex(/^[0-9a-f]{32}$/),hash:e.string().regex(/^[0-9a-f]{64}$/)}),D=e.object({id:e.string().regex(/^[0-9a-f]{8}$/),username:e.string().min(1),tokenHash:e.string().regex(/^[0-9a-f]{64}$/),note:e.string().optional(),createdAt:e.string().datetime(),revokedAt:e.string().datetime().optional()}),O=e.object({version:e.literal(1),users:e.record(e.string(),e.object({password:E})),tokens:e.array(D)}),se=e.object({id:e.string().regex(/^[0-9a-f]{8}$/),token:e.string(),note:e.string().optional(),createdAt:e.string().datetime()}),ce=e.object({id:e.string().regex(/^[0-9a-f]{8}$/),note:e.string().optional(),createdAt:e.string().datetime(),revoked:e.boolean()});var k=class extends u{constructor(e){super(`包不存在: ${e}`,`NPM_REGISTRY_PACKAGE_NOT_FOUND`,{name:e}),this.name=`PackageNotFoundError`}},A=class extends u{constructor(e,t){super(`包版本不存在: ${e}@${t}`,`NPM_REGISTRY_PACKAGE_VERSION_NOT_FOUND`,{name:e,version:t}),this.name=`PackageVersionNotFoundError`}},j=class extends u{constructor(e,t){super(`版本已存在,npm 版本不可变: ${e}@${t}`,`NPM_REGISTRY_VERSION_EXISTS`,{name:e,version:t}),this.name=`VersionExistsError`}},M=class extends u{constructor(e,t,n){super(`修订号不匹配(携带 ${t},当前 ${n}),请重新获取 packument`,`NPM_REGISTRY_REVISION_MISMATCH`,{name:e,expected:t,actual:n}),this.name=`RevisionMismatchError`}},N=class extends u{constructor(e){super(`publish 载荷不合法: ${e}`,`NPM_REGISTRY_PUBLISH_PAYLOAD_INVALID`,{reason:e}),this.name=`PublishPayloadError`}},le=class extends u{constructor(e,t){super(`${e} 载荷不合法: ${t}`,`NPM_REGISTRY_PROTOCOL_PAYLOAD_INVALID`,{kind:e,reason:t}),this.name=`ProtocolPayloadError`}},P=class extends u{constructor(e,t,n,r){super(`tarball shasum 不符(声明 ${n},实测 ${r}): ${e}@${t}`,`NPM_REGISTRY_SHASUM_MISMATCH`,{name:e,version:t,declared:n,actual:r}),this.name=`ShasumMismatchError`}},F=class extends u{constructor(e){super(`包名不在允许发布的 scope 内: ${e}`,`NPM_REGISTRY_SCOPE_NOT_ALLOWED`,{name:e}),this.name=`ScopeNotAllowedError`}},I=class extends u{constructor(){super(`token 无效或已吊销`,`NPM_REGISTRY_TOKEN_INVALID`,{}),this.name=`TokenInvalidError`}},L=class extends u{constructor(e){super(`本地用户已存在: ${e}`,`NPM_REGISTRY_USER_ALREADY_EXISTS`,{name:e}),this.name=`UserAlreadyExistsError`}},R=class extends u{constructor(){super(`用户名或口令错误`,`NPM_REGISTRY_INVALID_CREDENTIALS`,{}),this.name=`InvalidCredentialsError`}};function z(e,t){return l(e,`store`,H(t))}function B(e,t){return l(z(e,t),`index.json`)}function V(e,t,n){return l(z(e,t),`tarballs`,U(t,n))}function H(e){return e.replace(/\//g,`%2f`)}function ue(e){return e.replace(/%2f/g,`/`)}function U(e,t){return`${e.split(`/`).at(-1)??e}-${t}.tgz`}function W(e,t){let n=`${e}.${process.pid}.tmp`;c(n,`${JSON.stringify(t,null,2)}\n`,`utf8`),a(n,e)}function G(e,t){let n=`${e}.${process.pid}.tmp`;c(n,t),a(n,e)}function K(e){t(e)||n(e,{recursive:!0})}function q(e){return d(`sha1`).update(e).digest(`hex`)}function J(e){return d(`sha256`).update(e).digest(`hex`)}function Y(e){return f(e).toString(`hex`)}function X(){return(/* @__PURE__ */ new Date()).toISOString()}function Z(e){let[t=``]=e.split(`+`),[n=``,r]=t.split(`-`),[i=0,a=0,o=0]=n.split(`.`).map(e=>Number.parseInt(e,10));return{core:[i,a,o],pre:r===void 0?null:r.split(`.`)}}function Q(e,t){let n=Z(e),r=Z(t);for(let e=0;e<3;e++){let t=n.core[e]??0,i=r.core[e]??0;if(t!==i)return t-i}return n.pre===null&&r.pre===null?0:n.pre===null?1:r.pre===null?-1:de(n.pre,r.pre)}function de(e,t){let n=Math.min(e.length,t.length);for(let r=0;r<n;r++){let n=e[r]??``,i=t[r]??``,a=/^\d+$/.test(n),o=/^\d+$/.test(i);if(a&&o){let e=Number.parseInt(n,10)-Number.parseInt(i,10);if(e!==0)return e;continue}if(a)return-1;if(o)return 1;if(n!==i)return n<i?-1:1}return e.length-t.length}function $(e){return`${Number.parseInt(e?.split(`-`)[0]??`0`,10)+1}-${Y(4)}`}function fe(e){let n=l(e.dataRoot,`auth.json`),i=()=>{if(!t(n))return{version:1,users:{},tokens:[]};let e=O.safeParse(JSON.parse(r(n,`utf8`)));if(!e.success)throw Error(`[core] auth.json 不合法:${e.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `)}`);return e.data},a=e=>{W(n,e)};return{createUser:(e,t)=>{let n=i(),r=Object.keys(n.users)[0];if(r!==void 0)throw new L(r);let o=Y(16);n.users[e]={password:{salt:o,hash:J(o+t)}},a(n)},verifyPassword:(e,t)=>{let n=i().users[e];if(n===void 0||J(n.password.salt+t)!==n.password.hash)throw new R},getUserName:()=>{let e=i(),t=Object.keys(e.users)[0];return t===void 0?null:t},issueToken:(e,t)=>{let n=i();if(n.users[e]===void 0)throw new R;let r=`${T}${Y(24)}`,o={id:Y(4),username:e,tokenHash:J(r),createdAt:X(),...t!==void 0&&t!==``?{note:t}:{}};return n.tokens.push(o),a(n),{id:o.id,token:r,createdAt:o.createdAt,...o.note===void 0?{}:{note:o.note}}},listTokens:()=>i().tokens.map(e=>({id:e.id,createdAt:e.createdAt,revoked:e.revokedAt!==void 0,...e.note===void 0?{}:{note:e.note}})),revokeToken:e=>{let t=i(),n=t.tokens.find(t=>t.id===e);return n===void 0||n.revokedAt!==void 0?!1:(n.revokedAt=X(),a(t),!0)},verifyToken:e=>{let t=i(),n=J(e),r=t.tokens.find(e=>e.tokenHash===n&&e.revokedAt===void 0);if(r===void 0)throw new I;return r.username}}}function pe(e,t,n){let r=w.safeParse(t);if(!r.success)throw new N(r.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `));let i=r.data;if(e.allowPublish!==null&&!e.allowPublish.test(i.name))throw new F(i.name);let a=Object.keys(i.versions);if(a.length!==1)throw new N(`仅支持单版本发布,收到 ${a.length} 个`);let o=Object.keys(i._attachments);if(o.length!==1)throw new N(`仅支持单附件发布,收到 ${o.length} 个`);let s=a[0];if(s===void 0)throw new N(`versions 键缺失`);let c=i.versions[s];if(c===void 0)throw new N(`versions[${s}] manifest 缺失`);let u=o[0];if(u===void 0)throw new N(`_attachments 键缺失`);let d=i._attachments[u];if(d===void 0)throw new N(`_attachments[${u}] 附件缺失`);let f;try{f=new Uint8Array(Buffer.from(d.data,`base64`))}catch{throw new N(`附件 base64 解码失败`)}if(f.length!==d.length)throw new N(`附件长度不符(声明 ${d.length},实测 ${f.length})`);let p=q(f);if(c.dist.shasum!==void 0&&c.dist.shasum!==p)throw new P(i.name,s,c.dist.shasum,p);let m=e.readPackument(i.name)??{_id:i.name,_rev:`0-0`,name:i.name,"dist-tags":{},versions:{},time:{}};if(m.versions[s]!==void 0)throw new j(i.name,s);K(l(z(e.dataRoot,i.name),`tarballs`)),G(V(e.dataRoot,i.name,s),f);let h={...c,dist:{...c.dist,shasum:p}};delete h.dist.tarball,m.time??={};let g=X();m.versions[s]=h;for(let[e,t]of Object.entries(i[`dist-tags`]))m[`dist-tags`][e]=t;return m.time[s]=g,m.time.created??=g,m.time.modified=g,m.maintainers??=i.maintainers??[{name:n}],m.description=i.description??m.description,i.readme!==void 0&&(m.readme=i.readme),m._rev=$(m._rev),e.writePackument(m),{rev:m._rev??`0-0`,version:s}}function me(e,n,r,i){if(i.versions[r]===void 0)throw new A(n,r);let a=V(e.dataRoot,n,r);t(a)&&s(a),delete i.versions[r],i.time!==void 0&&delete i.time[r];for(let[e,t]of Object.entries(i[`dist-tags`]))t===r&&delete i[`dist-tags`][e];let c=Object.keys(i.versions);if(c.length===0){let t=$(i._rev);return o(z(e.dataRoot,n),{recursive:!0,force:!0}),{rev:t}}if(i[`dist-tags`].latest===void 0){let e=c[0];if(e!==void 0){let t=c.reduce((e,t)=>Q(t,e)>0?t:e,e);i[`dist-tags`].latest=t}}return i.time??={},i.time.modified=X(),i._rev=$(i._rev),e.writePackument(i),{rev:i._rev??`0-0`}}function he(e,t,n){let r=$(n._rev);return o(z(e.dataRoot,t),{recursive:!0,force:!0}),{rev:r}}function ge(e){let n=l(e.dataRoot,`store`),a=e.allowPublish??null,o=n=>{let i=B(e.dataRoot,n);if(!t(i))return null;let a=S.safeParse(JSON.parse(r(i,`utf8`)));return a.success?a.data:null},s=(e,t)=>{let n=o(e);if(n===null)throw new k(e);if(n._rev!==t)throw new M(e,t,n._rev??`0-0`);return n},c=t=>{K(z(e.dataRoot,t.name)),W(B(e.dataRoot,t.name),t)},u={dataRoot:e.dataRoot,allowPublish:a,readPackument:o,writePackument:c},d=()=>{K(n),K(l(e.dataRoot,`run`))},f=e=>o(e),p=(e,t)=>{let n=o(e);if(n===null)return null;let r=n[`dist-tags`][t]??t;return n.versions[r]??null},m=(n,i)=>{let a=V(e.dataRoot,n,i);return t(a)?new Uint8Array(r(a)):null},h=e=>{let t=o(e);return t===null?null:t[`dist-tags`]},g=(e,t)=>pe(u,e,t),_=(e,t,n)=>me(u,e,t,s(e,n)),v=(e,t)=>he(u,e,s(e,t)),y=(e,t)=>{let n=o(e);if(n===null)throw new k(e);for(let r of Object.values(t))if(n.versions[r]===void 0)throw new A(e,r);n[`dist-tags`]={...t},n.time??={},n.time.modified=X(),n._rev=$(n._rev),c(n)},b=(e,t,n)=>{let r=o(e);if(r===null)throw new k(e);if(r.versions[n]===void 0)throw new A(e,n);r[`dist-tags`][t]=n,r.time??={},r.time.modified=X(),r._rev=$(r._rev),c(r)},x=(e,t)=>{let n=o(e);return n===null||n[`dist-tags`][t]===void 0?!1:(delete n[`dist-tags`][t],n.time??={},n.time.modified=X(),n._rev=$(n._rev),c(n),!0)},C=()=>{if(!t(n))return[];let e=[];for(let t of i(n,{withFileTypes:!0})){if(!t.isDirectory())continue;let n=t.name.replace(/%2f/g,`/`),r=o(n);r!==null&&e.push({name:n,versionCount:Object.keys(r.versions).length,...r[`dist-tags`].latest===void 0?{}:{latest:r[`dist-tags`].latest},...r.time?.modified===void 0?{}:{modified:r.time.modified}})}return e.sort((e,t)=>e.name<t.name?-1:+(e.name>t.name))};return{ensureLayout:d,readPackument:f,readManifest:p,readTarball:m,readDistTags:h,publish:g,unpublishVersion:_,unpublishPackage:v,replaceDistTags:y,addDistTag:b,removeDistTag:x,listPackages:C,countPackages:()=>C().length}}export{oe as AUTH_STORE_VERSION,O as AuthStoreSchema,g as COUCHDB_USER_ID_PREFIX,ne as CouchUserPayloadSchema,h as DIST_TAG_PATTERN,y as DistMetaSchema,x as DistTagMapSchema,R as InvalidCredentialsError,re as NpmErrorResponseSchema,p as PACKAGE_NAME_PATTERN,ae as PackageDetailSchema,_ as PackageIdentifierSchema,k as PackageNotFoundError,ie as PackageSummarySchema,A as PackageVersionNotFoundError,S as PackumentSchema,E as PasswordRecordSchema,le as ProtocolPayloadError,C as PublishAttachmentSchema,N as PublishPayloadError,w as PublishPayloadSchema,ee as PublishResponseSchema,M as RevisionMismatchError,m as SEMVER_PATTERN,F as ScopeNotAllowedError,v as SemverSchema,P as ShasumMismatchError,T as TOKEN_PREFIX,se as TokenCreateInfoSchema,ce as TokenInfoSchema,I as TokenInvalidError,D as TokenRecordSchema,L as UserAlreadyExistsError,j as VersionExistsError,b as VersionManifestSchema,te as WhoamiResponseSchema,G as atomicWriteBytes,W as atomicWriteJson,Q as compareSemver,fe as createAuthStore,ge as createLocalNpmRegistry,H as escapePackageName,$ as nextRevision,X as nowIso,z as packageDirPath,B as packumentPath,q as sha1Hex,J as sha256Hex,U as tarballFileName,V as tarballPath,ue as unescapePackageName};
1
+ import"./rolldown-runtime-BqT_7tdF.js";import*as e from"zod";import{existsSync as t,mkdirSync as n,readFileSync as r,readdirSync as i,renameSync as a,rmSync as o,unlinkSync as s,writeFileSync as c}from"node:fs";import{join as l}from"node:path";import{DomainError as u}from"@longzai-intelligence-error/core";import{createHash as d,randomBytes as f}from"node:crypto";const p=/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/,m=/^\d+\.\d+\.\d+(-[0-9A-Za-z-.+]+)?(\+[0-9A-Za-z-.]+)?$/,h=/^[a-z][a-z0-9-._]*$/i,g=`org.couchdb.user:`,_=e.string().regex(p),v=e.string().regex(m),y=e.object({shasum:e.string().regex(/^[0-9a-f]{40}$/).optional(),integrity:e.string().optional(),tarball:e.url().optional(),fileCount:e.int().nonnegative().optional(),unpackedSize:e.int().nonnegative().optional()}),b=e.looseObject({name:_,version:v,dist:y}),x=e.record(e.string().regex(h),v),S=e.looseObject({_id:_,_rev:e.string().regex(/^\d+-[0-9a-f]+$/).optional(),name:_,description:e.string().optional(),"dist-tags":x,versions:e.record(v,b),time:e.record(e.string(),e.string()).optional(),maintainers:e.array(e.looseObject({name:e.string(),email:e.string().optional()})).optional(),readme:e.string().optional()}),C=e.object({content_type:e.string(),data:e.string(),length:e.int().nonnegative()}),w=e.looseObject({_id:_.optional(),name:_,description:e.string().optional(),"dist-tags":x,versions:e.record(v,b).refine(e=>Object.keys(e).length>=1,{error:`publish 载荷 versions 至少含一个新版本`}),access:e.enum([`public`,`restricted`]).nullish(),readme:e.string().optional(),_attachments:e.record(e.string(),C).refine(e=>Object.keys(e).length>=1,{error:`publish 载荷 _attachments 至少含一个 tarball`}),maintainers:e.array(e.looseObject({name:e.string(),email:e.string().optional()})).optional()}).refine(e=>e._id===void 0||e._id===e.name,{error:`publish 载荷 _id 与 name 不一致`,path:[`_id`]}),ee=e.object({ok:e.literal(!0),rev:e.string(),id:e.string().optional()}),te=e.object({username:e.string().min(1)}),ne=e.looseObject({_id:e.string().optional(),name:e.string().min(1).regex(/^[a-z][a-z0-9-]*$/i,{error:`用户名仅允许字母数字与中划线`}),password:e.string().min(1),email:e.email().optional(),type:e.literal(`user`).optional(),roles:e.array(e.string()).optional(),date:e.string().optional()}),re=e.object({error:e.string()}),ie=e.object({name:_,versionCount:e.int().positive(),latest:v.optional(),modified:e.iso.datetime().optional()}),ae=e.object({name:_,versionCount:e.int().positive(),latest:v.optional(),modified:e.iso.datetime().optional(),distTags:x,versions:e.array(v)}),T=`lzi_local_`,oe=1,E=e.object({salt:e.string().regex(/^[0-9a-f]{32}$/),hash:e.string().regex(/^[0-9a-f]{64}$/)}),D=e.object({id:e.string().regex(/^[0-9a-f]{8}$/),username:e.string().min(1),tokenHash:e.string().regex(/^[0-9a-f]{64}$/),note:e.string().optional(),createdAt:e.iso.datetime(),revokedAt:e.iso.datetime().optional()}),O=e.object({version:e.literal(1),users:e.record(e.string(),e.object({password:E})),tokens:e.array(D)}),se=e.object({id:e.string().regex(/^[0-9a-f]{8}$/),token:e.string(),note:e.string().optional(),createdAt:e.iso.datetime()}),ce=e.object({id:e.string().regex(/^[0-9a-f]{8}$/),note:e.string().optional(),createdAt:e.iso.datetime(),revoked:e.boolean()});var k=class extends u{constructor(e){super(`包不存在: ${e}`,`NPM_REGISTRY_PACKAGE_NOT_FOUND`,{name:e}),this.name=`PackageNotFoundError`}},A=class extends u{constructor(e,t){super(`包版本不存在: ${e}@${t}`,`NPM_REGISTRY_PACKAGE_VERSION_NOT_FOUND`,{name:e,version:t}),this.name=`PackageVersionNotFoundError`}},j=class extends u{constructor(e,t){super(`版本已存在,npm 版本不可变: ${e}@${t}`,`NPM_REGISTRY_VERSION_EXISTS`,{name:e,version:t}),this.name=`VersionExistsError`}},M=class extends u{constructor(e,t,n){super(`修订号不匹配(携带 ${t},当前 ${n}),请重新获取 packument`,`NPM_REGISTRY_REVISION_MISMATCH`,{name:e,expected:t,actual:n}),this.name=`RevisionMismatchError`}},N=class extends u{constructor(e){super(`publish 载荷不合法: ${e}`,`NPM_REGISTRY_PUBLISH_PAYLOAD_INVALID`,{reason:e}),this.name=`PublishPayloadError`}},le=class extends u{constructor(e,t){super(`${e} 载荷不合法: ${t}`,`NPM_REGISTRY_PROTOCOL_PAYLOAD_INVALID`,{kind:e,reason:t}),this.name=`ProtocolPayloadError`}},P=class extends u{constructor(e,t,n,r){super(`tarball shasum 不符(声明 ${n},实测 ${r}): ${e}@${t}`,`NPM_REGISTRY_SHASUM_MISMATCH`,{name:e,version:t,declared:n,actual:r}),this.name=`ShasumMismatchError`}},F=class extends u{constructor(e){super(`包名不在允许发布的 scope 内: ${e}`,`NPM_REGISTRY_SCOPE_NOT_ALLOWED`,{name:e}),this.name=`ScopeNotAllowedError`}},I=class extends u{constructor(){super(`token 无效或已吊销`,`NPM_REGISTRY_TOKEN_INVALID`,{}),this.name=`TokenInvalidError`}},L=class extends u{constructor(e){super(`本地用户已存在: ${e}`,`NPM_REGISTRY_USER_ALREADY_EXISTS`,{name:e}),this.name=`UserAlreadyExistsError`}},R=class extends u{constructor(){super(`用户名或口令错误`,`NPM_REGISTRY_INVALID_CREDENTIALS`,{}),this.name=`InvalidCredentialsError`}};function z(e,t){return l(e,`store`,H(t))}function B(e,t){return l(z(e,t),`index.json`)}function V(e,t,n){return l(z(e,t),`tarballs`,U(t,n))}function H(e){return e.replace(/\//g,`%2f`)}function ue(e){return e.replace(/%2f/g,`/`)}function U(e,t){return`${e.split(`/`).at(-1)??e}-${t}.tgz`}function W(e,t){let n=`${e}.${process.pid}.tmp`;c(n,`${JSON.stringify(t,null,2)}\n`,`utf8`),a(n,e)}function G(e,t){let n=`${e}.${process.pid}.tmp`;c(n,t),a(n,e)}function K(e){t(e)||n(e,{recursive:!0})}function q(e){return d(`sha1`).update(e).digest(`hex`)}function J(e){return d(`sha256`).update(e).digest(`hex`)}function Y(e){return f(e).toString(`hex`)}function X(){return(/* @__PURE__ */ new Date()).toISOString()}function Z(e){let[t=``]=e.split(`+`),[n=``,r]=t.split(`-`),[i=0,a=0,o=0]=n.split(`.`).map(e=>Number.parseInt(e,10));return{core:[i,a,o],pre:r===void 0?null:r.split(`.`)}}function Q(e,t){let n=Z(e),r=Z(t);for(let e=0;e<3;e++){let t=n.core[e]??0,i=r.core[e]??0;if(t!==i)return t-i}return n.pre===null&&r.pre===null?0:n.pre===null?1:r.pre===null?-1:de(n.pre,r.pre)}function de(e,t){let n=Math.min(e.length,t.length);for(let r=0;r<n;r++){let n=e[r]??``,i=t[r]??``,a=/^\d+$/.test(n),o=/^\d+$/.test(i);if(a&&o){let e=Number.parseInt(n,10)-Number.parseInt(i,10);if(e!==0)return e}else{if(a)return-1;if(o)return 1;if(n!==i)return n<i?-1:1}}return e.length-t.length}function $(e){return`${Number.parseInt(e?.split(`-`)[0]??`0`,10)+1}-${Y(4)}`}function fe(e){let n=l(e.dataRoot,`auth.json`),i=()=>{if(!t(n))return{version:1,users:{},tokens:[]};let e=O.safeParse(JSON.parse(r(n,`utf8`)));if(!e.success)throw Error(`[core] auth.json 不合法:${e.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `)}`);return e.data},a=e=>{W(n,e)};return{createUser:(e,t)=>{let n=i(),r=Object.keys(n.users)[0];if(r!==void 0)throw new L(r);let o=Y(16);n.users[e]={password:{salt:o,hash:J(o+t)}},a(n)},verifyPassword:(e,t)=>{let n=i().users[e];if(n===void 0||J(n.password.salt+t)!==n.password.hash)throw new R},getUserName:()=>{let e=i(),t=Object.keys(e.users)[0];return t===void 0?null:t},issueToken:(e,t)=>{let n=i();if(n.users[e]===void 0)throw new R;let r=`${T}${Y(24)}`,o={id:Y(4),username:e,tokenHash:J(r),createdAt:X(),...t!==void 0&&t!==``?{note:t}:{}};return n.tokens.push(o),a(n),{id:o.id,token:r,createdAt:o.createdAt,...o.note===void 0?{}:{note:o.note}}},listTokens:()=>i().tokens.map(e=>({id:e.id,createdAt:e.createdAt,revoked:e.revokedAt!==void 0,...e.note===void 0?{}:{note:e.note}})),revokeToken:e=>{let t=i(),n=t.tokens.find(t=>t.id===e);return n===void 0||n.revokedAt!==void 0?!1:(n.revokedAt=X(),a(t),!0)},verifyToken:e=>{let t=i(),n=J(e),r=t.tokens.find(e=>e.tokenHash===n&&e.revokedAt===void 0);if(r===void 0)throw new I;return r.username}}}function pe(e,t,n){let r=w.safeParse(t);if(!r.success)throw new N(r.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `));let i=r.data;if(e.allowPublish!==null&&!e.allowPublish.test(i.name))throw new F(i.name);let a=Object.keys(i.versions);if(a.length!==1)throw new N(`仅支持单版本发布,收到 ${a.length} 个`);let o=Object.keys(i._attachments);if(o.length!==1)throw new N(`仅支持单附件发布,收到 ${o.length} 个`);let s=a[0];if(s===void 0)throw new N(`versions 键缺失`);let c=i.versions[s];if(c===void 0)throw new N(`versions[${s}] manifest 缺失`);let u=o[0];if(u===void 0)throw new N(`_attachments 键缺失`);let d=i._attachments[u];if(d===void 0)throw new N(`_attachments[${u}] 附件缺失`);let f;try{f=new Uint8Array(Buffer.from(d.data,`base64`))}catch{throw new N(`附件 base64 解码失败`)}if(f.length!==d.length)throw new N(`附件长度不符(声明 ${d.length},实测 ${f.length})`);let p=q(f);if(c.dist.shasum!==void 0&&c.dist.shasum!==p)throw new P(i.name,s,c.dist.shasum,p);let m=e.readPackument(i.name)??{_id:i.name,_rev:`0-0`,name:i.name,"dist-tags":{},versions:{},time:{}};if(m.versions[s]!==void 0)throw new j(i.name,s);K(l(z(e.dataRoot,i.name),`tarballs`)),G(V(e.dataRoot,i.name,s),f);let h={...c,dist:{...c.dist,shasum:p}};delete h.dist.tarball,m.time??={};let g=X();m.versions[s]=h;for(let[e,t]of Object.entries(i[`dist-tags`]))m[`dist-tags`][e]=t;return m.time[s]=g,m.time.created??=g,m.time.modified=g,m.maintainers??=i.maintainers??[{name:n}],m.description=i.description??m.description,i.readme!==void 0&&(m.readme=i.readme),m._rev=$(m._rev),e.writePackument(m),{rev:m._rev??`0-0`,version:s}}function me(e,n,r,i){if(i.versions[r]===void 0)throw new A(n,r);let a=V(e.dataRoot,n,r);t(a)&&s(a),delete i.versions[r],i.time!==void 0&&delete i.time[r];for(let[e,t]of Object.entries(i[`dist-tags`]))t===r&&delete i[`dist-tags`][e];let c=Object.keys(i.versions);if(c.length===0){let t=$(i._rev);return o(z(e.dataRoot,n),{recursive:!0,force:!0}),{rev:t}}if(i[`dist-tags`].latest===void 0){let e=c[0];if(e!==void 0){let t=c.reduce((e,t)=>Q(t,e)>0?t:e,e);i[`dist-tags`].latest=t}}return i.time??={},i.time.modified=X(),i._rev=$(i._rev),e.writePackument(i),{rev:i._rev??`0-0`}}function he(e,t,n){let r=$(n._rev);return o(z(e.dataRoot,t),{recursive:!0,force:!0}),{rev:r}}function ge(e){let n=l(e.dataRoot,`store`),a=e.allowPublish??null,o=n=>{let i=B(e.dataRoot,n);if(!t(i))return null;let a=S.safeParse(JSON.parse(r(i,`utf8`)));return a.success?a.data:null},s=(e,t)=>{let n=o(e);if(n===null)throw new k(e);if(n._rev!==t)throw new M(e,t,n._rev??`0-0`);return n},c=t=>{K(z(e.dataRoot,t.name)),W(B(e.dataRoot,t.name),t)},u={dataRoot:e.dataRoot,allowPublish:a,readPackument:o,writePackument:c},d=()=>{K(n),K(l(e.dataRoot,`run`))},f=e=>o(e),p=(e,t)=>{let n=o(e);if(n===null)return null;let r=n[`dist-tags`][t]??t;return n.versions[r]??null},m=(n,i)=>{let a=V(e.dataRoot,n,i);return t(a)?new Uint8Array(r(a)):null},h=e=>{let t=o(e);return t===null?null:t[`dist-tags`]},g=(e,t)=>pe(u,e,t),_=(e,t,n)=>me(u,e,t,s(e,n)),v=(e,t)=>he(u,e,s(e,t)),y=(e,t)=>{let n=o(e);if(n===null)throw new k(e);for(let r of Object.values(t))if(n.versions[r]===void 0)throw new A(e,r);n[`dist-tags`]={...t},n.time??={},n.time.modified=X(),n._rev=$(n._rev),c(n)},b=(e,t,n)=>{let r=o(e);if(r===null)throw new k(e);if(r.versions[n]===void 0)throw new A(e,n);r[`dist-tags`][t]=n,r.time??={},r.time.modified=X(),r._rev=$(r._rev),c(r)},x=(e,t)=>{let n=o(e);return n===null||n[`dist-tags`][t]===void 0?!1:(delete n[`dist-tags`][t],n.time??={},n.time.modified=X(),n._rev=$(n._rev),c(n),!0)},C=()=>{if(!t(n))return[];let e=[];for(let t of i(n,{withFileTypes:!0})){if(!t.isDirectory())continue;let n=t.name.replace(/%2f/g,`/`),r=o(n);r!==null&&e.push({name:n,versionCount:Object.keys(r.versions).length,...r[`dist-tags`].latest===void 0?{}:{latest:r[`dist-tags`].latest},...r.time?.modified===void 0?{}:{modified:r.time.modified}})}return e.sort((e,t)=>e.name<t.name?-1:+(e.name>t.name))};return{ensureLayout:d,readPackument:f,readManifest:p,readTarball:m,readDistTags:h,publish:g,unpublishVersion:_,unpublishPackage:v,replaceDistTags:y,addDistTag:b,removeDistTag:x,listPackages:C,countPackages:()=>C().length}}export{oe as AUTH_STORE_VERSION,O as AuthStoreSchema,g as COUCHDB_USER_ID_PREFIX,ne as CouchUserPayloadSchema,h as DIST_TAG_PATTERN,y as DistMetaSchema,x as DistTagMapSchema,R as InvalidCredentialsError,re as NpmErrorResponseSchema,p as PACKAGE_NAME_PATTERN,ae as PackageDetailSchema,_ as PackageIdentifierSchema,k as PackageNotFoundError,ie as PackageSummarySchema,A as PackageVersionNotFoundError,S as PackumentSchema,E as PasswordRecordSchema,le as ProtocolPayloadError,C as PublishAttachmentSchema,N as PublishPayloadError,w as PublishPayloadSchema,ee as PublishResponseSchema,M as RevisionMismatchError,m as SEMVER_PATTERN,F as ScopeNotAllowedError,v as SemverSchema,P as ShasumMismatchError,T as TOKEN_PREFIX,se as TokenCreateInfoSchema,ce as TokenInfoSchema,I as TokenInvalidError,D as TokenRecordSchema,L as UserAlreadyExistsError,j as VersionExistsError,b as VersionManifestSchema,te as WhoamiResponseSchema,G as atomicWriteBytes,W as atomicWriteJson,Q as compareSemver,fe as createAuthStore,ge as createLocalNpmRegistry,H as escapePackageName,$ as nextRevision,X as nowIso,z as packageDirPath,B as packumentPath,q as sha1Hex,J as sha256Hex,U as tarballFileName,V as tarballPath,ue as unescapePackageName};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@longzai-intelligence-npm-registry/core",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "Longzai Intelligence 本地 npm registry 存储引擎",
5
5
  "keywords": [
6
6
  "core",