@appstrate/validation 1.0.0 → 1.0.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appstrate/validation",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "type": "module",
5
5
  "files": ["src"],
6
6
  "exports": {
package/src/index.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import { z } from "zod";
2
2
  import semver from "semver";
3
+ import { SLUG_REGEX } from "./naming.ts";
3
4
 
4
- export const SLUG_REGEX = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
5
+ export { SLUG_REGEX };
5
6
 
6
7
  const flowFieldTypeEnum = z.enum(["string", "number", "boolean", "array", "object", "file"]);
7
8
 
@@ -73,15 +74,10 @@ export const baseManifestSchema = z.object({
73
74
  export type BaseManifest = z.infer<typeof baseManifestSchema>;
74
75
 
75
76
  // ─────────────────────────────────────────────
76
- // Flow manifest schemaextends base with flow-specific fields
77
+ // Shared flow fieldsused by both flowManifestSchema and localFlowManifestSchema
77
78
  // ─────────────────────────────────────────────
78
79
 
79
- export const flowManifestSchema = baseManifestSchema.extend({
80
- $schema: z.string().optional(),
81
- schemaVersion: z.string(),
82
- displayName: z.string().min(1),
83
- author: z.string(),
84
- tags: z.array(z.string()).optional(),
80
+ const flowSharedFields = {
85
81
  requires: z.object({
86
82
  services: z.array(serviceRequirementSchema),
87
83
  skills: z.array(slugString).optional().default([]),
@@ -109,6 +105,19 @@ export const flowManifestSchema = baseManifestSchema.extend({
109
105
  outputRetries: z.number().min(0).max(5).optional(),
110
106
  })
111
107
  .optional(),
108
+ } as const;
109
+
110
+ // ─────────────────────────────────────────────
111
+ // Flow manifest schema — extends base with flow-specific fields
112
+ // ─────────────────────────────────────────────
113
+
114
+ export const flowManifestSchema = baseManifestSchema.extend({
115
+ $schema: z.string().optional(),
116
+ schemaVersion: z.string(),
117
+ displayName: z.string().min(1),
118
+ author: z.string(),
119
+ tags: z.array(z.string()).optional(),
120
+ ...flowSharedFields,
112
121
  });
113
122
 
114
123
  export type FlowManifest = z.infer<typeof flowManifestSchema>;
@@ -121,11 +130,11 @@ export type ManifestSchema = FlowManifest;
121
130
  // Unified validateManifest — dispatches by type
122
131
  // ─────────────────────────────────────────────
123
132
 
124
- export function validateManifest(raw: unknown): {
125
- valid: boolean;
126
- errors: string[];
127
- manifest?: unknown;
128
- } {
133
+ export type ValidateManifestResult =
134
+ | { valid: true; errors: []; manifest: BaseManifest | FlowManifest }
135
+ | { valid: false; errors: string[]; manifest?: undefined };
136
+
137
+ export function validateManifest(raw: unknown): ValidateManifestResult {
129
138
  // First, check if it has a type field to dispatch
130
139
  if (raw && typeof raw === "object" && "type" in raw) {
131
140
  const obj = raw as Record<string, unknown>;
@@ -148,11 +157,7 @@ export function validateManifest(raw: unknown): {
148
157
  return validateFlowManifest(raw);
149
158
  }
150
159
 
151
- function validateFlowManifest(raw: unknown): {
152
- valid: boolean;
153
- errors: string[];
154
- manifest?: unknown;
155
- } {
160
+ function validateFlowManifest(raw: unknown): ValidateManifestResult {
156
161
  const result = flowManifestSchema.safeParse(raw);
157
162
  if (result.success) {
158
163
  return { valid: true, errors: [], manifest: result.data };
@@ -240,33 +245,7 @@ export const localFlowManifestSchema = z.looseObject({
240
245
  tags: z.array(z.string()).optional(),
241
246
  type: z.string().optional(),
242
247
  version: z.string().optional(),
243
- requires: z.object({
244
- services: z.array(serviceRequirementSchema),
245
- skills: z.array(slugString).optional().default([]),
246
- extensions: z.array(slugString).optional().default([]),
247
- registryDependencies: registryDependenciesSchema,
248
- }),
249
- input: z
250
- .object({
251
- schema: jsonSchemaObjectSchema,
252
- })
253
- .optional(),
254
- output: z
255
- .object({
256
- schema: jsonSchemaObjectSchema,
257
- })
258
- .optional(),
259
- config: z
260
- .object({
261
- schema: jsonSchemaObjectSchema,
262
- })
263
- .optional(),
264
- execution: z
265
- .object({
266
- timeout: z.number().optional(),
267
- outputRetries: z.number().min(0).max(5).optional(),
268
- })
269
- .optional(),
248
+ ...flowSharedFields,
270
249
  });
271
250
 
272
251
  export type LocalFlowManifest = z.infer<typeof localFlowManifestSchema>;
package/src/naming.ts CHANGED
@@ -1,8 +1,7 @@
1
- import { SLUG_REGEX } from "./index.ts";
2
-
3
- export { SLUG_REGEX };
1
+ export const SLUG_REGEX = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
4
2
 
5
3
  export function normalizeScope(scope: string): string {
4
+ if (!scope) throw new Error("Scope cannot be empty");
6
5
  return scope.startsWith("@") ? scope : `@${scope}`;
7
6
  }
8
7