@noves/intent-typescript-sdk
Version:
Noves Intent Typescript SDK
150 lines (139 loc) • 5.16 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateTypeDefinitions = generateTypeDefinitions;
const axios_1 = __importDefault(require("axios"));
const types_1 = require("../shared/types");
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
async function generateTypeDefinitions() {
try {
const response = await axios_1.default.get(`${types_1.IntentEndpoints.API_URL}/intents`);
const intents = response.data;
let typeDefinitions = `// Auto-generated types for Noves Intent SDK
// Do not modify this file directly
export type IntentModeType = {
stream: "stream";
value: "value";
};
export type IntentMap = {`;
intents.forEach(intent => {
const paramType = generateParamType(intent.params);
const responseType = generateResponseType(intent.outputSchema);
typeDefinitions += `
/** @id ${intent.id} - ${intent.description} */
"${intent.id}": {
name: "${intent.name}",
params: ${paramType},
response: ${responseType},
mode: "${intent.mode}",
description: "${intent.description}"
},`;
});
typeDefinitions = typeDefinitions.slice(0, -1); // Remove trailing comma
typeDefinitions += `}
export type IntentId = keyof IntentMap;
export type IntentName = IntentMap[IntentId]['name'];
export type IntentParams<T extends IntentId> = IntentMap[T]['params'];
export type IntentResponse<T extends IntentId> = IntentMap[T]['response'];
export type IntentMode<T extends IntentId> = IntentMap[T]['mode'];
// Filter intents by mode
export type StreamableIntentId = StreamIntent<IntentId>;
export type ValueIntentId = ValueIntent<IntentId>;
/** @deprecated Use StreamableIntentId or ValueIntentId instead */
export type ExecuteParams<T extends IntentId> = {
intentId: T;
params: IntentParams<T>;
};
// Add JSDoc comments for better IDE hints
/** Intent map for streaming operations */
export type StreamIntentMap = {
[K in StreamableIntentId]: IntentMap[K]
};
/** Intent map for value operations */
export type ValueIntentMap = {
[K in ValueIntentId]: IntentMap[K]
};
// Helper type to ensure proper distribution of conditional types
type DistributiveOmit<T, K extends keyof any> = T extends any
? Omit<T, K>
: never;
// More precise intent filtering types
export type StreamIntent<T extends IntentId> = T extends any
? IntentMap[T]['mode'] extends 'stream'
? T
: never
: never;
export type ValueIntent<T extends IntentId> = T extends any
? IntentMap[T]['mode'] extends 'value'
? T
: never
: never;`;
// Write to dist directory
const distTypesDir = path_1.default.join(__dirname, '../../dist/types');
if (!fs_1.default.existsSync(distTypesDir)) {
fs_1.default.mkdirSync(distTypesDir, { recursive: true });
}
fs_1.default.writeFileSync(path_1.default.join(distTypesDir, 'generated.d.ts'), typeDefinitions);
// Also write to src directory
fs_1.default.writeFileSync(path_1.default.join(__dirname, 'generated.ts'), typeDefinitions);
}
catch (error) {
console.error('Failed to generate type definitions:', error);
throw error;
}
}
function generateParamType(params) {
if (!params || Object.keys(params).length === 0) {
return '{}';
}
let paramType = '{\n';
for (const [key, value] of Object.entries(params)) {
// Handle restricted values
if (value.restrictedTo) {
// Create union type of allowed values
const allowedValues = value.restrictedTo.map((v) => `"${v}"`).join(' | ');
paramType += ` ${key}${value.nullable ? '?' : ''}: ${allowedValues};\n`;
}
else {
// Map API types to TypeScript types
const tsType = value.type === 'integer' ? 'number' : value.type;
paramType += ` ${key}${value.nullable ? '?' : ''}: ${tsType};\n`;
}
}
paramType += ' }';
return paramType;
}
function generateResponseType(schema) {
if (!schema)
return 'any';
return getTypeFromSchema(schema);
}
function getTypeFromSchema(schema) {
if (!schema)
return 'any';
switch (schema.type) {
case 'string':
return 'string';
case 'number':
return 'number';
case 'boolean':
return 'boolean';
case 'array':
return `Array<${getTypeFromSchema(schema.items)}>`;
case 'object':
if (!schema.properties)
return 'Record<string, any>';
let objType = '{\n';
for (const [key, prop] of Object.entries(schema.properties)) {
const isOptional = !schema.required?.includes(key);
objType += ` ${key}${isOptional ? '?' : ''}: ${getTypeFromSchema(prop)};\n`;
}
objType += ' }';
return objType;
default:
return 'any';
}
}