@vue-skuilder/common 0.1.11-9 → 0.1.11

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
@@ -6,8 +6,10 @@ export * from './logshim.js';
6
6
  export * from './validators.js';
7
7
  export * from './fieldConverters.js';
8
8
  export * from './db.js';
9
+ export * from './logger.js';
9
10
  export * from './bulkImport/cardParser.js';
10
11
  export * from './bulkImport/types.js';
11
12
  export * from './interfaces/index.js';
12
13
  export * from './enums/index.js';
14
+ export * from './schemas/dataShapeToZod.js';
13
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,SAAS,CAAC;AAExB,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AAGtC,cAAc,uBAAuB,CAAC;AAGtC,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAE5B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AAGtC,cAAc,uBAAuB,CAAC;AAGtC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,6BAA6B,CAAC"}
package/dist/index.js CHANGED
@@ -22,12 +22,15 @@ __exportStar(require("./logshim.js"), exports);
22
22
  __exportStar(require("./validators.js"), exports);
23
23
  __exportStar(require("./fieldConverters.js"), exports);
24
24
  __exportStar(require("./db.js"), exports);
25
+ __exportStar(require("./logger.js"), exports);
25
26
  __exportStar(require("./bulkImport/cardParser.js"), exports);
26
27
  __exportStar(require("./bulkImport/types.js"), exports);
27
28
  // interfaces
28
29
  __exportStar(require("./interfaces/index.js"), exports);
29
30
  // enums
30
31
  __exportStar(require("./enums/index.js"), exports);
32
+ // schemas
33
+ __exportStar(require("./schemas/dataShapeToZod.js"), exports);
31
34
  // docker utilities (Node.js only - not exported in main index for browser compatibility)
32
35
  // Use explicit import: import { CouchDBManager } from '@vue-skuilder/common/docker'
33
36
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,SAAS,CAAC;AAExB,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AAEtC,aAAa;AACb,cAAc,uBAAuB,CAAC;AAEtC,QAAQ;AACR,cAAc,kBAAkB,CAAC;AAEjC,yFAAyF;AACzF,oFAAoF"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAE5B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AAEtC,aAAa;AACb,cAAc,uBAAuB,CAAC;AAEtC,QAAQ;AACR,cAAc,kBAAkB,CAAC;AAEjC,UAAU;AACV,cAAc,6BAA6B,CAAC;AAE5C,yFAAyF;AACzF,oFAAoF"}
package/dist/index.mjs CHANGED
@@ -6,12 +6,15 @@ export * from './logshim.mjs';
6
6
  export * from './validators.mjs';
7
7
  export * from './fieldConverters.mjs';
8
8
  export * from './db.mjs';
9
+ export * from './logger.mjs';
9
10
  export * from './bulkImport/cardParser.mjs';
10
11
  export * from './bulkImport/types.mjs';
11
12
  // interfaces
12
13
  export * from './interfaces/index.mjs';
13
14
  // enums
14
15
  export * from './enums/index.mjs';
16
+ // schemas
17
+ export * from './schemas/dataShapeToZod.mjs';
15
18
  // docker utilities (Node.js only - not exported in main index for browser compatibility)
16
19
  // Use explicit import: import { CouchDBManager } from '@vue-skuilder/common/docker'
17
20
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Standard logger interface for vue-skuilder packages
3
+ *
4
+ * This interface enables dependency injection of logging functionality,
5
+ * allowing different runtime contexts to provide appropriate logger implementations:
6
+ * - Node.js contexts can use Winston
7
+ * - Browser contexts can use console wrappers
8
+ * - Test contexts can use mock loggers
9
+ */
10
+ export interface SkLogger {
11
+ debug(message: string, ...args: unknown[]): void;
12
+ info(message: string, ...args: unknown[]): void;
13
+ warn(message: string, ...args: unknown[]): void;
14
+ error(message: string, ...args: unknown[]): void;
15
+ }
16
+ /**
17
+ * No-op logger implementation for contexts where logging is not needed
18
+ */
19
+ export declare const noOpLogger: SkLogger;
20
+ /**
21
+ * Console-based logger for browser/development contexts
22
+ * Uses console methods with appropriate ESLint suppressions
23
+ */
24
+ export declare const consoleLogger: SkLogger;
25
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAClD;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,QAKxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,QAK3B,CAAC"}
package/dist/logger.js ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.consoleLogger = exports.noOpLogger = void 0;
4
+ /**
5
+ * No-op logger implementation for contexts where logging is not needed
6
+ */
7
+ exports.noOpLogger = {
8
+ debug: () => { },
9
+ info: () => { },
10
+ warn: () => { },
11
+ error: () => { },
12
+ };
13
+ /**
14
+ * Console-based logger for browser/development contexts
15
+ * Uses console methods with appropriate ESLint suppressions
16
+ */
17
+ exports.consoleLogger = {
18
+ debug: (message, ...args) => console.debug(message, ...args), // eslint-disable-line no-console
19
+ info: (message, ...args) => console.info(message, ...args), // eslint-disable-line no-console
20
+ warn: (message, ...args) => console.warn(message, ...args), // eslint-disable-line no-console
21
+ error: (message, ...args) => console.error(message, ...args), // eslint-disable-line no-console
22
+ };
23
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAgBA;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAa;IAClC,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;IACf,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;CAChB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAa;IACrC,KAAK,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,EAAE,iCAAiC;IAClH,IAAI,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,EAAE,iCAAiC;IAChH,IAAI,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,EAAE,iCAAiC;IAChH,KAAK,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,EAAE,iCAAiC;CACnH,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * No-op logger implementation for contexts where logging is not needed
3
+ */
4
+ export const noOpLogger = {
5
+ debug: () => { },
6
+ info: () => { },
7
+ warn: () => { },
8
+ error: () => { },
9
+ };
10
+ /**
11
+ * Console-based logger for browser/development contexts
12
+ * Uses console methods with appropriate ESLint suppressions
13
+ */
14
+ export const consoleLogger = {
15
+ debug: (message, ...args) => console.debug(message, ...args), // eslint-disable-line no-console
16
+ info: (message, ...args) => console.info(message, ...args), // eslint-disable-line no-console
17
+ warn: (message, ...args) => console.warn(message, ...args), // eslint-disable-line no-console
18
+ error: (message, ...args) => console.error(message, ...args), // eslint-disable-line no-console
19
+ };
20
+ //# sourceMappingURL=logger.js.map
@@ -5,7 +5,7 @@ class NameSpacer {
5
5
  static getDataShapeDescriptor(shapeStr) {
6
6
  const splitArray = shapeStr.split('.');
7
7
  if (splitArray.length !== 3) {
8
- throw new Error('shapeStr not valid');
8
+ throw new Error(`shapeStr [${shapeStr}] not valid`);
9
9
  }
10
10
  else {
11
11
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"namespacer.js","sourceRoot":"","sources":["../src/namespacer.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,UAAU;IACd,MAAM,CAAC,sBAAsB,CAAC,QAAgB;QACnD,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEvC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,OAAO;gBACL,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;gBACrB,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;aACzB,CAAC;QACJ,CAAC;IACH,CAAC;IACM,MAAM,CAAC,kBAAkB,CAAC,gBAAiC;QAChE,OAAO,GAAG,gBAAgB,CAAC,MAAM,cAAc,gBAAgB,CAAC,SAAS,EAAE,CAAC;IAC9E,CAAC;IAEM,MAAM,CAAC,iBAAiB,CAAC,OAAe;QAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEtC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,OAAO;gBACL,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;gBACrB,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;gBAC3B,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;aACpB,CAAC;QACJ,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,aAAa,CAAC,eAA+B;QACzD,OAAO,CACL,GAAG,eAAe,CAAC,MAAM,YAAY;YACrC,GAAG,eAAe,CAAC,YAAY,IAAI,eAAe,CAAC,IAAI,EAAE,CAC1D,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,qBAAqB,CAAC,WAAmB;QACrD,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE1C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,OAAO;gBACL,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;gBACrB,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;aAC5B,CAAC;QACJ,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,iBAAiB,CAAC,mBAAuC;QACrE,OAAO,GAAG,mBAAmB,CAAC,MAAM,aAAa,mBAAmB,CAAC,YAAY,EAAE,CAAC;IACtF,CAAC;CACF"}
1
+ {"version":3,"file":"namespacer.js","sourceRoot":"","sources":["../src/namespacer.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,UAAU;IACd,MAAM,CAAC,sBAAsB,CAAC,QAAgB;QACnD,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEvC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,aAAa,QAAQ,aAAa,CAAC,CAAC;QACtD,CAAC;aAAM,CAAC;YACN,OAAO;gBACL,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;gBACrB,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;aACzB,CAAC;QACJ,CAAC;IACH,CAAC;IACM,MAAM,CAAC,kBAAkB,CAAC,gBAAiC;QAChE,OAAO,GAAG,gBAAgB,CAAC,MAAM,cAAc,gBAAgB,CAAC,SAAS,EAAE,CAAC;IAC9E,CAAC;IAEM,MAAM,CAAC,iBAAiB,CAAC,OAAe;QAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEtC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,OAAO;gBACL,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;gBACrB,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;gBAC3B,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;aACpB,CAAC;QACJ,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,aAAa,CAAC,eAA+B;QACzD,OAAO,CACL,GAAG,eAAe,CAAC,MAAM,YAAY;YACrC,GAAG,eAAe,CAAC,YAAY,IAAI,eAAe,CAAC,IAAI,EAAE,CAC1D,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,qBAAqB,CAAC,WAAmB;QACrD,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE1C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,OAAO;gBACL,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;gBACrB,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;aAC5B,CAAC;QACJ,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,iBAAiB,CAAC,mBAAuC;QACrE,OAAO,GAAG,mBAAmB,CAAC,MAAM,aAAa,mBAAmB,CAAC,YAAY,EAAE,CAAC;IACtF,CAAC;CACF"}
@@ -2,7 +2,7 @@ export class NameSpacer {
2
2
  static getDataShapeDescriptor(shapeStr) {
3
3
  const splitArray = shapeStr.split('.');
4
4
  if (splitArray.length !== 3) {
5
- throw new Error('shapeStr not valid');
5
+ throw new Error(`shapeStr [${shapeStr}] not valid`);
6
6
  }
7
7
  else {
8
8
  return {
@@ -0,0 +1,11 @@
1
+ import { z, ZodRawShape } from 'zod';
2
+ import { DataShape } from '../index.js';
3
+ /**
4
+ * Converts a DataShape to a Zod schema
5
+ */
6
+ export declare function toZod(dataShape: DataShape): z.ZodObject<ZodRawShape>;
7
+ /**
8
+ * Converts a DataShape to JSON Schema string using Zod v4 native conversion
9
+ */
10
+ export declare function toZodJSON(dataShape: DataShape): string;
11
+ //# sourceMappingURL=dataShapeToZod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataShapeToZod.d.ts","sourceRoot":"","sources":["../../src/schemas/dataShapeToZod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,MAAM,KAAK,CAAC;AACrC,OAAO,EAAE,SAAS,EAAsC,MAAM,aAAa,CAAC;AAiG5E;;GAEG;AACH,wBAAgB,KAAK,CAAC,SAAS,EAAE,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAQpE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAItD"}
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toZod = toZod;
4
+ exports.toZodJSON = toZodJSON;
5
+ const zod_1 = require("zod");
6
+ const index_js_1 = require("../index.js");
7
+ /**
8
+ * Converts a FieldType enum to appropriate Zod schema
9
+ */
10
+ function fieldTypeToZodSchema(field) {
11
+ let baseSchema;
12
+ switch (field.type) {
13
+ case index_js_1.FieldType.STRING:
14
+ baseSchema = zod_1.z.string().min(1, `${field.name} cannot be empty`);
15
+ break;
16
+ case index_js_1.FieldType.MARKDOWN:
17
+ baseSchema = zod_1.z.string().min(1, `${field.name} cannot be empty`);
18
+ // Special handling for known patterns like Blanks
19
+ if (field.name === 'Input') {
20
+ baseSchema = baseSchema
21
+ .refine((value) => typeof value === 'string' && value.includes('{{') && value.includes('}}'), 'Must contain at least one blank in format {{answer}} or {{answer1|answer2||distractor}}')
22
+ .describe("Markdown text with blanks. Format: {{answer}} for fill-in or {{answer1|answer2||distractor1|distractor2}} for multiple choice. Use the 'fill-in-card-authoring' MCP prompt for detailed syntax guidance.");
23
+ }
24
+ else {
25
+ baseSchema = baseSchema.describe('Markdown content');
26
+ }
27
+ break;
28
+ case index_js_1.FieldType.NUMBER:
29
+ baseSchema = zod_1.z.number().describe(`Numeric value for ${field.name}`);
30
+ break;
31
+ case index_js_1.FieldType.INT:
32
+ baseSchema = zod_1.z.number().int().describe(`Integer value for ${field.name}`);
33
+ break;
34
+ case index_js_1.FieldType.IMAGE:
35
+ baseSchema = zod_1.z.any().optional().describe('Image file');
36
+ break;
37
+ case index_js_1.FieldType.AUDIO:
38
+ baseSchema = zod_1.z.any().optional().describe('Audio file');
39
+ break;
40
+ case index_js_1.FieldType.MIDI:
41
+ baseSchema = zod_1.z.any().optional().describe('MIDI file');
42
+ break;
43
+ case index_js_1.FieldType.MEDIA_UPLOADS:
44
+ baseSchema = zod_1.z
45
+ .array(zod_1.z.any())
46
+ .optional()
47
+ .describe('Optional media files (images, audio, etc.)');
48
+ break;
49
+ case index_js_1.FieldType.CHESS_PUZZLE:
50
+ baseSchema = zod_1.z
51
+ .string()
52
+ .min(1, 'Chess puzzle cannot be empty')
53
+ .describe('Chess puzzle in FEN or PGN format');
54
+ break;
55
+ default:
56
+ baseSchema = zod_1.z.any().describe(`Field of type ${field.type}`);
57
+ }
58
+ // Add custom validation if present
59
+ if (field.validator) {
60
+ const originalValidator = field.validator;
61
+ baseSchema = baseSchema.refine((value) => {
62
+ try {
63
+ const result = originalValidator.test(String(value));
64
+ return result.status === index_js_1.Status.ok;
65
+ }
66
+ catch {
67
+ return false;
68
+ }
69
+ }, {
70
+ message: originalValidator.instructions || `Validation failed for ${field.name}`,
71
+ });
72
+ // Add validator instructions as description if available
73
+ if (originalValidator.instructions) {
74
+ baseSchema = baseSchema.describe(`${baseSchema.description || ''}\nInstructions: ${originalValidator.instructions}`.trim());
75
+ }
76
+ }
77
+ return baseSchema;
78
+ }
79
+ /**
80
+ * Converts a DataShape to a Zod schema
81
+ */
82
+ function toZod(dataShape) {
83
+ const schemaFields = {};
84
+ dataShape.fields.forEach((field) => {
85
+ schemaFields[field.name] = fieldTypeToZodSchema(field);
86
+ });
87
+ return zod_1.z.object(schemaFields).describe(`DataShape: ${dataShape.name} - Schema for card creation`);
88
+ }
89
+ /**
90
+ * Converts a DataShape to JSON Schema string using Zod v4 native conversion
91
+ */
92
+ function toZodJSON(dataShape) {
93
+ const zodSchema = toZod(dataShape);
94
+ const jsonSchema = zod_1.z.toJSONSchema(zodSchema);
95
+ return JSON.stringify(jsonSchema, null, 2);
96
+ }
97
+ //# sourceMappingURL=dataShapeToZod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataShapeToZod.js","sourceRoot":"","sources":["../../src/schemas/dataShapeToZod.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ import { z } from 'zod';
2
+ import { FieldType, Status } from '../index.mjs';
3
+ /**
4
+ * Converts a FieldType enum to appropriate Zod schema
5
+ */
6
+ function fieldTypeToZodSchema(field) {
7
+ let baseSchema;
8
+ switch (field.type) {
9
+ case FieldType.STRING:
10
+ baseSchema = z.string().min(1, `${field.name} cannot be empty`);
11
+ break;
12
+ case FieldType.MARKDOWN:
13
+ baseSchema = z.string().min(1, `${field.name} cannot be empty`);
14
+ // Special handling for known patterns like Blanks
15
+ if (field.name === 'Input') {
16
+ baseSchema = baseSchema
17
+ .refine((value) => typeof value === 'string' && value.includes('{{') && value.includes('}}'), 'Must contain at least one blank in format {{answer}} or {{answer1|answer2||distractor}}')
18
+ .describe("Markdown text with blanks. Format: {{answer}} for fill-in or {{answer1|answer2||distractor1|distractor2}} for multiple choice. Use the 'fill-in-card-authoring' MCP prompt for detailed syntax guidance.");
19
+ }
20
+ else {
21
+ baseSchema = baseSchema.describe('Markdown content');
22
+ }
23
+ break;
24
+ case FieldType.NUMBER:
25
+ baseSchema = z.number().describe(`Numeric value for ${field.name}`);
26
+ break;
27
+ case FieldType.INT:
28
+ baseSchema = z.number().int().describe(`Integer value for ${field.name}`);
29
+ break;
30
+ case FieldType.IMAGE:
31
+ baseSchema = z.any().optional().describe('Image file');
32
+ break;
33
+ case FieldType.AUDIO:
34
+ baseSchema = z.any().optional().describe('Audio file');
35
+ break;
36
+ case FieldType.MIDI:
37
+ baseSchema = z.any().optional().describe('MIDI file');
38
+ break;
39
+ case FieldType.MEDIA_UPLOADS:
40
+ baseSchema = z
41
+ .array(z.any())
42
+ .optional()
43
+ .describe('Optional media files (images, audio, etc.)');
44
+ break;
45
+ case FieldType.CHESS_PUZZLE:
46
+ baseSchema = z
47
+ .string()
48
+ .min(1, 'Chess puzzle cannot be empty')
49
+ .describe('Chess puzzle in FEN or PGN format');
50
+ break;
51
+ default:
52
+ baseSchema = z.any().describe(`Field of type ${field.type}`);
53
+ }
54
+ // Add custom validation if present
55
+ if (field.validator) {
56
+ const originalValidator = field.validator;
57
+ baseSchema = baseSchema.refine((value) => {
58
+ try {
59
+ const result = originalValidator.test(String(value));
60
+ return result.status === Status.ok;
61
+ }
62
+ catch {
63
+ return false;
64
+ }
65
+ }, {
66
+ message: originalValidator.instructions || `Validation failed for ${field.name}`,
67
+ });
68
+ // Add validator instructions as description if available
69
+ if (originalValidator.instructions) {
70
+ baseSchema = baseSchema.describe(`${baseSchema.description || ''}\nInstructions: ${originalValidator.instructions}`.trim());
71
+ }
72
+ }
73
+ return baseSchema;
74
+ }
75
+ /**
76
+ * Converts a DataShape to a Zod schema
77
+ */
78
+ export function toZod(dataShape) {
79
+ const schemaFields = {};
80
+ dataShape.fields.forEach((field) => {
81
+ schemaFields[field.name] = fieldTypeToZodSchema(field);
82
+ });
83
+ return z.object(schemaFields).describe(`DataShape: ${dataShape.name} - Schema for card creation`);
84
+ }
85
+ /**
86
+ * Converts a DataShape to JSON Schema string using Zod v4 native conversion
87
+ */
88
+ export function toZodJSON(dataShape) {
89
+ const zodSchema = toZod(dataShape);
90
+ const jsonSchema = z.toJSONSchema(zodSchema);
91
+ return JSON.stringify(jsonSchema, null, 2);
92
+ }
93
+ //# sourceMappingURL=dataShapeToZod.js.map
@@ -59,6 +59,7 @@ type NamespacedDatashape = string;
59
59
  export interface DataShape55 {
60
60
  name: NamespacedDatashape;
61
61
  questionTypes: PouchDB.Core.DocumentId[];
62
+ serializedZodSchema?: string;
62
63
  }
63
64
  type NamespacedQuestion = string;
64
65
  export interface QuestionType55 {
@@ -131,6 +132,7 @@ export interface PackCourse extends IServerRequest {
131
132
  type: ServerRequestType.PACK_COURSE;
132
133
  courseId: string;
133
134
  outputPath?: string;
135
+ couchdbUrl?: string;
134
136
  response: {
135
137
  status: Status;
136
138
  ok: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"wire-format.d.ts","sourceRoot":"","sources":["../src/wire-format.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wire-format.d.ts","sourceRoot":"","sources":["../src/wire-format.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"wire-format.js","sourceRoot":"","sources":["../src/wire-format.ts"],"names":[],"mappings":"AAEA,MAAM,CAAN,IAAY,MAKX;AALD,WAAY,MAAM;IAChB,uCAA6B,CAAA;IAC7B,mBAAS,CAAA;IACT,6BAAmB,CAAA;IACnB,yBAAe,CAAA;AACjB,CAAC,EALW,MAAM,KAAN,MAAM,QAKjB;AA+JD,MAAM,CAAN,IAAY,iBASX;AATD,WAAY,iBAAiB;IAC3B,0DAAqC,CAAA;IACrC,0DAAqC,CAAA;IACrC,sDAAiC,CAAA;IACjC,wDAAmC,CAAA;IACnC,oDAA+B,CAAA;IAC/B,oDAA+B,CAAA;IAC/B,wDAAmC,CAAA;IACnC,gDAA2B,CAAA;AAC7B,CAAC,EATW,iBAAiB,KAAjB,iBAAiB,QAS5B"}
1
+ {"version":3,"file":"wire-format.js","sourceRoot":"","sources":["../src/wire-format.ts"],"names":[],"mappings":"AAEA,MAAM,CAAN,IAAY,MAKX;AALD,WAAY,MAAM;IAChB,uCAA6B,CAAA;IAC7B,mBAAS,CAAA;IACT,6BAAmB,CAAA;IACnB,yBAAe,CAAA;AACjB,CAAC,EALW,MAAM,KAAN,MAAM,QAKjB;AAiKD,MAAM,CAAN,IAAY,iBASX;AATD,WAAY,iBAAiB;IAC3B,0DAAqC,CAAA;IACrC,0DAAqC,CAAA;IACrC,sDAAiC,CAAA;IACjC,wDAAmC,CAAA;IACnC,oDAA+B,CAAA;IAC/B,oDAA+B,CAAA;IAC/B,wDAAmC,CAAA;IACnC,gDAA2B,CAAA;AAC7B,CAAC,EATW,iBAAiB,KAAjB,iBAAiB,QAS5B"}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.1.11-9",
6
+ "version": "0.1.11",
7
7
  "type": "module",
8
8
  "main": "dist/index.js",
9
9
  "module": "dist/index.mjs",
@@ -32,7 +32,8 @@
32
32
  "typescript": "~5.7.2"
33
33
  },
34
34
  "dependencies": {
35
- "moment": "^2.30.1"
35
+ "moment": "^2.30.1",
36
+ "zod": "^4.0.0"
36
37
  },
37
- "stableVersion": "0.1.10"
38
+ "stableVersion": "0.1.11"
38
39
  }
package/src/index.ts CHANGED
@@ -6,6 +6,7 @@ export * from './logshim.js';
6
6
  export * from './validators.js';
7
7
  export * from './fieldConverters.js';
8
8
  export * from './db.js';
9
+ export * from './logger.js';
9
10
 
10
11
  export * from './bulkImport/cardParser.js';
11
12
  export * from './bulkImport/types.js';
@@ -16,5 +17,8 @@ export * from './interfaces/index.js';
16
17
  // enums
17
18
  export * from './enums/index.js';
18
19
 
20
+ // schemas
21
+ export * from './schemas/dataShapeToZod.js';
22
+
19
23
  // docker utilities (Node.js only - not exported in main index for browser compatibility)
20
24
  // Use explicit import: import { CouchDBManager } from '@vue-skuilder/common/docker'
package/src/logger.ts ADDED
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Standard logger interface for vue-skuilder packages
3
+ *
4
+ * This interface enables dependency injection of logging functionality,
5
+ * allowing different runtime contexts to provide appropriate logger implementations:
6
+ * - Node.js contexts can use Winston
7
+ * - Browser contexts can use console wrappers
8
+ * - Test contexts can use mock loggers
9
+ */
10
+ export interface SkLogger {
11
+ debug(message: string, ...args: unknown[]): void;
12
+ info(message: string, ...args: unknown[]): void;
13
+ warn(message: string, ...args: unknown[]): void;
14
+ error(message: string, ...args: unknown[]): void;
15
+ }
16
+
17
+ /**
18
+ * No-op logger implementation for contexts where logging is not needed
19
+ */
20
+ export const noOpLogger: SkLogger = {
21
+ debug: () => {},
22
+ info: () => {},
23
+ warn: () => {},
24
+ error: () => {},
25
+ };
26
+
27
+ /**
28
+ * Console-based logger for browser/development contexts
29
+ * Uses console methods with appropriate ESLint suppressions
30
+ */
31
+ export const consoleLogger: SkLogger = {
32
+ debug: (message: string, ...args: unknown[]) => console.debug(message, ...args), // eslint-disable-line no-console
33
+ info: (message: string, ...args: unknown[]) => console.info(message, ...args), // eslint-disable-line no-console
34
+ warn: (message: string, ...args: unknown[]) => console.warn(message, ...args), // eslint-disable-line no-console
35
+ error: (message: string, ...args: unknown[]) => console.error(message, ...args), // eslint-disable-line no-console
36
+ };
package/src/namespacer.ts CHANGED
@@ -3,7 +3,7 @@ export class NameSpacer {
3
3
  const splitArray = shapeStr.split('.');
4
4
 
5
5
  if (splitArray.length !== 3) {
6
- throw new Error('shapeStr not valid');
6
+ throw new Error(`shapeStr [${shapeStr}] not valid`);
7
7
  } else {
8
8
  return {
9
9
  course: splitArray[0],
@@ -0,0 +1,119 @@
1
+ import { z, ZodRawShape } from 'zod';
2
+ import { DataShape, FieldDefinition, FieldType, Status } from '../index.js';
3
+
4
+ /**
5
+ * Converts a FieldType enum to appropriate Zod schema
6
+ */
7
+ function fieldTypeToZodSchema(field: FieldDefinition): z.ZodTypeAny {
8
+ let baseSchema: z.ZodTypeAny;
9
+
10
+ switch (field.type) {
11
+ case FieldType.STRING:
12
+ baseSchema = z.string().min(1, `${field.name} cannot be empty`);
13
+ break;
14
+
15
+ case FieldType.MARKDOWN:
16
+ baseSchema = z.string().min(1, `${field.name} cannot be empty`);
17
+
18
+ // Special handling for known patterns like Blanks
19
+ if (field.name === 'Input') {
20
+ baseSchema = baseSchema
21
+ .refine(
22
+ (value): value is string => typeof value === 'string' && value.includes('{{') && value.includes('}}'),
23
+ 'Must contain at least one blank in format {{answer}} or {{answer1|answer2||distractor}}'
24
+ )
25
+ .describe(
26
+ "Markdown text with blanks. Format: {{answer}} for fill-in or {{answer1|answer2||distractor1|distractor2}} for multiple choice. Use the 'fill-in-card-authoring' MCP prompt for detailed syntax guidance."
27
+ );
28
+ } else {
29
+ baseSchema = baseSchema.describe('Markdown content');
30
+ }
31
+ break;
32
+
33
+ case FieldType.NUMBER:
34
+ baseSchema = z.number().describe(`Numeric value for ${field.name}`);
35
+ break;
36
+
37
+ case FieldType.INT:
38
+ baseSchema = z.number().int().describe(`Integer value for ${field.name}`);
39
+ break;
40
+
41
+ case FieldType.IMAGE:
42
+ baseSchema = z.any().optional().describe('Image file');
43
+ break;
44
+
45
+ case FieldType.AUDIO:
46
+ baseSchema = z.any().optional().describe('Audio file');
47
+ break;
48
+
49
+ case FieldType.MIDI:
50
+ baseSchema = z.any().optional().describe('MIDI file');
51
+ break;
52
+
53
+ case FieldType.MEDIA_UPLOADS:
54
+ baseSchema = z
55
+ .array(z.any())
56
+ .optional()
57
+ .describe('Optional media files (images, audio, etc.)');
58
+ break;
59
+
60
+ case FieldType.CHESS_PUZZLE:
61
+ baseSchema = z
62
+ .string()
63
+ .min(1, 'Chess puzzle cannot be empty')
64
+ .describe('Chess puzzle in FEN or PGN format');
65
+ break;
66
+
67
+ default:
68
+ baseSchema = z.any().describe(`Field of type ${field.type}`);
69
+ }
70
+
71
+ // Add custom validation if present
72
+ if (field.validator) {
73
+ const originalValidator = field.validator;
74
+ baseSchema = baseSchema.refine(
75
+ (value) => {
76
+ try {
77
+ const result = originalValidator.test(String(value));
78
+ return result.status === Status.ok;
79
+ } catch {
80
+ return false;
81
+ }
82
+ },
83
+ {
84
+ message: originalValidator.instructions || `Validation failed for ${field.name}`,
85
+ }
86
+ );
87
+
88
+ // Add validator instructions as description if available
89
+ if (originalValidator.instructions) {
90
+ baseSchema = baseSchema.describe(
91
+ `${baseSchema.description || ''}\nInstructions: ${originalValidator.instructions}`.trim()
92
+ );
93
+ }
94
+ }
95
+
96
+ return baseSchema;
97
+ }
98
+
99
+ /**
100
+ * Converts a DataShape to a Zod schema
101
+ */
102
+ export function toZod(dataShape: DataShape): z.ZodObject<ZodRawShape> {
103
+ const schemaFields: Record<string, z.ZodTypeAny> = {};
104
+
105
+ dataShape.fields.forEach((field) => {
106
+ schemaFields[field.name] = fieldTypeToZodSchema(field);
107
+ });
108
+
109
+ return z.object(schemaFields).describe(`DataShape: ${dataShape.name} - Schema for card creation`);
110
+ }
111
+
112
+ /**
113
+ * Converts a DataShape to JSON Schema string using Zod v4 native conversion
114
+ */
115
+ export function toZodJSON(dataShape: DataShape): string {
116
+ const zodSchema = toZod(dataShape);
117
+ const jsonSchema = z.toJSONSchema(zodSchema);
118
+ return JSON.stringify(jsonSchema, null, 2);
119
+ }
@@ -66,6 +66,7 @@ export interface DataShape55 {
66
66
  // [ ] rename this to something else - disambiguate from DataShape in base-course
67
67
  name: NamespacedDatashape;
68
68
  questionTypes: PouchDB.Core.DocumentId[];
69
+ serializedZodSchema?: string;
69
70
  }
70
71
 
71
72
  type NamespacedQuestion = string; // ${course}.question.${question}
@@ -143,6 +144,7 @@ export interface PackCourse extends IServerRequest {
143
144
  type: ServerRequestType.PACK_COURSE;
144
145
  courseId: string;
145
146
  outputPath?: string;
147
+ couchdbUrl?: string; // Optional full CouchDB connection URL for studio mode
146
148
  response: {
147
149
  status: Status;
148
150
  ok: boolean;