@coralai/sps-plugin-api 0.14.0 → 0.16.0
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 +30 -0
- package/dist/index.js +17 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -382,7 +382,37 @@ export interface SpsWorkspace {
|
|
|
382
382
|
discover(): Promise<SpsWorkspaceProject[]>;
|
|
383
383
|
/** 某产品的用户资产范围。没有声明时回落窄兜底,并把 `usedDefault` 置真。 */
|
|
384
384
|
assetScope(product: string): SpsAssetScope;
|
|
385
|
+
/**
|
|
386
|
+
* 构建方声明的产物目录(`<repoDir>/.sps/build.json` 的 `outDir`)。
|
|
387
|
+
*
|
|
388
|
+
* 🔴 **三态,别塌成两态**:
|
|
389
|
+
* ```
|
|
390
|
+
* undefined 没声明(文件不在 / 没这个字段 / 坏 JSON)
|
|
391
|
+
* null 声明了「这个项目没有产物目录」
|
|
392
|
+
* string 声明的相对目录
|
|
393
|
+
* ```
|
|
394
|
+
* 把 `null` 和 `undefined` 合成一个,就分不出「构建方说没有」和「构建方没说」——
|
|
395
|
+
* 而前者该照做,后者只能去猜。
|
|
396
|
+
*
|
|
397
|
+
* 🔴 **别自己读 `.sps/build.json`。** 它取代的正是"三方各自猜"那个形状:
|
|
398
|
+
* sps 的 play.ts、插件的 publish.mjs 曾各写一份
|
|
399
|
+
* `exists(dist/index.html) ? dist : repoDir` 的三元(逐字相同)。
|
|
400
|
+
* 现有项目全是 vite(默认 `dist`)所以一直没露;webpack 默认 `build`、Next 是 `.next`
|
|
401
|
+
* ⇒ 只要有一个项目的打包器输出不是 dist,猜的那份当场就错,而表现是
|
|
402
|
+
* "预览到未构建的源码",**零报错**。
|
|
403
|
+
*
|
|
404
|
+
* ⚠️ 它在 `sps.workspace` 而不是别处,是因为这是**读工作区里的一个约定文件** ——
|
|
405
|
+
* 和 `assetScope` 同类:约定由宿主定,插件问宿主要答案,而不是自己拼路径。
|
|
406
|
+
*/
|
|
407
|
+
declaredOutDir(repoDir: string): string | null | undefined;
|
|
408
|
+
}
|
|
409
|
+
export type SyncRejectCode = 'EMPTY_SEGMENT' | 'ABSOLUTE' | 'PARENT_SEGMENT' | 'DOT_SEGMENT';
|
|
410
|
+
export interface SyncRejection {
|
|
411
|
+
code: SyncRejectCode;
|
|
412
|
+
rel: string;
|
|
385
413
|
}
|
|
414
|
+
/** 相对路径的形状判据。返回 `null` = 形状没问题(**不代表可同步**,还要过软链围栏)。 */
|
|
415
|
+
export declare function syncableShape(rel: string): SyncRejection | null;
|
|
386
416
|
/**
|
|
387
417
|
* `p` 是否在 `root` 之内(含 root 自身)。
|
|
388
418
|
*
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,23 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { realpath } from 'node:fs/promises';
|
|
15
15
|
import { dirname, join, resolve as nodeResolve, sep } from 'node:path';
|
|
16
|
+
/** 相对路径的形状判据。返回 `null` = 形状没问题(**不代表可同步**,还要过软链围栏)。 */
|
|
17
|
+
export function syncableShape(rel) {
|
|
18
|
+
if (!rel)
|
|
19
|
+
return { code: 'EMPTY_SEGMENT', rel };
|
|
20
|
+
if (rel.startsWith('/'))
|
|
21
|
+
return { code: 'ABSOLUTE', rel };
|
|
22
|
+
for (const seg of rel.split('/')) {
|
|
23
|
+
if (!seg)
|
|
24
|
+
return { code: 'EMPTY_SEGMENT', rel };
|
|
25
|
+
if (seg === '..')
|
|
26
|
+
return { code: 'PARENT_SEGMENT', rel };
|
|
27
|
+
// ← 承重的是这条:`.claude/`、`.git/`、`.sps/` 全靠它
|
|
28
|
+
if (seg.startsWith('.'))
|
|
29
|
+
return { code: 'DOT_SEGMENT', rel };
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
16
33
|
// ── 路径围栏:所有插件共用的安全下限 ──────────────────────────────────────
|
|
17
34
|
//
|
|
18
35
|
// 🔴 **安全判据不能有第二份。** 本仓已经为这个形状付过三次代价:
|