@zhuk/spego 0.1.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/LICENSE +190 -0
- package/README.md +49 -0
- package/dist/artifacts/engine.d.ts +45 -0
- package/dist/artifacts/engine.js +209 -0
- package/dist/artifacts/engine.js.map +1 -0
- package/dist/artifacts/schemas.d.ts +4 -0
- package/dist/artifacts/schemas.js +79 -0
- package/dist/artifacts/schemas.js.map +1 -0
- package/dist/artifacts/slug.d.ts +9 -0
- package/dist/artifacts/slug.js +24 -0
- package/dist/artifacts/slug.js.map +1 -0
- package/dist/artifacts/storage.d.ts +18 -0
- package/dist/artifacts/storage.js +94 -0
- package/dist/artifacts/storage.js.map +1 -0
- package/dist/artifacts/types.d.ts +52 -0
- package/dist/artifacts/types.js +42 -0
- package/dist/artifacts/types.js.map +1 -0
- package/dist/artifacts/validation.d.ts +46 -0
- package/dist/artifacts/validation.js +72 -0
- package/dist/artifacts/validation.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +461 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/registry.d.ts +18 -0
- package/dist/commands/registry.js +127 -0
- package/dist/commands/registry.js.map +1 -0
- package/dist/delivery/index.d.ts +2 -0
- package/dist/delivery/index.js +2 -0
- package/dist/delivery/index.js.map +1 -0
- package/dist/delivery/openspec-adapter.d.ts +2 -0
- package/dist/delivery/openspec-adapter.js +86 -0
- package/dist/delivery/openspec-adapter.js.map +1 -0
- package/dist/delivery/openspec-discover.d.ts +8 -0
- package/dist/delivery/openspec-discover.js +80 -0
- package/dist/delivery/openspec-discover.js.map +1 -0
- package/dist/delivery/openspec-parse.d.ts +9 -0
- package/dist/delivery/openspec-parse.js +63 -0
- package/dist/delivery/openspec-parse.js.map +1 -0
- package/dist/delivery/resolve.d.ts +3 -0
- package/dist/delivery/resolve.js +14 -0
- package/dist/delivery/resolve.js.map +1 -0
- package/dist/delivery/types.d.ts +27 -0
- package/dist/delivery/types.js +2 -0
- package/dist/delivery/types.js.map +1 -0
- package/dist/errors.d.ts +18 -0
- package/dist/errors.js +14 -0
- package/dist/errors.js.map +1 -0
- package/dist/export/view.d.ts +54 -0
- package/dist/export/view.js +74 -0
- package/dist/export/view.js.map +1 -0
- package/dist/generator/claude.d.ts +5 -0
- package/dist/generator/claude.js +85 -0
- package/dist/generator/claude.js.map +1 -0
- package/dist/generator/index.d.ts +5 -0
- package/dist/generator/index.js +23 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/generator/markers.d.ts +3 -0
- package/dist/generator/markers.js +8 -0
- package/dist/generator/markers.js.map +1 -0
- package/dist/generator/types.d.ts +15 -0
- package/dist/generator/types.js +2 -0
- package/dist/generator/types.js.map +1 -0
- package/dist/generator/write.d.ts +2 -0
- package/dist/generator/write.js +28 -0
- package/dist/generator/write.js.map +1 -0
- package/dist/index/db.d.ts +17 -0
- package/dist/index/db.js +95 -0
- package/dist/index/db.js.map +1 -0
- package/dist/index/indexer.d.ts +42 -0
- package/dist/index/indexer.js +219 -0
- package/dist/index/indexer.js.map +1 -0
- package/dist/index/revisions.d.ts +13 -0
- package/dist/index/revisions.js +31 -0
- package/dist/index/revisions.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/workspace/config.d.ts +47 -0
- package/dist/workspace/config.js +64 -0
- package/dist/workspace/config.js.map +1 -0
- package/dist/workspace/init.d.ts +37 -0
- package/dist/workspace/init.js +114 -0
- package/dist/workspace/init.js.map +1 -0
- package/dist/workspace/paths.d.ts +30 -0
- package/dist/workspace/paths.js +34 -0
- package/dist/workspace/paths.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ArtifactFrontmatter } from './types.js';
|
|
2
|
+
/** Render frontmatter + body to a single markdown string. */
|
|
3
|
+
export declare function renderArtifactFile(frontmatter: ArtifactFrontmatter, body: string): string;
|
|
4
|
+
/** Parse a markdown file's text into frontmatter + body. */
|
|
5
|
+
export declare function parseArtifactFile(text: string, sourcePath: string): {
|
|
6
|
+
frontmatter: ArtifactFrontmatter;
|
|
7
|
+
body: string;
|
|
8
|
+
};
|
|
9
|
+
/** Read and parse a markdown artifact file from disk. */
|
|
10
|
+
export declare function readArtifactFile(absPath: string): Promise<{
|
|
11
|
+
frontmatter: ArtifactFrontmatter;
|
|
12
|
+
body: string;
|
|
13
|
+
}>;
|
|
14
|
+
/**
|
|
15
|
+
* Atomically write a markdown file: write to a temp sibling, fsync, rename.
|
|
16
|
+
* Rename on the same filesystem is atomic on POSIX and Windows (ReplaceFile).
|
|
17
|
+
*/
|
|
18
|
+
export declare function atomicWriteFile(absPath: string, contents: string): Promise<void>;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import YAML from 'yaml';
|
|
4
|
+
import { artifactFrontmatterSchema } from './types.js';
|
|
5
|
+
import { SpegoError } from '../errors.js';
|
|
6
|
+
const FENCE_OPEN = /^---\r?\n/;
|
|
7
|
+
const FENCE_CLOSE = /\r?\n---\r?\n?/;
|
|
8
|
+
/** Render frontmatter + body to a single markdown string. */
|
|
9
|
+
export function renderArtifactFile(frontmatter, body) {
|
|
10
|
+
// Always quote string scalars so date-like values round-trip as strings
|
|
11
|
+
// (YAML 1.1 implicit Date typing has bitten us before).
|
|
12
|
+
const yaml = YAML.stringify(frontmatter, {
|
|
13
|
+
lineWidth: 0,
|
|
14
|
+
defaultStringType: 'QUOTE_DOUBLE',
|
|
15
|
+
defaultKeyType: 'PLAIN',
|
|
16
|
+
}).trimEnd();
|
|
17
|
+
const trimmedBody = body.endsWith('\n') ? body : `${body}\n`;
|
|
18
|
+
return `---\n${yaml}\n---\n\n${trimmedBody}`;
|
|
19
|
+
}
|
|
20
|
+
/** Parse a markdown file's text into frontmatter + body. */
|
|
21
|
+
export function parseArtifactFile(text, sourcePath) {
|
|
22
|
+
const openMatch = text.match(FENCE_OPEN);
|
|
23
|
+
if (!openMatch) {
|
|
24
|
+
throw new SpegoError('VALIDATION_FAILED', `Missing frontmatter block in ${sourcePath}`, { path: sourcePath });
|
|
25
|
+
}
|
|
26
|
+
const afterOpen = text.slice(openMatch[0].length);
|
|
27
|
+
const closeMatch = afterOpen.match(FENCE_CLOSE);
|
|
28
|
+
if (!closeMatch || closeMatch.index === undefined) {
|
|
29
|
+
throw new SpegoError('VALIDATION_FAILED', `Unterminated frontmatter block in ${sourcePath}`, { path: sourcePath });
|
|
30
|
+
}
|
|
31
|
+
const yamlText = afterOpen.slice(0, closeMatch.index);
|
|
32
|
+
const body = afterOpen.slice(closeMatch.index + closeMatch[0].length).replace(/^\n+/, '');
|
|
33
|
+
let data;
|
|
34
|
+
try {
|
|
35
|
+
// `yaml` library defaults to YAML 1.2 / JSON-compatible scalars: ISO date
|
|
36
|
+
// strings stay strings, which is what our Zod schema requires.
|
|
37
|
+
data = YAML.parse(yamlText);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
throw new SpegoError('VALIDATION_FAILED', `Invalid YAML frontmatter in ${sourcePath}`, { path: sourcePath, cause: err.message });
|
|
41
|
+
}
|
|
42
|
+
const result = artifactFrontmatterSchema.safeParse(data);
|
|
43
|
+
if (!result.success) {
|
|
44
|
+
throw new SpegoError('VALIDATION_FAILED', `Invalid frontmatter in ${sourcePath}`, {
|
|
45
|
+
path: sourcePath,
|
|
46
|
+
issues: result.error.issues,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return { frontmatter: result.data, body };
|
|
50
|
+
}
|
|
51
|
+
/** Read and parse a markdown artifact file from disk. */
|
|
52
|
+
export async function readArtifactFile(absPath) {
|
|
53
|
+
let text;
|
|
54
|
+
try {
|
|
55
|
+
text = await fs.readFile(absPath, 'utf8');
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
if (err.code === 'ENOENT') {
|
|
59
|
+
throw new SpegoError('ARTIFACT_NOT_FOUND', `Artifact file not found at ${absPath}`, {
|
|
60
|
+
path: absPath,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
throw err;
|
|
64
|
+
}
|
|
65
|
+
return parseArtifactFile(text, absPath);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Atomically write a markdown file: write to a temp sibling, fsync, rename.
|
|
69
|
+
* Rename on the same filesystem is atomic on POSIX and Windows (ReplaceFile).
|
|
70
|
+
*/
|
|
71
|
+
export async function atomicWriteFile(absPath, contents) {
|
|
72
|
+
await fs.mkdir(path.dirname(absPath), { recursive: true });
|
|
73
|
+
const tmp = `${absPath}.${process.pid}.${Date.now()}.tmp`;
|
|
74
|
+
const handle = await fs.open(tmp, 'w', 0o644);
|
|
75
|
+
try {
|
|
76
|
+
await handle.writeFile(contents, 'utf8');
|
|
77
|
+
await handle.sync();
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
await handle.close();
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
await fs.rename(tmp, absPath);
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
// Clean up temp file if rename failed.
|
|
87
|
+
await fs.unlink(tmp).catch(() => undefined);
|
|
88
|
+
throw new SpegoError('WRITE_FAILED', `Failed to write artifact to ${absPath}`, {
|
|
89
|
+
path: absPath,
|
|
90
|
+
cause: err.message,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/artifacts/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Built-in artifact types from the product spec. Custom types may be added
|
|
4
|
+
* via workspace config (see config schema).
|
|
5
|
+
*/
|
|
6
|
+
export declare const BUILTIN_ARTIFACT_TYPES: readonly ["prd", "okr", "retro", "sprint-plan", "brainstorm", "usecases", "design", "api", "architecture", "decision", "risk", "qa", "ceremony"];
|
|
7
|
+
export type BuiltinArtifactType = (typeof BUILTIN_ARTIFACT_TYPES)[number];
|
|
8
|
+
export type ArtifactType = string;
|
|
9
|
+
/** ISO-8601 datetime string. */
|
|
10
|
+
export declare const isoDateTime: z.ZodEffects<z.ZodString, string, string>;
|
|
11
|
+
/**
|
|
12
|
+
* Frontmatter persisted at the top of every artifact markdown file.
|
|
13
|
+
* Mirrored into SQLite for fast listing/filter; markdown is the source of truth.
|
|
14
|
+
*/
|
|
15
|
+
export declare const artifactFrontmatterSchema: z.ZodObject<{
|
|
16
|
+
id: z.ZodString;
|
|
17
|
+
type: z.ZodString;
|
|
18
|
+
title: z.ZodString;
|
|
19
|
+
slug: z.ZodString;
|
|
20
|
+
revision: z.ZodNumber;
|
|
21
|
+
createdAt: z.ZodEffects<z.ZodString, string, string>;
|
|
22
|
+
updatedAt: z.ZodEffects<z.ZodString, string, string>;
|
|
23
|
+
deletedAt: z.ZodOptional<z.ZodNullable<z.ZodEffects<z.ZodString, string, string>>>;
|
|
24
|
+
meta: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
25
|
+
}, "strict", z.ZodTypeAny, {
|
|
26
|
+
id: string;
|
|
27
|
+
type: string;
|
|
28
|
+
title: string;
|
|
29
|
+
slug: string;
|
|
30
|
+
revision: number;
|
|
31
|
+
createdAt: string;
|
|
32
|
+
updatedAt: string;
|
|
33
|
+
meta: Record<string, unknown>;
|
|
34
|
+
deletedAt?: string | null | undefined;
|
|
35
|
+
}, {
|
|
36
|
+
id: string;
|
|
37
|
+
type: string;
|
|
38
|
+
title: string;
|
|
39
|
+
slug: string;
|
|
40
|
+
revision: number;
|
|
41
|
+
createdAt: string;
|
|
42
|
+
updatedAt: string;
|
|
43
|
+
deletedAt?: string | null | undefined;
|
|
44
|
+
meta?: Record<string, unknown> | undefined;
|
|
45
|
+
}>;
|
|
46
|
+
export type ArtifactFrontmatter = z.infer<typeof artifactFrontmatterSchema>;
|
|
47
|
+
export interface ArtifactRecord {
|
|
48
|
+
frontmatter: ArtifactFrontmatter;
|
|
49
|
+
body: string;
|
|
50
|
+
/** Absolute path of the canonical markdown file. */
|
|
51
|
+
path: string;
|
|
52
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Built-in artifact types from the product spec. Custom types may be added
|
|
4
|
+
* via workspace config (see config schema).
|
|
5
|
+
*/
|
|
6
|
+
export const BUILTIN_ARTIFACT_TYPES = [
|
|
7
|
+
'prd',
|
|
8
|
+
'okr',
|
|
9
|
+
'retro',
|
|
10
|
+
'sprint-plan',
|
|
11
|
+
'brainstorm',
|
|
12
|
+
'usecases',
|
|
13
|
+
'design',
|
|
14
|
+
'api',
|
|
15
|
+
'architecture',
|
|
16
|
+
'decision',
|
|
17
|
+
'risk',
|
|
18
|
+
'qa',
|
|
19
|
+
'ceremony',
|
|
20
|
+
];
|
|
21
|
+
/** ISO-8601 datetime string. */
|
|
22
|
+
export const isoDateTime = z
|
|
23
|
+
.string()
|
|
24
|
+
.refine((v) => !Number.isNaN(Date.parse(v)), { message: 'must be an ISO-8601 datetime' });
|
|
25
|
+
/**
|
|
26
|
+
* Frontmatter persisted at the top of every artifact markdown file.
|
|
27
|
+
* Mirrored into SQLite for fast listing/filter; markdown is the source of truth.
|
|
28
|
+
*/
|
|
29
|
+
export const artifactFrontmatterSchema = z
|
|
30
|
+
.object({
|
|
31
|
+
id: z.string().min(1),
|
|
32
|
+
type: z.string().min(1),
|
|
33
|
+
title: z.string().min(1, 'title is required'),
|
|
34
|
+
slug: z.string().min(1),
|
|
35
|
+
revision: z.number().int().positive(),
|
|
36
|
+
createdAt: isoDateTime,
|
|
37
|
+
updatedAt: isoDateTime,
|
|
38
|
+
deletedAt: isoDateTime.nullable().optional(),
|
|
39
|
+
meta: z.record(z.string(), z.unknown()).default({}),
|
|
40
|
+
})
|
|
41
|
+
.strict();
|
|
42
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/artifacts/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,KAAK;IACL,KAAK;IACL,OAAO;IACP,aAAa;IACb,YAAY;IACZ,UAAU;IACV,QAAQ;IACR,KAAK;IACL,cAAc;IACd,UAAU;IACV,MAAM;IACN,IAAI;IACJ,UAAU;CACF,CAAC;AAKX,gCAAgC;AAChC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC;KACzB,MAAM,EAAE;KACR,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC,CAAC;AAE5F;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC;KACvC,MAAM,CAAC;IACN,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC;IAC7C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACrC,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC5C,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACpD,CAAC;KACD,MAAM,EAAE,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type WorkspaceConfig } from '../workspace/config.js';
|
|
3
|
+
/** User-supplied input for create. */
|
|
4
|
+
export declare const createArtifactInputSchema: z.ZodObject<{
|
|
5
|
+
type: z.ZodString;
|
|
6
|
+
title: z.ZodString;
|
|
7
|
+
body: z.ZodDefault<z.ZodString>;
|
|
8
|
+
slug: z.ZodOptional<z.ZodString>;
|
|
9
|
+
meta: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
10
|
+
}, "strict", z.ZodTypeAny, {
|
|
11
|
+
type: string;
|
|
12
|
+
title: string;
|
|
13
|
+
meta: Record<string, unknown>;
|
|
14
|
+
body: string;
|
|
15
|
+
slug?: string | undefined;
|
|
16
|
+
}, {
|
|
17
|
+
type: string;
|
|
18
|
+
title: string;
|
|
19
|
+
slug?: string | undefined;
|
|
20
|
+
meta?: Record<string, unknown> | undefined;
|
|
21
|
+
body?: string | undefined;
|
|
22
|
+
}>;
|
|
23
|
+
export type CreateArtifactInput = z.infer<typeof createArtifactInputSchema>;
|
|
24
|
+
/** User-supplied input for update. Identifier uses one of id or {type, slug}. */
|
|
25
|
+
export declare const updateArtifactInputSchema: z.ZodObject<{
|
|
26
|
+
title: z.ZodOptional<z.ZodString>;
|
|
27
|
+
body: z.ZodOptional<z.ZodString>;
|
|
28
|
+
meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
29
|
+
/** Optimistic-concurrency revision the agent based the edit on. */
|
|
30
|
+
expectedRevision: z.ZodOptional<z.ZodNumber>;
|
|
31
|
+
}, "strict", z.ZodTypeAny, {
|
|
32
|
+
title?: string | undefined;
|
|
33
|
+
meta?: Record<string, unknown> | undefined;
|
|
34
|
+
body?: string | undefined;
|
|
35
|
+
expectedRevision?: number | undefined;
|
|
36
|
+
}, {
|
|
37
|
+
title?: string | undefined;
|
|
38
|
+
meta?: Record<string, unknown> | undefined;
|
|
39
|
+
body?: string | undefined;
|
|
40
|
+
expectedRevision?: number | undefined;
|
|
41
|
+
}>;
|
|
42
|
+
export type UpdateArtifactInput = z.infer<typeof updateArtifactInputSchema>;
|
|
43
|
+
export declare function assertSupportedType(type: string, config: WorkspaceConfig): void;
|
|
44
|
+
export declare function parseCreateInput(input: unknown): CreateArtifactInput;
|
|
45
|
+
export declare function parseUpdateInput(input: unknown): UpdateArtifactInput;
|
|
46
|
+
export declare function validateArtifactMeta(type: string, meta: unknown): Record<string, unknown>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { SpegoError } from '../errors.js';
|
|
3
|
+
import { knownArtifactTypes } from '../workspace/config.js';
|
|
4
|
+
import { validateMetaForType } from './schemas.js';
|
|
5
|
+
/** User-supplied input for create. */
|
|
6
|
+
export const createArtifactInputSchema = z
|
|
7
|
+
.object({
|
|
8
|
+
type: z.string().min(1),
|
|
9
|
+
title: z.string().min(1, 'title is required'),
|
|
10
|
+
body: z.string().default(''),
|
|
11
|
+
slug: z.string().min(1).optional(),
|
|
12
|
+
meta: z.record(z.string(), z.unknown()).default({}),
|
|
13
|
+
})
|
|
14
|
+
.strict();
|
|
15
|
+
/** User-supplied input for update. Identifier uses one of id or {type, slug}. */
|
|
16
|
+
export const updateArtifactInputSchema = z
|
|
17
|
+
.object({
|
|
18
|
+
title: z.string().min(1).optional(),
|
|
19
|
+
body: z.string().optional(),
|
|
20
|
+
meta: z.record(z.string(), z.unknown()).optional(),
|
|
21
|
+
/** Optimistic-concurrency revision the agent based the edit on. */
|
|
22
|
+
expectedRevision: z.number().int().positive().optional(),
|
|
23
|
+
})
|
|
24
|
+
.strict();
|
|
25
|
+
const SAFE_TYPE_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
26
|
+
export function assertSupportedType(type, config) {
|
|
27
|
+
if (!SAFE_TYPE_RE.test(type)) {
|
|
28
|
+
throw new SpegoError('INVALID_ARTIFACT_TYPE', `Invalid artifact type format: ${type}`, {
|
|
29
|
+
type,
|
|
30
|
+
hint: 'Type must be lowercase alphanumeric with hyphens.',
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
if (!knownArtifactTypes(config).has(type)) {
|
|
34
|
+
throw new SpegoError('INVALID_ARTIFACT_TYPE', `Unsupported artifact type: ${type}`, {
|
|
35
|
+
type,
|
|
36
|
+
hint: `Register the type via workspace config (extraArtifactTypes) to allow it.`,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function parseCreateInput(input) {
|
|
41
|
+
const result = createArtifactInputSchema.safeParse(input);
|
|
42
|
+
if (!result.success) {
|
|
43
|
+
throw new SpegoError('VALIDATION_FAILED', 'Invalid create-artifact input', {
|
|
44
|
+
issues: result.error.issues,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return result.data;
|
|
48
|
+
}
|
|
49
|
+
export function parseUpdateInput(input) {
|
|
50
|
+
const result = updateArtifactInputSchema.safeParse(input);
|
|
51
|
+
if (!result.success) {
|
|
52
|
+
throw new SpegoError('VALIDATION_FAILED', 'Invalid update-artifact input', {
|
|
53
|
+
issues: result.error.issues,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return result.data;
|
|
57
|
+
}
|
|
58
|
+
export function validateArtifactMeta(type, meta) {
|
|
59
|
+
try {
|
|
60
|
+
return validateMetaForType(type, meta);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
if (err instanceof Error && 'issues' in err) {
|
|
64
|
+
throw new SpegoError('VALIDATION_FAILED', `Invalid metadata for artifact type: ${type}`, {
|
|
65
|
+
type,
|
|
66
|
+
issues: err.issues,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
throw err;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/artifacts/validation.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED