@suiteportal/generator 0.4.0 → 0.5.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.cjs +170 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +170 -28
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -80,6 +80,122 @@ function fieldTypeToTS(fieldType) {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
// src/emitters/type-emitter.ts
|
|
83
|
+
function fieldTypeToFilter(fieldType) {
|
|
84
|
+
switch (fieldType) {
|
|
85
|
+
case "string":
|
|
86
|
+
case "text":
|
|
87
|
+
case "richtext":
|
|
88
|
+
case "email":
|
|
89
|
+
case "url":
|
|
90
|
+
case "phone":
|
|
91
|
+
case "date":
|
|
92
|
+
case "datetime":
|
|
93
|
+
case "multiselect":
|
|
94
|
+
return { filterType: "StringFilter", shorthand: "string" };
|
|
95
|
+
case "integer":
|
|
96
|
+
case "float":
|
|
97
|
+
case "currency":
|
|
98
|
+
case "percent":
|
|
99
|
+
return { filterType: "NumberFilter", shorthand: "number" };
|
|
100
|
+
case "boolean":
|
|
101
|
+
return { filterType: "BooleanFilter", shorthand: "boolean" };
|
|
102
|
+
case "select":
|
|
103
|
+
return { filterType: "SelectFilter", shorthand: "string | number" };
|
|
104
|
+
case "unknown":
|
|
105
|
+
default:
|
|
106
|
+
return { filterType: "StringFilter", shorthand: "unknown" };
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function emitFilterTypes() {
|
|
110
|
+
return `/** String field filter operators. */
|
|
111
|
+
export interface StringFilter {
|
|
112
|
+
equals?: string | null;
|
|
113
|
+
not?: string | null;
|
|
114
|
+
in?: string[];
|
|
115
|
+
notIn?: string[];
|
|
116
|
+
gt?: string;
|
|
117
|
+
gte?: string;
|
|
118
|
+
lt?: string;
|
|
119
|
+
lte?: string;
|
|
120
|
+
contains?: string;
|
|
121
|
+
startsWith?: string;
|
|
122
|
+
endsWith?: string;
|
|
123
|
+
isNull?: boolean;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** Number field filter operators. */
|
|
127
|
+
export interface NumberFilter {
|
|
128
|
+
equals?: number | null;
|
|
129
|
+
not?: number | null;
|
|
130
|
+
in?: number[];
|
|
131
|
+
notIn?: number[];
|
|
132
|
+
gt?: number;
|
|
133
|
+
gte?: number;
|
|
134
|
+
lt?: number;
|
|
135
|
+
lte?: number;
|
|
136
|
+
isNull?: boolean;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** Boolean field filter operators. */
|
|
140
|
+
export interface BooleanFilter {
|
|
141
|
+
equals?: boolean | null;
|
|
142
|
+
not?: boolean | null;
|
|
143
|
+
isNull?: boolean;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** Select (string | number) field filter operators. */
|
|
147
|
+
export interface SelectFilter {
|
|
148
|
+
equals?: string | number | null;
|
|
149
|
+
not?: string | number | null;
|
|
150
|
+
in?: (string | number)[];
|
|
151
|
+
notIn?: (string | number)[];
|
|
152
|
+
gt?: string | number;
|
|
153
|
+
gte?: string | number;
|
|
154
|
+
lt?: string | number;
|
|
155
|
+
lte?: string | number;
|
|
156
|
+
isNull?: boolean;
|
|
157
|
+
}`;
|
|
158
|
+
}
|
|
159
|
+
function emitWhereInput(recordId, record) {
|
|
160
|
+
const name = toPascalCase(recordId);
|
|
161
|
+
const lines = [];
|
|
162
|
+
lines.push(`/** Where clause for ${record.label} queries. */`);
|
|
163
|
+
lines.push(`export interface ${name}WhereInput {`);
|
|
164
|
+
for (const [fieldId, field] of Object.entries(record.fields)) {
|
|
165
|
+
const { filterType, shorthand } = fieldTypeToFilter(field.type);
|
|
166
|
+
lines.push(` /** ${field.label} */`);
|
|
167
|
+
lines.push(` ${fieldId}?: ${shorthand} | ${filterType};`);
|
|
168
|
+
}
|
|
169
|
+
lines.push(` AND?: ${name}WhereInput[];`);
|
|
170
|
+
lines.push(` OR?: ${name}WhereInput[];`);
|
|
171
|
+
lines.push(` NOT?: ${name}WhereInput;`);
|
|
172
|
+
lines.push("}");
|
|
173
|
+
return lines.join("\n");
|
|
174
|
+
}
|
|
175
|
+
function emitSelectType(recordId, record) {
|
|
176
|
+
const name = toPascalCase(recordId);
|
|
177
|
+
const lines = [];
|
|
178
|
+
lines.push(`/** Field selection for ${record.label} queries. */`);
|
|
179
|
+
lines.push(`export interface ${name}Select {`);
|
|
180
|
+
for (const [fieldId, field] of Object.entries(record.fields)) {
|
|
181
|
+
lines.push(` /** ${field.label} */`);
|
|
182
|
+
lines.push(` ${fieldId}?: boolean;`);
|
|
183
|
+
}
|
|
184
|
+
lines.push("}");
|
|
185
|
+
return lines.join("\n");
|
|
186
|
+
}
|
|
187
|
+
function emitOrderByType(recordId, record) {
|
|
188
|
+
const name = toPascalCase(recordId);
|
|
189
|
+
const lines = [];
|
|
190
|
+
lines.push(`/** Order by clause for ${record.label} queries. */`);
|
|
191
|
+
lines.push(`export interface ${name}OrderByInput {`);
|
|
192
|
+
for (const [fieldId, field] of Object.entries(record.fields)) {
|
|
193
|
+
lines.push(` /** ${field.label} */`);
|
|
194
|
+
lines.push(` ${fieldId}?: 'asc' | 'desc';`);
|
|
195
|
+
}
|
|
196
|
+
lines.push("}");
|
|
197
|
+
return lines.join("\n");
|
|
198
|
+
}
|
|
83
199
|
function emitRecordInterface(recordId, record) {
|
|
84
200
|
const name = toPascalCase(recordId);
|
|
85
201
|
const fieldEntries = Object.entries(record.fields);
|
|
@@ -163,6 +279,10 @@ function emitTypes(schema) {
|
|
|
163
279
|
""
|
|
164
280
|
];
|
|
165
281
|
const recordEntries = Object.entries(schema.records);
|
|
282
|
+
if (recordEntries.length > 0) {
|
|
283
|
+
lines.push(emitFilterTypes());
|
|
284
|
+
lines.push("");
|
|
285
|
+
}
|
|
166
286
|
for (const [recordId, record] of recordEntries) {
|
|
167
287
|
lines.push(emitRecordInterface(recordId, record));
|
|
168
288
|
lines.push("");
|
|
@@ -175,6 +295,12 @@ function emitTypes(schema) {
|
|
|
175
295
|
lines.push("");
|
|
176
296
|
lines.push(emitUpdateInput(recordId, record));
|
|
177
297
|
lines.push("");
|
|
298
|
+
lines.push(emitWhereInput(recordId, record));
|
|
299
|
+
lines.push("");
|
|
300
|
+
lines.push(emitSelectType(recordId, record));
|
|
301
|
+
lines.push("");
|
|
302
|
+
lines.push(emitOrderByType(recordId, record));
|
|
303
|
+
lines.push("");
|
|
178
304
|
}
|
|
179
305
|
if (recordEntries.length > 0) {
|
|
180
306
|
const names = recordEntries.map(([id]) => `'${id}'`);
|
|
@@ -193,6 +319,21 @@ function emitTypes(schema) {
|
|
|
193
319
|
}
|
|
194
320
|
|
|
195
321
|
// src/emitters/client-emitter.ts
|
|
322
|
+
function emitDelegate(recordId) {
|
|
323
|
+
const name = toPascalCase(recordId);
|
|
324
|
+
const lines = [];
|
|
325
|
+
lines.push(`/** Typed delegate for ${name} records. */`);
|
|
326
|
+
lines.push(`export interface ${name}Delegate {`);
|
|
327
|
+
lines.push(` findMany(args?: { where?: ${name}WhereInput; select?: ${name}Select; orderBy?: ${name}OrderByInput; include?: IncludeInput; take?: number; skip?: number }): Promise<${name}[]>;`);
|
|
328
|
+
lines.push(` findFirst(args?: { where?: ${name}WhereInput; select?: ${name}Select; orderBy?: ${name}OrderByInput; include?: IncludeInput; skip?: number }): Promise<${name} | null>;`);
|
|
329
|
+
lines.push(` count(args?: { where?: ${name}WhereInput }): Promise<number>;`);
|
|
330
|
+
lines.push(` create(args: { data: ${name}CreateInput }): Promise<${name}>;`);
|
|
331
|
+
lines.push(` update(args: { where: { id: { equals: string | number } }; data: ${name}UpdateInput }): Promise<${name}>;`);
|
|
332
|
+
lines.push(` delete(args: { where: { id: { equals: string | number } } }): Promise<void>;`);
|
|
333
|
+
lines.push(` upsert(args: { where: { externalId: string }; data: ${name}CreateInput }): Promise<${name}>;`);
|
|
334
|
+
lines.push("}");
|
|
335
|
+
return lines.join("\n");
|
|
336
|
+
}
|
|
196
337
|
function emitClient(schema) {
|
|
197
338
|
const recordEntries = Object.entries(schema.records);
|
|
198
339
|
const typeImports = recordEntries.map(([id]) => toPascalCase(id));
|
|
@@ -205,41 +346,34 @@ function emitClient(schema) {
|
|
|
205
346
|
` SuitePortalClient as BaseClient,`,
|
|
206
347
|
` getClient as baseGetClient,`,
|
|
207
348
|
` destroySingleton,`,
|
|
208
|
-
` type FindManyArgs,`,
|
|
209
|
-
` type FindFirstArgs,`,
|
|
210
|
-
` type CountArgs,`,
|
|
211
|
-
` type CreateArgs,`,
|
|
212
|
-
` type UpdateArgs,`,
|
|
213
|
-
` type DeleteArgs,`,
|
|
214
|
-
` type UpsertArgs,`,
|
|
215
349
|
` type IncludeInput,`,
|
|
216
350
|
` type ClientOptions,`,
|
|
217
351
|
`} from 'suiteportal';`
|
|
218
352
|
];
|
|
219
353
|
if (typeImports.length > 0) {
|
|
220
|
-
const
|
|
354
|
+
const perRecordImports = recordEntries.flatMap(([id]) => {
|
|
221
355
|
const name = toPascalCase(id);
|
|
222
|
-
return [
|
|
356
|
+
return [
|
|
357
|
+
name,
|
|
358
|
+
`${name}CreateInput`,
|
|
359
|
+
`${name}UpdateInput`,
|
|
360
|
+
`${name}WhereInput`,
|
|
361
|
+
`${name}Select`,
|
|
362
|
+
`${name}OrderByInput`
|
|
363
|
+
];
|
|
223
364
|
});
|
|
224
|
-
lines.push(`import type { ${
|
|
365
|
+
lines.push(`import type { ${perRecordImports.join(", ")} } from './types';`);
|
|
225
366
|
}
|
|
226
367
|
lines.push("");
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
lines.push(" count(args?: CountArgs): Promise<number>;");
|
|
232
|
-
lines.push(" create(args: CreateArgs<TCreate>): Promise<T>;");
|
|
233
|
-
lines.push(" update(args: UpdateArgs<TUpdate>): Promise<T>;");
|
|
234
|
-
lines.push(" delete(args: DeleteArgs): Promise<void>;");
|
|
235
|
-
lines.push(" upsert(args: UpsertArgs<TCreate>): Promise<T>;");
|
|
236
|
-
lines.push("}");
|
|
237
|
-
lines.push("");
|
|
368
|
+
for (const [recordId] of recordEntries) {
|
|
369
|
+
lines.push(emitDelegate(recordId));
|
|
370
|
+
lines.push("");
|
|
371
|
+
}
|
|
238
372
|
lines.push("/** Typed SuitePortal client with per-record delegates. */");
|
|
239
373
|
lines.push("export interface SuitePortalClient {");
|
|
240
374
|
for (const [recordId] of recordEntries) {
|
|
241
375
|
const typeName = toPascalCase(recordId);
|
|
242
|
-
lines.push(` ${recordId}:
|
|
376
|
+
lines.push(` ${recordId}: ${typeName}Delegate;`);
|
|
243
377
|
}
|
|
244
378
|
lines.push(" $queryRaw<T = Record<string, unknown>>(sql: string): Promise<T[]>;");
|
|
245
379
|
lines.push(" $disconnect(): void;");
|
|
@@ -272,7 +406,7 @@ function emitClient(schema) {
|
|
|
272
406
|
lines.push("");
|
|
273
407
|
lines.push("export { destroySingleton };");
|
|
274
408
|
lines.push("");
|
|
275
|
-
lines.push("export type {
|
|
409
|
+
lines.push("export type { IncludeInput } from 'suiteportal';");
|
|
276
410
|
lines.push("");
|
|
277
411
|
return lines.join("\n");
|
|
278
412
|
}
|
|
@@ -287,15 +421,23 @@ function emitBarrel(schema) {
|
|
|
287
421
|
""
|
|
288
422
|
];
|
|
289
423
|
if (typeNames.length > 0) {
|
|
290
|
-
const
|
|
424
|
+
const perRecordTypes = recordEntries.flatMap(([id]) => {
|
|
291
425
|
const name = toPascalCase(id);
|
|
292
|
-
return [
|
|
426
|
+
return [
|
|
427
|
+
`${name}CreateInput`,
|
|
428
|
+
`${name}UpdateInput`,
|
|
429
|
+
`${name}WhereInput`,
|
|
430
|
+
`${name}Select`,
|
|
431
|
+
`${name}OrderByInput`
|
|
432
|
+
];
|
|
293
433
|
});
|
|
294
|
-
lines.push(`export type { ${[...typeNames, ...
|
|
434
|
+
lines.push(`export type { ${[...typeNames, ...perRecordTypes].join(", ")}, RecordTypeId, RecordTypeMap } from './types';`);
|
|
435
|
+
lines.push(`export type { StringFilter, NumberFilter, BooleanFilter, SelectFilter } from './types';`);
|
|
295
436
|
}
|
|
296
|
-
|
|
437
|
+
const delegateTypes = recordEntries.map(([id]) => `${toPascalCase(id)}Delegate`);
|
|
438
|
+
lines.push(`export type { SuitePortalClient${delegateTypes.length > 0 ? ", " + delegateTypes.join(", ") : ""} } from './client';`);
|
|
297
439
|
lines.push(`export { createClient } from './client';`);
|
|
298
|
-
lines.push(`export type {
|
|
440
|
+
lines.push(`export type { IncludeInput } from './client';`);
|
|
299
441
|
lines.push("");
|
|
300
442
|
return lines.join("\n");
|
|
301
443
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/generate.ts","../src/schema-reader.ts","../src/naming.ts","../src/emitters/type-emitter.ts","../src/emitters/client-emitter.ts","../src/emitters/barrel-emitter.ts"],"sourcesContent":["// Generator\nexport { generate } from './generate.js';\n\n// Schema reader\nexport { readSchema } from './schema-reader.js';\n\n// Naming utilities\nexport { toPascalCase, fieldTypeToTS } from './naming.js';\n\n// Emitters\nexport { emitTypes } from './emitters/type-emitter.js';\nexport { emitClient } from './emitters/client-emitter.js';\nexport { emitBarrel } from './emitters/barrel-emitter.js';\n\n// Types\nexport type { GenerateOptions, GenerateResult } from './types.js';\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { readSchema } from './schema-reader.js';\nimport { emitTypes } from './emitters/type-emitter.js';\nimport { emitClient } from './emitters/client-emitter.js';\nimport { emitBarrel } from './emitters/barrel-emitter.js';\nimport type { GenerateOptions, GenerateResult } from './types.js';\n\nconst DEFAULT_SCHEMA_PATH = '.suiteportal/schema.json';\nconst DEFAULT_OUTPUT_DIR = '.suiteportal/client';\n\n/**\n * Generate typed client code from a schema.json file.\n *\n * Reads the introspected schema, emits TypeScript interfaces for all records,\n * a typed client wrapper, and a barrel export file.\n */\nexport async function generate(options?: GenerateOptions): Promise<GenerateResult> {\n const schemaPath = options?.schemaPath ?? DEFAULT_SCHEMA_PATH;\n const outputDir = options?.outputDir ?? DEFAULT_OUTPUT_DIR;\n\n // Read schema\n const schema = await readSchema(schemaPath);\n\n // Ensure output directory exists\n await mkdir(outputDir, { recursive: true });\n\n // Generate files\n const typesContent = emitTypes(schema);\n const clientContent = emitClient(schema);\n const barrelContent = emitBarrel(schema);\n\n // Write files\n const typesPath = join(outputDir, 'types.ts');\n const clientPath = join(outputDir, 'client.ts');\n const barrelPath = join(outputDir, 'index.ts');\n\n await Promise.all([\n writeFile(typesPath, typesContent, 'utf-8'),\n writeFile(clientPath, clientContent, 'utf-8'),\n writeFile(barrelPath, barrelContent, 'utf-8'),\n ]);\n\n // Compute stats\n const recordEntries = Object.entries(schema.records);\n const fieldCount = recordEntries.reduce(\n (sum, [, record]) => sum + Object.keys(record.fields).length,\n 0,\n );\n\n return {\n recordCount: recordEntries.length,\n fieldCount,\n files: [typesPath, clientPath, barrelPath],\n outputDir,\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport type { NormalizedSchema } from '@suiteportal/introspector';\n\n/**\n * Read and parse a schema.json file.\n */\nexport async function readSchema(schemaPath: string): Promise<NormalizedSchema> {\n const raw = await readFile(schemaPath, 'utf-8');\n const schema = JSON.parse(raw) as NormalizedSchema;\n\n if (!schema.records || typeof schema.records !== 'object') {\n throw new Error(`Invalid schema: missing \"records\" in ${schemaPath}`);\n }\n\n return schema;\n}\n","import type { FieldType } from '@suiteportal/introspector';\n\n/**\n * Convert a record ID to PascalCase for use as a TypeScript interface name.\n * Examples:\n * 'customer' → 'Customer'\n * 'salesorder' → 'Salesorder'\n * 'customrecord_mytype' → 'CustomrecordMytype'\n */\nexport function toPascalCase(name: string): string {\n return name\n .split('_')\n .map((part) => (part.length > 0 ? part[0]!.toUpperCase() + part.slice(1).toLowerCase() : ''))\n .join('');\n}\n\n/**\n * Map a normalized FieldType to its TypeScript type representation.\n */\nexport function fieldTypeToTS(fieldType: FieldType): string {\n switch (fieldType) {\n case 'string':\n case 'text':\n case 'richtext':\n case 'email':\n case 'url':\n case 'phone':\n return 'string';\n\n case 'integer':\n case 'float':\n case 'currency':\n case 'percent':\n return 'number';\n\n case 'boolean':\n return 'boolean';\n\n case 'date':\n case 'datetime':\n return 'string'; // SuiteQL returns date strings\n\n case 'select':\n return 'string | number';\n\n case 'multiselect':\n return 'string';\n\n case 'unknown':\n default:\n return 'unknown';\n }\n}\n","import type { NormalizedSchema, RecordDefinition, SublistDefinition } from '@suiteportal/introspector';\nimport { toPascalCase, fieldTypeToTS } from '../naming.js';\n\n/**\n * Emit a TypeScript interface for a single record.\n */\nfunction emitRecordInterface(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const fieldEntries = Object.entries(record.fields);\n const fieldCount = fieldEntries.length;\n\n const lines: string[] = [];\n lines.push(`/** ${record.label} — ${fieldCount} fields */`);\n lines.push(`export interface ${name} {`);\n\n for (const [fieldId, field] of fieldEntries) {\n const tsType = fieldTypeToTS(field.type);\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: ${tsType};`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit a TypeScript interface for a single sublist item.\n */\nfunction emitSublistItem(recordId: string, sublistId: string, sublist: SublistDefinition): string {\n const recordName = toPascalCase(recordId);\n const sublistName = toPascalCase(sublistId);\n const interfaceName = `${recordName}${sublistName}Item`;\n const fieldEntries = Object.entries(sublist.fields);\n\n const lines: string[] = [];\n lines.push(`/** ${sublist.label} line item on ${recordName}. */`);\n lines.push(`export interface ${interfaceName} {`);\n\n for (const [fieldId, field] of fieldEntries) {\n const tsType = fieldTypeToTS(field.type);\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: ${tsType};`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit a CreateInput interface for a record.\n * Excludes readOnly fields and `id`. Required writable fields are non-optional.\n */\nfunction emitCreateInput(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const sublistKeys = new Set(Object.keys(record.sublists ?? {}));\n const lines: string[] = [];\n lines.push(`/** Fields for creating a ${record.label}. */`);\n lines.push(`export interface ${name}CreateInput {`);\n\n for (const [fieldId, field] of Object.entries(record.fields)) {\n if (fieldId === 'id' || field.readOnly) continue;\n // Skip fields that collide with sublist names — sublist takes precedence\n if (sublistKeys.has(fieldId)) continue;\n const tsType = fieldTypeToTS(field.type);\n const optional = field.required ? '' : '?';\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}${optional}: ${tsType};`);\n }\n\n // Sublist fields\n const sublistEntries = Object.entries(record.sublists ?? {});\n for (const [sublistId] of sublistEntries) {\n const itemType = `${name}${toPascalCase(sublistId)}Item`;\n lines.push(` /** ${toPascalCase(sublistId)} sublist. */`);\n lines.push(` ${sublistId}?: { items: ${itemType}[] };`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit an UpdateInput interface for a record.\n * Excludes readOnly fields and `id`. All fields are optional.\n */\nfunction emitUpdateInput(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const sublistKeys = new Set(Object.keys(record.sublists ?? {}));\n const lines: string[] = [];\n lines.push(`/** Fields for updating a ${record.label}. */`);\n lines.push(`export interface ${name}UpdateInput {`);\n\n for (const [fieldId, field] of Object.entries(record.fields)) {\n if (fieldId === 'id' || field.readOnly) continue;\n // Skip fields that collide with sublist names — sublist takes precedence\n if (sublistKeys.has(fieldId)) continue;\n const tsType = fieldTypeToTS(field.type);\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: ${tsType};`);\n }\n\n // Sublist fields\n const sublistEntries = Object.entries(record.sublists ?? {});\n for (const [sublistId] of sublistEntries) {\n const itemType = `${name}${toPascalCase(sublistId)}Item`;\n lines.push(` /** ${toPascalCase(sublistId)} sublist. */`);\n lines.push(` ${sublistId}?: { items: ${itemType}[] };`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit the full types.ts file content from a schema.\n */\nexport function emitTypes(schema: NormalizedSchema): string {\n const lines: string[] = [\n '// Auto-generated by @suiteportal/generator — DO NOT EDIT',\n `// Generated at: ${new Date().toISOString()}`,\n '',\n ];\n\n const recordEntries = Object.entries(schema.records);\n\n for (const [recordId, record] of recordEntries) {\n lines.push(emitRecordInterface(recordId, record));\n lines.push('');\n\n // Emit sublist item interfaces before Create/UpdateInput (they reference the item types)\n const sublistEntries = Object.entries(record.sublists ?? {});\n for (const [sublistId, sublist] of sublistEntries) {\n lines.push(emitSublistItem(recordId, sublistId, sublist));\n lines.push('');\n }\n\n lines.push(emitCreateInput(recordId, record));\n lines.push('');\n lines.push(emitUpdateInput(recordId, record));\n lines.push('');\n }\n\n // Export a union type of all record names\n if (recordEntries.length > 0) {\n const names = recordEntries.map(([id]) => `'${id}'`);\n lines.push(`/** All available record type IDs. */`);\n lines.push(`export type RecordTypeId = ${names.join(' | ')};`);\n lines.push('');\n\n // Record type map\n lines.push(`/** Map of record type IDs to their TypeScript interfaces. */`);\n lines.push(`export interface RecordTypeMap {`);\n for (const [recordId] of recordEntries) {\n lines.push(` ${recordId}: ${toPascalCase(recordId)};`);\n }\n lines.push('}');\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","import type { NormalizedSchema } from '@suiteportal/introspector';\nimport { toPascalCase } from '../naming.js';\n\n/**\n * Emit the client.ts file content — a typed wrapper around the base SuitePortalClient.\n */\nexport function emitClient(schema: NormalizedSchema): string {\n const recordEntries = Object.entries(schema.records);\n const typeImports = recordEntries.map(([id]) => toPascalCase(id));\n\n const lines: string[] = [\n '// Auto-generated by suiteportal — DO NOT EDIT',\n `// Generated at: ${new Date().toISOString()}`,\n '',\n `import type { NetSuiteConfig } from 'suiteportal';`,\n `import {`,\n ` SuitePortalClient as BaseClient,`,\n ` getClient as baseGetClient,`,\n ` destroySingleton,`,\n ` type FindManyArgs,`,\n ` type FindFirstArgs,`,\n ` type CountArgs,`,\n ` type CreateArgs,`,\n ` type UpdateArgs,`,\n ` type DeleteArgs,`,\n ` type UpsertArgs,`,\n ` type IncludeInput,`,\n ` type ClientOptions,`,\n `} from 'suiteportal';`,\n ];\n\n if (typeImports.length > 0) {\n const inputImports = recordEntries.flatMap(([id]) => {\n const name = toPascalCase(id);\n return [`${name}CreateInput`, `${name}UpdateInput`];\n });\n lines.push(`import type { ${[...typeImports, ...inputImports].join(', ')} } from './types';`);\n }\n\n lines.push('');\n\n // TypedModelDelegate interface\n lines.push('/** A typed model delegate for a specific record type. */');\n lines.push('export interface TypedModelDelegate<T, TCreate = Record<string, unknown>, TUpdate = Record<string, unknown>> {');\n lines.push(' findMany(args?: FindManyArgs): Promise<T[]>;');\n lines.push(' findFirst(args?: FindFirstArgs): Promise<T | null>;');\n lines.push(' count(args?: CountArgs): Promise<number>;');\n lines.push(' create(args: CreateArgs<TCreate>): Promise<T>;');\n lines.push(' update(args: UpdateArgs<TUpdate>): Promise<T>;');\n lines.push(' delete(args: DeleteArgs): Promise<void>;');\n lines.push(' upsert(args: UpsertArgs<TCreate>): Promise<T>;');\n lines.push('}');\n lines.push('');\n\n // SuitePortalClient interface\n lines.push('/** Typed SuitePortal client with per-record delegates. */');\n lines.push('export interface SuitePortalClient {');\n\n for (const [recordId] of recordEntries) {\n const typeName = toPascalCase(recordId);\n lines.push(` ${recordId}: TypedModelDelegate<${typeName}, ${typeName}CreateInput, ${typeName}UpdateInput>;`);\n }\n\n lines.push(' $queryRaw<T = Record<string, unknown>>(sql: string): Promise<T[]>;');\n lines.push(' $disconnect(): void;');\n lines.push(' $loadSchema(): Promise<void>;');\n lines.push('}');\n lines.push('');\n\n // createClient function\n lines.push('/**');\n lines.push(' * Create a typed SuitePortal client.');\n lines.push(' * Loads schema.json and provides typed access to all record types.');\n lines.push(' */');\n lines.push('export async function createClient(');\n lines.push(' config: NetSuiteConfig,');\n lines.push(' options?: ClientOptions,');\n lines.push('): Promise<SuitePortalClient> {');\n lines.push(' const client = new BaseClient(config, options);');\n lines.push(' await client.$loadSchema();');\n lines.push(' return client as unknown as SuitePortalClient;');\n lines.push('}');\n lines.push('');\n\n // getClient singleton\n lines.push('/**');\n lines.push(' * Get (or create) a process-wide singleton typed client.');\n lines.push(' * Safe for use across server components, server actions, and API routes.');\n lines.push(' */');\n lines.push('export async function getClient(');\n lines.push(' config: NetSuiteConfig,');\n lines.push(' options?: ClientOptions,');\n lines.push('): Promise<SuitePortalClient> {');\n lines.push(' return baseGetClient(config, options) as Promise<unknown> as Promise<SuitePortalClient>;');\n lines.push('}');\n lines.push('');\n\n // Re-export destroySingleton\n lines.push('export { destroySingleton };');\n lines.push('');\n\n // Re-export types for convenience\n lines.push('export type { FindManyArgs, FindFirstArgs, CountArgs, CreateArgs, UpdateArgs, DeleteArgs, UpsertArgs, IncludeInput } from \\'suiteportal\\';');\n lines.push('');\n\n return lines.join('\\n');\n}\n","import type { NormalizedSchema } from '@suiteportal/introspector';\nimport { toPascalCase } from '../naming.js';\n\n/**\n * Emit the index.ts barrel export file content.\n */\nexport function emitBarrel(schema: NormalizedSchema): string {\n const recordEntries = Object.entries(schema.records);\n const typeNames = recordEntries.map(([id]) => toPascalCase(id));\n\n const lines: string[] = [\n '// Auto-generated by @suiteportal/generator — DO NOT EDIT',\n `// Generated at: ${new Date().toISOString()}`,\n '',\n ];\n\n // Type exports\n if (typeNames.length > 0) {\n const inputTypes = recordEntries.flatMap(([id]) => {\n const name = toPascalCase(id);\n return [`${name}CreateInput`, `${name}UpdateInput`];\n });\n lines.push(`export type { ${[...typeNames, ...inputTypes].join(', ')}, RecordTypeId, RecordTypeMap } from './types';`);\n }\n\n // Client exports\n lines.push(`export type { SuitePortalClient, TypedModelDelegate } from './client';`);\n lines.push(`export { createClient } from './client';`);\n lines.push(`export type { FindManyArgs, FindFirstArgs, CountArgs, CreateArgs, UpdateArgs, DeleteArgs, IncludeInput } from './client';`);\n lines.push('');\n\n return lines.join('\\n');\n}\n"],"mappings":"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","names":["import_promises"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/generate.ts","../src/schema-reader.ts","../src/naming.ts","../src/emitters/type-emitter.ts","../src/emitters/client-emitter.ts","../src/emitters/barrel-emitter.ts"],"sourcesContent":["// Generator\nexport { generate } from './generate.js';\n\n// Schema reader\nexport { readSchema } from './schema-reader.js';\n\n// Naming utilities\nexport { toPascalCase, fieldTypeToTS } from './naming.js';\n\n// Emitters\nexport { emitTypes } from './emitters/type-emitter.js';\nexport { emitClient } from './emitters/client-emitter.js';\nexport { emitBarrel } from './emitters/barrel-emitter.js';\n\n// Types\nexport type { GenerateOptions, GenerateResult } from './types.js';\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { readSchema } from './schema-reader.js';\nimport { emitTypes } from './emitters/type-emitter.js';\nimport { emitClient } from './emitters/client-emitter.js';\nimport { emitBarrel } from './emitters/barrel-emitter.js';\nimport type { GenerateOptions, GenerateResult } from './types.js';\n\nconst DEFAULT_SCHEMA_PATH = '.suiteportal/schema.json';\nconst DEFAULT_OUTPUT_DIR = '.suiteportal/client';\n\n/**\n * Generate typed client code from a schema.json file.\n *\n * Reads the introspected schema, emits TypeScript interfaces for all records,\n * a typed client wrapper, and a barrel export file.\n */\nexport async function generate(options?: GenerateOptions): Promise<GenerateResult> {\n const schemaPath = options?.schemaPath ?? DEFAULT_SCHEMA_PATH;\n const outputDir = options?.outputDir ?? DEFAULT_OUTPUT_DIR;\n\n // Read schema\n const schema = await readSchema(schemaPath);\n\n // Ensure output directory exists\n await mkdir(outputDir, { recursive: true });\n\n // Generate files\n const typesContent = emitTypes(schema);\n const clientContent = emitClient(schema);\n const barrelContent = emitBarrel(schema);\n\n // Write files\n const typesPath = join(outputDir, 'types.ts');\n const clientPath = join(outputDir, 'client.ts');\n const barrelPath = join(outputDir, 'index.ts');\n\n await Promise.all([\n writeFile(typesPath, typesContent, 'utf-8'),\n writeFile(clientPath, clientContent, 'utf-8'),\n writeFile(barrelPath, barrelContent, 'utf-8'),\n ]);\n\n // Compute stats\n const recordEntries = Object.entries(schema.records);\n const fieldCount = recordEntries.reduce(\n (sum, [, record]) => sum + Object.keys(record.fields).length,\n 0,\n );\n\n return {\n recordCount: recordEntries.length,\n fieldCount,\n files: [typesPath, clientPath, barrelPath],\n outputDir,\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport type { NormalizedSchema } from '@suiteportal/introspector';\n\n/**\n * Read and parse a schema.json file.\n */\nexport async function readSchema(schemaPath: string): Promise<NormalizedSchema> {\n const raw = await readFile(schemaPath, 'utf-8');\n const schema = JSON.parse(raw) as NormalizedSchema;\n\n if (!schema.records || typeof schema.records !== 'object') {\n throw new Error(`Invalid schema: missing \"records\" in ${schemaPath}`);\n }\n\n return schema;\n}\n","import type { FieldType } from '@suiteportal/introspector';\n\n/**\n * Convert a record ID to PascalCase for use as a TypeScript interface name.\n * Examples:\n * 'customer' → 'Customer'\n * 'salesorder' → 'Salesorder'\n * 'customrecord_mytype' → 'CustomrecordMytype'\n */\nexport function toPascalCase(name: string): string {\n return name\n .split('_')\n .map((part) => (part.length > 0 ? part[0]!.toUpperCase() + part.slice(1).toLowerCase() : ''))\n .join('');\n}\n\n/**\n * Map a normalized FieldType to its TypeScript type representation.\n */\nexport function fieldTypeToTS(fieldType: FieldType): string {\n switch (fieldType) {\n case 'string':\n case 'text':\n case 'richtext':\n case 'email':\n case 'url':\n case 'phone':\n return 'string';\n\n case 'integer':\n case 'float':\n case 'currency':\n case 'percent':\n return 'number';\n\n case 'boolean':\n return 'boolean';\n\n case 'date':\n case 'datetime':\n return 'string'; // SuiteQL returns date strings\n\n case 'select':\n return 'string | number';\n\n case 'multiselect':\n return 'string';\n\n case 'unknown':\n default:\n return 'unknown';\n }\n}\n","import type { NormalizedSchema, RecordDefinition, FieldDefinition, SublistDefinition, FieldType } from '@suiteportal/introspector';\nimport { toPascalCase, fieldTypeToTS } from '../naming.js';\n\n/**\n * Map a FieldType to its filter type name and shorthand value type.\n */\nfunction fieldTypeToFilter(fieldType: FieldType): { filterType: string; shorthand: string } {\n switch (fieldType) {\n case 'string':\n case 'text':\n case 'richtext':\n case 'email':\n case 'url':\n case 'phone':\n case 'date':\n case 'datetime':\n case 'multiselect':\n return { filterType: 'StringFilter', shorthand: 'string' };\n\n case 'integer':\n case 'float':\n case 'currency':\n case 'percent':\n return { filterType: 'NumberFilter', shorthand: 'number' };\n\n case 'boolean':\n return { filterType: 'BooleanFilter', shorthand: 'boolean' };\n\n case 'select':\n return { filterType: 'SelectFilter', shorthand: 'string | number' };\n\n case 'unknown':\n default:\n return { filterType: 'StringFilter', shorthand: 'unknown' };\n }\n}\n\n/**\n * Emit shared filter type interfaces used by all per-record WhereInput types.\n */\nfunction emitFilterTypes(): string {\n return `/** String field filter operators. */\nexport interface StringFilter {\n equals?: string | null;\n not?: string | null;\n in?: string[];\n notIn?: string[];\n gt?: string;\n gte?: string;\n lt?: string;\n lte?: string;\n contains?: string;\n startsWith?: string;\n endsWith?: string;\n isNull?: boolean;\n}\n\n/** Number field filter operators. */\nexport interface NumberFilter {\n equals?: number | null;\n not?: number | null;\n in?: number[];\n notIn?: number[];\n gt?: number;\n gte?: number;\n lt?: number;\n lte?: number;\n isNull?: boolean;\n}\n\n/** Boolean field filter operators. */\nexport interface BooleanFilter {\n equals?: boolean | null;\n not?: boolean | null;\n isNull?: boolean;\n}\n\n/** Select (string | number) field filter operators. */\nexport interface SelectFilter {\n equals?: string | number | null;\n not?: string | number | null;\n in?: (string | number)[];\n notIn?: (string | number)[];\n gt?: string | number;\n gte?: string | number;\n lt?: string | number;\n lte?: string | number;\n isNull?: boolean;\n}`;\n}\n\n/**\n * Emit a per-record WhereInput type with typed fields.\n */\nfunction emitWhereInput(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const lines: string[] = [];\n lines.push(`/** Where clause for ${record.label} queries. */`);\n lines.push(`export interface ${name}WhereInput {`);\n\n for (const [fieldId, field] of Object.entries(record.fields)) {\n const { filterType, shorthand } = fieldTypeToFilter(field.type);\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: ${shorthand} | ${filterType};`);\n }\n\n lines.push(` AND?: ${name}WhereInput[];`);\n lines.push(` OR?: ${name}WhereInput[];`);\n lines.push(` NOT?: ${name}WhereInput;`);\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit a per-record Select type.\n */\nfunction emitSelectType(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const lines: string[] = [];\n lines.push(`/** Field selection for ${record.label} queries. */`);\n lines.push(`export interface ${name}Select {`);\n\n for (const [fieldId, field] of Object.entries(record.fields)) {\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: boolean;`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit a per-record OrderByInput type.\n */\nfunction emitOrderByType(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const lines: string[] = [];\n lines.push(`/** Order by clause for ${record.label} queries. */`);\n lines.push(`export interface ${name}OrderByInput {`);\n\n for (const [fieldId, field] of Object.entries(record.fields)) {\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: 'asc' | 'desc';`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit a TypeScript interface for a single record.\n */\nfunction emitRecordInterface(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const fieldEntries = Object.entries(record.fields);\n const fieldCount = fieldEntries.length;\n\n const lines: string[] = [];\n lines.push(`/** ${record.label} — ${fieldCount} fields */`);\n lines.push(`export interface ${name} {`);\n\n for (const [fieldId, field] of fieldEntries) {\n const tsType = fieldTypeToTS(field.type);\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: ${tsType};`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit a TypeScript interface for a single sublist item.\n */\nfunction emitSublistItem(recordId: string, sublistId: string, sublist: SublistDefinition): string {\n const recordName = toPascalCase(recordId);\n const sublistName = toPascalCase(sublistId);\n const interfaceName = `${recordName}${sublistName}Item`;\n const fieldEntries = Object.entries(sublist.fields);\n\n const lines: string[] = [];\n lines.push(`/** ${sublist.label} line item on ${recordName}. */`);\n lines.push(`export interface ${interfaceName} {`);\n\n for (const [fieldId, field] of fieldEntries) {\n const tsType = fieldTypeToTS(field.type);\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: ${tsType};`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit a CreateInput interface for a record.\n * Excludes readOnly fields and `id`. Required writable fields are non-optional.\n */\nfunction emitCreateInput(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const sublistKeys = new Set(Object.keys(record.sublists ?? {}));\n const lines: string[] = [];\n lines.push(`/** Fields for creating a ${record.label}. */`);\n lines.push(`export interface ${name}CreateInput {`);\n\n for (const [fieldId, field] of Object.entries(record.fields)) {\n if (fieldId === 'id' || field.readOnly) continue;\n // Skip fields that collide with sublist names — sublist takes precedence\n if (sublistKeys.has(fieldId)) continue;\n const tsType = fieldTypeToTS(field.type);\n const optional = field.required ? '' : '?';\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}${optional}: ${tsType};`);\n }\n\n // Sublist fields\n const sublistEntries = Object.entries(record.sublists ?? {});\n for (const [sublistId] of sublistEntries) {\n const itemType = `${name}${toPascalCase(sublistId)}Item`;\n lines.push(` /** ${toPascalCase(sublistId)} sublist. */`);\n lines.push(` ${sublistId}?: { items: ${itemType}[] };`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit an UpdateInput interface for a record.\n * Excludes readOnly fields and `id`. All fields are optional.\n */\nfunction emitUpdateInput(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const sublistKeys = new Set(Object.keys(record.sublists ?? {}));\n const lines: string[] = [];\n lines.push(`/** Fields for updating a ${record.label}. */`);\n lines.push(`export interface ${name}UpdateInput {`);\n\n for (const [fieldId, field] of Object.entries(record.fields)) {\n if (fieldId === 'id' || field.readOnly) continue;\n // Skip fields that collide with sublist names — sublist takes precedence\n if (sublistKeys.has(fieldId)) continue;\n const tsType = fieldTypeToTS(field.type);\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: ${tsType};`);\n }\n\n // Sublist fields\n const sublistEntries = Object.entries(record.sublists ?? {});\n for (const [sublistId] of sublistEntries) {\n const itemType = `${name}${toPascalCase(sublistId)}Item`;\n lines.push(` /** ${toPascalCase(sublistId)} sublist. */`);\n lines.push(` ${sublistId}?: { items: ${itemType}[] };`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit the full types.ts file content from a schema.\n */\nexport function emitTypes(schema: NormalizedSchema): string {\n const lines: string[] = [\n '// Auto-generated by @suiteportal/generator — DO NOT EDIT',\n `// Generated at: ${new Date().toISOString()}`,\n '',\n ];\n\n const recordEntries = Object.entries(schema.records);\n\n // Emit shared filter types first (used by all WhereInput types)\n if (recordEntries.length > 0) {\n lines.push(emitFilterTypes());\n lines.push('');\n }\n\n for (const [recordId, record] of recordEntries) {\n lines.push(emitRecordInterface(recordId, record));\n lines.push('');\n\n // Emit sublist item interfaces before Create/UpdateInput (they reference the item types)\n const sublistEntries = Object.entries(record.sublists ?? {});\n for (const [sublistId, sublist] of sublistEntries) {\n lines.push(emitSublistItem(recordId, sublistId, sublist));\n lines.push('');\n }\n\n lines.push(emitCreateInput(recordId, record));\n lines.push('');\n lines.push(emitUpdateInput(recordId, record));\n lines.push('');\n\n // Emit per-record query types (WhereInput, Select, OrderByInput)\n lines.push(emitWhereInput(recordId, record));\n lines.push('');\n lines.push(emitSelectType(recordId, record));\n lines.push('');\n lines.push(emitOrderByType(recordId, record));\n lines.push('');\n }\n\n // Export a union type of all record names\n if (recordEntries.length > 0) {\n const names = recordEntries.map(([id]) => `'${id}'`);\n lines.push(`/** All available record type IDs. */`);\n lines.push(`export type RecordTypeId = ${names.join(' | ')};`);\n lines.push('');\n\n // Record type map\n lines.push(`/** Map of record type IDs to their TypeScript interfaces. */`);\n lines.push(`export interface RecordTypeMap {`);\n for (const [recordId] of recordEntries) {\n lines.push(` ${recordId}: ${toPascalCase(recordId)};`);\n }\n lines.push('}');\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","import type { NormalizedSchema } from '@suiteportal/introspector';\nimport { toPascalCase } from '../naming.js';\n\n/**\n * Emit a per-record delegate interface with fully typed query args.\n */\nfunction emitDelegate(recordId: string): string {\n const name = toPascalCase(recordId);\n const lines: string[] = [];\n lines.push(`/** Typed delegate for ${name} records. */`);\n lines.push(`export interface ${name}Delegate {`);\n lines.push(` findMany(args?: { where?: ${name}WhereInput; select?: ${name}Select; orderBy?: ${name}OrderByInput; include?: IncludeInput; take?: number; skip?: number }): Promise<${name}[]>;`);\n lines.push(` findFirst(args?: { where?: ${name}WhereInput; select?: ${name}Select; orderBy?: ${name}OrderByInput; include?: IncludeInput; skip?: number }): Promise<${name} | null>;`);\n lines.push(` count(args?: { where?: ${name}WhereInput }): Promise<number>;`);\n lines.push(` create(args: { data: ${name}CreateInput }): Promise<${name}>;`);\n lines.push(` update(args: { where: { id: { equals: string | number } }; data: ${name}UpdateInput }): Promise<${name}>;`);\n lines.push(` delete(args: { where: { id: { equals: string | number } } }): Promise<void>;`);\n lines.push(` upsert(args: { where: { externalId: string }; data: ${name}CreateInput }): Promise<${name}>;`);\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit the client.ts file content — a typed wrapper around the base SuitePortalClient.\n */\nexport function emitClient(schema: NormalizedSchema): string {\n const recordEntries = Object.entries(schema.records);\n const typeImports = recordEntries.map(([id]) => toPascalCase(id));\n\n const lines: string[] = [\n '// Auto-generated by suiteportal — DO NOT EDIT',\n `// Generated at: ${new Date().toISOString()}`,\n '',\n `import type { NetSuiteConfig } from 'suiteportal';`,\n `import {`,\n ` SuitePortalClient as BaseClient,`,\n ` getClient as baseGetClient,`,\n ` destroySingleton,`,\n ` type IncludeInput,`,\n ` type ClientOptions,`,\n `} from 'suiteportal';`,\n ];\n\n if (typeImports.length > 0) {\n const perRecordImports = recordEntries.flatMap(([id]) => {\n const name = toPascalCase(id);\n return [\n name,\n `${name}CreateInput`,\n `${name}UpdateInput`,\n `${name}WhereInput`,\n `${name}Select`,\n `${name}OrderByInput`,\n ];\n });\n lines.push(`import type { ${perRecordImports.join(', ')} } from './types';`);\n }\n\n lines.push('');\n\n // Per-record delegate interfaces\n for (const [recordId] of recordEntries) {\n lines.push(emitDelegate(recordId));\n lines.push('');\n }\n\n // SuitePortalClient interface\n lines.push('/** Typed SuitePortal client with per-record delegates. */');\n lines.push('export interface SuitePortalClient {');\n\n for (const [recordId] of recordEntries) {\n const typeName = toPascalCase(recordId);\n lines.push(` ${recordId}: ${typeName}Delegate;`);\n }\n\n lines.push(' $queryRaw<T = Record<string, unknown>>(sql: string): Promise<T[]>;');\n lines.push(' $disconnect(): void;');\n lines.push(' $loadSchema(): Promise<void>;');\n lines.push('}');\n lines.push('');\n\n // createClient function\n lines.push('/**');\n lines.push(' * Create a typed SuitePortal client.');\n lines.push(' * Loads schema.json and provides typed access to all record types.');\n lines.push(' */');\n lines.push('export async function createClient(');\n lines.push(' config: NetSuiteConfig,');\n lines.push(' options?: ClientOptions,');\n lines.push('): Promise<SuitePortalClient> {');\n lines.push(' const client = new BaseClient(config, options);');\n lines.push(' await client.$loadSchema();');\n lines.push(' return client as unknown as SuitePortalClient;');\n lines.push('}');\n lines.push('');\n\n // getClient singleton\n lines.push('/**');\n lines.push(' * Get (or create) a process-wide singleton typed client.');\n lines.push(' * Safe for use across server components, server actions, and API routes.');\n lines.push(' */');\n lines.push('export async function getClient(');\n lines.push(' config: NetSuiteConfig,');\n lines.push(' options?: ClientOptions,');\n lines.push('): Promise<SuitePortalClient> {');\n lines.push(' return baseGetClient(config, options) as Promise<unknown> as Promise<SuitePortalClient>;');\n lines.push('}');\n lines.push('');\n\n // Re-export destroySingleton\n lines.push('export { destroySingleton };');\n lines.push('');\n\n // Re-export types for convenience\n lines.push('export type { IncludeInput } from \\'suiteportal\\';');\n lines.push('');\n\n return lines.join('\\n');\n}\n","import type { NormalizedSchema } from '@suiteportal/introspector';\nimport { toPascalCase } from '../naming.js';\n\n/**\n * Emit the index.ts barrel export file content.\n */\nexport function emitBarrel(schema: NormalizedSchema): string {\n const recordEntries = Object.entries(schema.records);\n const typeNames = recordEntries.map(([id]) => toPascalCase(id));\n\n const lines: string[] = [\n '// Auto-generated by @suiteportal/generator — DO NOT EDIT',\n `// Generated at: ${new Date().toISOString()}`,\n '',\n ];\n\n // Type exports\n if (typeNames.length > 0) {\n const perRecordTypes = recordEntries.flatMap(([id]) => {\n const name = toPascalCase(id);\n return [\n `${name}CreateInput`,\n `${name}UpdateInput`,\n `${name}WhereInput`,\n `${name}Select`,\n `${name}OrderByInput`,\n ];\n });\n lines.push(`export type { ${[...typeNames, ...perRecordTypes].join(', ')}, RecordTypeId, RecordTypeMap } from './types';`);\n lines.push(`export type { StringFilter, NumberFilter, BooleanFilter, SelectFilter } from './types';`);\n }\n\n // Client exports\n const delegateTypes = recordEntries.map(([id]) => `${toPascalCase(id)}Delegate`);\n lines.push(`export type { SuitePortalClient${delegateTypes.length > 0 ? ', ' + delegateTypes.join(', ') : ''} } from './client';`);\n lines.push(`export { createClient } from './client';`);\n lines.push(`export type { IncludeInput } from './client';`);\n lines.push('');\n\n return lines.join('\\n');\n}\n"],"mappings":"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","names":["import_promises"]}
|
package/dist/index.js
CHANGED
|
@@ -48,6 +48,122 @@ function fieldTypeToTS(fieldType) {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
// src/emitters/type-emitter.ts
|
|
51
|
+
function fieldTypeToFilter(fieldType) {
|
|
52
|
+
switch (fieldType) {
|
|
53
|
+
case "string":
|
|
54
|
+
case "text":
|
|
55
|
+
case "richtext":
|
|
56
|
+
case "email":
|
|
57
|
+
case "url":
|
|
58
|
+
case "phone":
|
|
59
|
+
case "date":
|
|
60
|
+
case "datetime":
|
|
61
|
+
case "multiselect":
|
|
62
|
+
return { filterType: "StringFilter", shorthand: "string" };
|
|
63
|
+
case "integer":
|
|
64
|
+
case "float":
|
|
65
|
+
case "currency":
|
|
66
|
+
case "percent":
|
|
67
|
+
return { filterType: "NumberFilter", shorthand: "number" };
|
|
68
|
+
case "boolean":
|
|
69
|
+
return { filterType: "BooleanFilter", shorthand: "boolean" };
|
|
70
|
+
case "select":
|
|
71
|
+
return { filterType: "SelectFilter", shorthand: "string | number" };
|
|
72
|
+
case "unknown":
|
|
73
|
+
default:
|
|
74
|
+
return { filterType: "StringFilter", shorthand: "unknown" };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function emitFilterTypes() {
|
|
78
|
+
return `/** String field filter operators. */
|
|
79
|
+
export interface StringFilter {
|
|
80
|
+
equals?: string | null;
|
|
81
|
+
not?: string | null;
|
|
82
|
+
in?: string[];
|
|
83
|
+
notIn?: string[];
|
|
84
|
+
gt?: string;
|
|
85
|
+
gte?: string;
|
|
86
|
+
lt?: string;
|
|
87
|
+
lte?: string;
|
|
88
|
+
contains?: string;
|
|
89
|
+
startsWith?: string;
|
|
90
|
+
endsWith?: string;
|
|
91
|
+
isNull?: boolean;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Number field filter operators. */
|
|
95
|
+
export interface NumberFilter {
|
|
96
|
+
equals?: number | null;
|
|
97
|
+
not?: number | null;
|
|
98
|
+
in?: number[];
|
|
99
|
+
notIn?: number[];
|
|
100
|
+
gt?: number;
|
|
101
|
+
gte?: number;
|
|
102
|
+
lt?: number;
|
|
103
|
+
lte?: number;
|
|
104
|
+
isNull?: boolean;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Boolean field filter operators. */
|
|
108
|
+
export interface BooleanFilter {
|
|
109
|
+
equals?: boolean | null;
|
|
110
|
+
not?: boolean | null;
|
|
111
|
+
isNull?: boolean;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Select (string | number) field filter operators. */
|
|
115
|
+
export interface SelectFilter {
|
|
116
|
+
equals?: string | number | null;
|
|
117
|
+
not?: string | number | null;
|
|
118
|
+
in?: (string | number)[];
|
|
119
|
+
notIn?: (string | number)[];
|
|
120
|
+
gt?: string | number;
|
|
121
|
+
gte?: string | number;
|
|
122
|
+
lt?: string | number;
|
|
123
|
+
lte?: string | number;
|
|
124
|
+
isNull?: boolean;
|
|
125
|
+
}`;
|
|
126
|
+
}
|
|
127
|
+
function emitWhereInput(recordId, record) {
|
|
128
|
+
const name = toPascalCase(recordId);
|
|
129
|
+
const lines = [];
|
|
130
|
+
lines.push(`/** Where clause for ${record.label} queries. */`);
|
|
131
|
+
lines.push(`export interface ${name}WhereInput {`);
|
|
132
|
+
for (const [fieldId, field] of Object.entries(record.fields)) {
|
|
133
|
+
const { filterType, shorthand } = fieldTypeToFilter(field.type);
|
|
134
|
+
lines.push(` /** ${field.label} */`);
|
|
135
|
+
lines.push(` ${fieldId}?: ${shorthand} | ${filterType};`);
|
|
136
|
+
}
|
|
137
|
+
lines.push(` AND?: ${name}WhereInput[];`);
|
|
138
|
+
lines.push(` OR?: ${name}WhereInput[];`);
|
|
139
|
+
lines.push(` NOT?: ${name}WhereInput;`);
|
|
140
|
+
lines.push("}");
|
|
141
|
+
return lines.join("\n");
|
|
142
|
+
}
|
|
143
|
+
function emitSelectType(recordId, record) {
|
|
144
|
+
const name = toPascalCase(recordId);
|
|
145
|
+
const lines = [];
|
|
146
|
+
lines.push(`/** Field selection for ${record.label} queries. */`);
|
|
147
|
+
lines.push(`export interface ${name}Select {`);
|
|
148
|
+
for (const [fieldId, field] of Object.entries(record.fields)) {
|
|
149
|
+
lines.push(` /** ${field.label} */`);
|
|
150
|
+
lines.push(` ${fieldId}?: boolean;`);
|
|
151
|
+
}
|
|
152
|
+
lines.push("}");
|
|
153
|
+
return lines.join("\n");
|
|
154
|
+
}
|
|
155
|
+
function emitOrderByType(recordId, record) {
|
|
156
|
+
const name = toPascalCase(recordId);
|
|
157
|
+
const lines = [];
|
|
158
|
+
lines.push(`/** Order by clause for ${record.label} queries. */`);
|
|
159
|
+
lines.push(`export interface ${name}OrderByInput {`);
|
|
160
|
+
for (const [fieldId, field] of Object.entries(record.fields)) {
|
|
161
|
+
lines.push(` /** ${field.label} */`);
|
|
162
|
+
lines.push(` ${fieldId}?: 'asc' | 'desc';`);
|
|
163
|
+
}
|
|
164
|
+
lines.push("}");
|
|
165
|
+
return lines.join("\n");
|
|
166
|
+
}
|
|
51
167
|
function emitRecordInterface(recordId, record) {
|
|
52
168
|
const name = toPascalCase(recordId);
|
|
53
169
|
const fieldEntries = Object.entries(record.fields);
|
|
@@ -131,6 +247,10 @@ function emitTypes(schema) {
|
|
|
131
247
|
""
|
|
132
248
|
];
|
|
133
249
|
const recordEntries = Object.entries(schema.records);
|
|
250
|
+
if (recordEntries.length > 0) {
|
|
251
|
+
lines.push(emitFilterTypes());
|
|
252
|
+
lines.push("");
|
|
253
|
+
}
|
|
134
254
|
for (const [recordId, record] of recordEntries) {
|
|
135
255
|
lines.push(emitRecordInterface(recordId, record));
|
|
136
256
|
lines.push("");
|
|
@@ -143,6 +263,12 @@ function emitTypes(schema) {
|
|
|
143
263
|
lines.push("");
|
|
144
264
|
lines.push(emitUpdateInput(recordId, record));
|
|
145
265
|
lines.push("");
|
|
266
|
+
lines.push(emitWhereInput(recordId, record));
|
|
267
|
+
lines.push("");
|
|
268
|
+
lines.push(emitSelectType(recordId, record));
|
|
269
|
+
lines.push("");
|
|
270
|
+
lines.push(emitOrderByType(recordId, record));
|
|
271
|
+
lines.push("");
|
|
146
272
|
}
|
|
147
273
|
if (recordEntries.length > 0) {
|
|
148
274
|
const names = recordEntries.map(([id]) => `'${id}'`);
|
|
@@ -161,6 +287,21 @@ function emitTypes(schema) {
|
|
|
161
287
|
}
|
|
162
288
|
|
|
163
289
|
// src/emitters/client-emitter.ts
|
|
290
|
+
function emitDelegate(recordId) {
|
|
291
|
+
const name = toPascalCase(recordId);
|
|
292
|
+
const lines = [];
|
|
293
|
+
lines.push(`/** Typed delegate for ${name} records. */`);
|
|
294
|
+
lines.push(`export interface ${name}Delegate {`);
|
|
295
|
+
lines.push(` findMany(args?: { where?: ${name}WhereInput; select?: ${name}Select; orderBy?: ${name}OrderByInput; include?: IncludeInput; take?: number; skip?: number }): Promise<${name}[]>;`);
|
|
296
|
+
lines.push(` findFirst(args?: { where?: ${name}WhereInput; select?: ${name}Select; orderBy?: ${name}OrderByInput; include?: IncludeInput; skip?: number }): Promise<${name} | null>;`);
|
|
297
|
+
lines.push(` count(args?: { where?: ${name}WhereInput }): Promise<number>;`);
|
|
298
|
+
lines.push(` create(args: { data: ${name}CreateInput }): Promise<${name}>;`);
|
|
299
|
+
lines.push(` update(args: { where: { id: { equals: string | number } }; data: ${name}UpdateInput }): Promise<${name}>;`);
|
|
300
|
+
lines.push(` delete(args: { where: { id: { equals: string | number } } }): Promise<void>;`);
|
|
301
|
+
lines.push(` upsert(args: { where: { externalId: string }; data: ${name}CreateInput }): Promise<${name}>;`);
|
|
302
|
+
lines.push("}");
|
|
303
|
+
return lines.join("\n");
|
|
304
|
+
}
|
|
164
305
|
function emitClient(schema) {
|
|
165
306
|
const recordEntries = Object.entries(schema.records);
|
|
166
307
|
const typeImports = recordEntries.map(([id]) => toPascalCase(id));
|
|
@@ -173,41 +314,34 @@ function emitClient(schema) {
|
|
|
173
314
|
` SuitePortalClient as BaseClient,`,
|
|
174
315
|
` getClient as baseGetClient,`,
|
|
175
316
|
` destroySingleton,`,
|
|
176
|
-
` type FindManyArgs,`,
|
|
177
|
-
` type FindFirstArgs,`,
|
|
178
|
-
` type CountArgs,`,
|
|
179
|
-
` type CreateArgs,`,
|
|
180
|
-
` type UpdateArgs,`,
|
|
181
|
-
` type DeleteArgs,`,
|
|
182
|
-
` type UpsertArgs,`,
|
|
183
317
|
` type IncludeInput,`,
|
|
184
318
|
` type ClientOptions,`,
|
|
185
319
|
`} from 'suiteportal';`
|
|
186
320
|
];
|
|
187
321
|
if (typeImports.length > 0) {
|
|
188
|
-
const
|
|
322
|
+
const perRecordImports = recordEntries.flatMap(([id]) => {
|
|
189
323
|
const name = toPascalCase(id);
|
|
190
|
-
return [
|
|
324
|
+
return [
|
|
325
|
+
name,
|
|
326
|
+
`${name}CreateInput`,
|
|
327
|
+
`${name}UpdateInput`,
|
|
328
|
+
`${name}WhereInput`,
|
|
329
|
+
`${name}Select`,
|
|
330
|
+
`${name}OrderByInput`
|
|
331
|
+
];
|
|
191
332
|
});
|
|
192
|
-
lines.push(`import type { ${
|
|
333
|
+
lines.push(`import type { ${perRecordImports.join(", ")} } from './types';`);
|
|
193
334
|
}
|
|
194
335
|
lines.push("");
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
lines.push(" count(args?: CountArgs): Promise<number>;");
|
|
200
|
-
lines.push(" create(args: CreateArgs<TCreate>): Promise<T>;");
|
|
201
|
-
lines.push(" update(args: UpdateArgs<TUpdate>): Promise<T>;");
|
|
202
|
-
lines.push(" delete(args: DeleteArgs): Promise<void>;");
|
|
203
|
-
lines.push(" upsert(args: UpsertArgs<TCreate>): Promise<T>;");
|
|
204
|
-
lines.push("}");
|
|
205
|
-
lines.push("");
|
|
336
|
+
for (const [recordId] of recordEntries) {
|
|
337
|
+
lines.push(emitDelegate(recordId));
|
|
338
|
+
lines.push("");
|
|
339
|
+
}
|
|
206
340
|
lines.push("/** Typed SuitePortal client with per-record delegates. */");
|
|
207
341
|
lines.push("export interface SuitePortalClient {");
|
|
208
342
|
for (const [recordId] of recordEntries) {
|
|
209
343
|
const typeName = toPascalCase(recordId);
|
|
210
|
-
lines.push(` ${recordId}:
|
|
344
|
+
lines.push(` ${recordId}: ${typeName}Delegate;`);
|
|
211
345
|
}
|
|
212
346
|
lines.push(" $queryRaw<T = Record<string, unknown>>(sql: string): Promise<T[]>;");
|
|
213
347
|
lines.push(" $disconnect(): void;");
|
|
@@ -240,7 +374,7 @@ function emitClient(schema) {
|
|
|
240
374
|
lines.push("");
|
|
241
375
|
lines.push("export { destroySingleton };");
|
|
242
376
|
lines.push("");
|
|
243
|
-
lines.push("export type {
|
|
377
|
+
lines.push("export type { IncludeInput } from 'suiteportal';");
|
|
244
378
|
lines.push("");
|
|
245
379
|
return lines.join("\n");
|
|
246
380
|
}
|
|
@@ -255,15 +389,23 @@ function emitBarrel(schema) {
|
|
|
255
389
|
""
|
|
256
390
|
];
|
|
257
391
|
if (typeNames.length > 0) {
|
|
258
|
-
const
|
|
392
|
+
const perRecordTypes = recordEntries.flatMap(([id]) => {
|
|
259
393
|
const name = toPascalCase(id);
|
|
260
|
-
return [
|
|
394
|
+
return [
|
|
395
|
+
`${name}CreateInput`,
|
|
396
|
+
`${name}UpdateInput`,
|
|
397
|
+
`${name}WhereInput`,
|
|
398
|
+
`${name}Select`,
|
|
399
|
+
`${name}OrderByInput`
|
|
400
|
+
];
|
|
261
401
|
});
|
|
262
|
-
lines.push(`export type { ${[...typeNames, ...
|
|
402
|
+
lines.push(`export type { ${[...typeNames, ...perRecordTypes].join(", ")}, RecordTypeId, RecordTypeMap } from './types';`);
|
|
403
|
+
lines.push(`export type { StringFilter, NumberFilter, BooleanFilter, SelectFilter } from './types';`);
|
|
263
404
|
}
|
|
264
|
-
|
|
405
|
+
const delegateTypes = recordEntries.map(([id]) => `${toPascalCase(id)}Delegate`);
|
|
406
|
+
lines.push(`export type { SuitePortalClient${delegateTypes.length > 0 ? ", " + delegateTypes.join(", ") : ""} } from './client';`);
|
|
265
407
|
lines.push(`export { createClient } from './client';`);
|
|
266
|
-
lines.push(`export type {
|
|
408
|
+
lines.push(`export type { IncludeInput } from './client';`);
|
|
267
409
|
lines.push("");
|
|
268
410
|
return lines.join("\n");
|
|
269
411
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/generate.ts","../src/schema-reader.ts","../src/naming.ts","../src/emitters/type-emitter.ts","../src/emitters/client-emitter.ts","../src/emitters/barrel-emitter.ts"],"sourcesContent":["import { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { readSchema } from './schema-reader.js';\nimport { emitTypes } from './emitters/type-emitter.js';\nimport { emitClient } from './emitters/client-emitter.js';\nimport { emitBarrel } from './emitters/barrel-emitter.js';\nimport type { GenerateOptions, GenerateResult } from './types.js';\n\nconst DEFAULT_SCHEMA_PATH = '.suiteportal/schema.json';\nconst DEFAULT_OUTPUT_DIR = '.suiteportal/client';\n\n/**\n * Generate typed client code from a schema.json file.\n *\n * Reads the introspected schema, emits TypeScript interfaces for all records,\n * a typed client wrapper, and a barrel export file.\n */\nexport async function generate(options?: GenerateOptions): Promise<GenerateResult> {\n const schemaPath = options?.schemaPath ?? DEFAULT_SCHEMA_PATH;\n const outputDir = options?.outputDir ?? DEFAULT_OUTPUT_DIR;\n\n // Read schema\n const schema = await readSchema(schemaPath);\n\n // Ensure output directory exists\n await mkdir(outputDir, { recursive: true });\n\n // Generate files\n const typesContent = emitTypes(schema);\n const clientContent = emitClient(schema);\n const barrelContent = emitBarrel(schema);\n\n // Write files\n const typesPath = join(outputDir, 'types.ts');\n const clientPath = join(outputDir, 'client.ts');\n const barrelPath = join(outputDir, 'index.ts');\n\n await Promise.all([\n writeFile(typesPath, typesContent, 'utf-8'),\n writeFile(clientPath, clientContent, 'utf-8'),\n writeFile(barrelPath, barrelContent, 'utf-8'),\n ]);\n\n // Compute stats\n const recordEntries = Object.entries(schema.records);\n const fieldCount = recordEntries.reduce(\n (sum, [, record]) => sum + Object.keys(record.fields).length,\n 0,\n );\n\n return {\n recordCount: recordEntries.length,\n fieldCount,\n files: [typesPath, clientPath, barrelPath],\n outputDir,\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport type { NormalizedSchema } from '@suiteportal/introspector';\n\n/**\n * Read and parse a schema.json file.\n */\nexport async function readSchema(schemaPath: string): Promise<NormalizedSchema> {\n const raw = await readFile(schemaPath, 'utf-8');\n const schema = JSON.parse(raw) as NormalizedSchema;\n\n if (!schema.records || typeof schema.records !== 'object') {\n throw new Error(`Invalid schema: missing \"records\" in ${schemaPath}`);\n }\n\n return schema;\n}\n","import type { FieldType } from '@suiteportal/introspector';\n\n/**\n * Convert a record ID to PascalCase for use as a TypeScript interface name.\n * Examples:\n * 'customer' → 'Customer'\n * 'salesorder' → 'Salesorder'\n * 'customrecord_mytype' → 'CustomrecordMytype'\n */\nexport function toPascalCase(name: string): string {\n return name\n .split('_')\n .map((part) => (part.length > 0 ? part[0]!.toUpperCase() + part.slice(1).toLowerCase() : ''))\n .join('');\n}\n\n/**\n * Map a normalized FieldType to its TypeScript type representation.\n */\nexport function fieldTypeToTS(fieldType: FieldType): string {\n switch (fieldType) {\n case 'string':\n case 'text':\n case 'richtext':\n case 'email':\n case 'url':\n case 'phone':\n return 'string';\n\n case 'integer':\n case 'float':\n case 'currency':\n case 'percent':\n return 'number';\n\n case 'boolean':\n return 'boolean';\n\n case 'date':\n case 'datetime':\n return 'string'; // SuiteQL returns date strings\n\n case 'select':\n return 'string | number';\n\n case 'multiselect':\n return 'string';\n\n case 'unknown':\n default:\n return 'unknown';\n }\n}\n","import type { NormalizedSchema, RecordDefinition, SublistDefinition } from '@suiteportal/introspector';\nimport { toPascalCase, fieldTypeToTS } from '../naming.js';\n\n/**\n * Emit a TypeScript interface for a single record.\n */\nfunction emitRecordInterface(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const fieldEntries = Object.entries(record.fields);\n const fieldCount = fieldEntries.length;\n\n const lines: string[] = [];\n lines.push(`/** ${record.label} — ${fieldCount} fields */`);\n lines.push(`export interface ${name} {`);\n\n for (const [fieldId, field] of fieldEntries) {\n const tsType = fieldTypeToTS(field.type);\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: ${tsType};`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit a TypeScript interface for a single sublist item.\n */\nfunction emitSublistItem(recordId: string, sublistId: string, sublist: SublistDefinition): string {\n const recordName = toPascalCase(recordId);\n const sublistName = toPascalCase(sublistId);\n const interfaceName = `${recordName}${sublistName}Item`;\n const fieldEntries = Object.entries(sublist.fields);\n\n const lines: string[] = [];\n lines.push(`/** ${sublist.label} line item on ${recordName}. */`);\n lines.push(`export interface ${interfaceName} {`);\n\n for (const [fieldId, field] of fieldEntries) {\n const tsType = fieldTypeToTS(field.type);\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: ${tsType};`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit a CreateInput interface for a record.\n * Excludes readOnly fields and `id`. Required writable fields are non-optional.\n */\nfunction emitCreateInput(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const sublistKeys = new Set(Object.keys(record.sublists ?? {}));\n const lines: string[] = [];\n lines.push(`/** Fields for creating a ${record.label}. */`);\n lines.push(`export interface ${name}CreateInput {`);\n\n for (const [fieldId, field] of Object.entries(record.fields)) {\n if (fieldId === 'id' || field.readOnly) continue;\n // Skip fields that collide with sublist names — sublist takes precedence\n if (sublistKeys.has(fieldId)) continue;\n const tsType = fieldTypeToTS(field.type);\n const optional = field.required ? '' : '?';\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}${optional}: ${tsType};`);\n }\n\n // Sublist fields\n const sublistEntries = Object.entries(record.sublists ?? {});\n for (const [sublistId] of sublistEntries) {\n const itemType = `${name}${toPascalCase(sublistId)}Item`;\n lines.push(` /** ${toPascalCase(sublistId)} sublist. */`);\n lines.push(` ${sublistId}?: { items: ${itemType}[] };`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit an UpdateInput interface for a record.\n * Excludes readOnly fields and `id`. All fields are optional.\n */\nfunction emitUpdateInput(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const sublistKeys = new Set(Object.keys(record.sublists ?? {}));\n const lines: string[] = [];\n lines.push(`/** Fields for updating a ${record.label}. */`);\n lines.push(`export interface ${name}UpdateInput {`);\n\n for (const [fieldId, field] of Object.entries(record.fields)) {\n if (fieldId === 'id' || field.readOnly) continue;\n // Skip fields that collide with sublist names — sublist takes precedence\n if (sublistKeys.has(fieldId)) continue;\n const tsType = fieldTypeToTS(field.type);\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: ${tsType};`);\n }\n\n // Sublist fields\n const sublistEntries = Object.entries(record.sublists ?? {});\n for (const [sublistId] of sublistEntries) {\n const itemType = `${name}${toPascalCase(sublistId)}Item`;\n lines.push(` /** ${toPascalCase(sublistId)} sublist. */`);\n lines.push(` ${sublistId}?: { items: ${itemType}[] };`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit the full types.ts file content from a schema.\n */\nexport function emitTypes(schema: NormalizedSchema): string {\n const lines: string[] = [\n '// Auto-generated by @suiteportal/generator — DO NOT EDIT',\n `// Generated at: ${new Date().toISOString()}`,\n '',\n ];\n\n const recordEntries = Object.entries(schema.records);\n\n for (const [recordId, record] of recordEntries) {\n lines.push(emitRecordInterface(recordId, record));\n lines.push('');\n\n // Emit sublist item interfaces before Create/UpdateInput (they reference the item types)\n const sublistEntries = Object.entries(record.sublists ?? {});\n for (const [sublistId, sublist] of sublistEntries) {\n lines.push(emitSublistItem(recordId, sublistId, sublist));\n lines.push('');\n }\n\n lines.push(emitCreateInput(recordId, record));\n lines.push('');\n lines.push(emitUpdateInput(recordId, record));\n lines.push('');\n }\n\n // Export a union type of all record names\n if (recordEntries.length > 0) {\n const names = recordEntries.map(([id]) => `'${id}'`);\n lines.push(`/** All available record type IDs. */`);\n lines.push(`export type RecordTypeId = ${names.join(' | ')};`);\n lines.push('');\n\n // Record type map\n lines.push(`/** Map of record type IDs to their TypeScript interfaces. */`);\n lines.push(`export interface RecordTypeMap {`);\n for (const [recordId] of recordEntries) {\n lines.push(` ${recordId}: ${toPascalCase(recordId)};`);\n }\n lines.push('}');\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","import type { NormalizedSchema } from '@suiteportal/introspector';\nimport { toPascalCase } from '../naming.js';\n\n/**\n * Emit the client.ts file content — a typed wrapper around the base SuitePortalClient.\n */\nexport function emitClient(schema: NormalizedSchema): string {\n const recordEntries = Object.entries(schema.records);\n const typeImports = recordEntries.map(([id]) => toPascalCase(id));\n\n const lines: string[] = [\n '// Auto-generated by suiteportal — DO NOT EDIT',\n `// Generated at: ${new Date().toISOString()}`,\n '',\n `import type { NetSuiteConfig } from 'suiteportal';`,\n `import {`,\n ` SuitePortalClient as BaseClient,`,\n ` getClient as baseGetClient,`,\n ` destroySingleton,`,\n ` type FindManyArgs,`,\n ` type FindFirstArgs,`,\n ` type CountArgs,`,\n ` type CreateArgs,`,\n ` type UpdateArgs,`,\n ` type DeleteArgs,`,\n ` type UpsertArgs,`,\n ` type IncludeInput,`,\n ` type ClientOptions,`,\n `} from 'suiteportal';`,\n ];\n\n if (typeImports.length > 0) {\n const inputImports = recordEntries.flatMap(([id]) => {\n const name = toPascalCase(id);\n return [`${name}CreateInput`, `${name}UpdateInput`];\n });\n lines.push(`import type { ${[...typeImports, ...inputImports].join(', ')} } from './types';`);\n }\n\n lines.push('');\n\n // TypedModelDelegate interface\n lines.push('/** A typed model delegate for a specific record type. */');\n lines.push('export interface TypedModelDelegate<T, TCreate = Record<string, unknown>, TUpdate = Record<string, unknown>> {');\n lines.push(' findMany(args?: FindManyArgs): Promise<T[]>;');\n lines.push(' findFirst(args?: FindFirstArgs): Promise<T | null>;');\n lines.push(' count(args?: CountArgs): Promise<number>;');\n lines.push(' create(args: CreateArgs<TCreate>): Promise<T>;');\n lines.push(' update(args: UpdateArgs<TUpdate>): Promise<T>;');\n lines.push(' delete(args: DeleteArgs): Promise<void>;');\n lines.push(' upsert(args: UpsertArgs<TCreate>): Promise<T>;');\n lines.push('}');\n lines.push('');\n\n // SuitePortalClient interface\n lines.push('/** Typed SuitePortal client with per-record delegates. */');\n lines.push('export interface SuitePortalClient {');\n\n for (const [recordId] of recordEntries) {\n const typeName = toPascalCase(recordId);\n lines.push(` ${recordId}: TypedModelDelegate<${typeName}, ${typeName}CreateInput, ${typeName}UpdateInput>;`);\n }\n\n lines.push(' $queryRaw<T = Record<string, unknown>>(sql: string): Promise<T[]>;');\n lines.push(' $disconnect(): void;');\n lines.push(' $loadSchema(): Promise<void>;');\n lines.push('}');\n lines.push('');\n\n // createClient function\n lines.push('/**');\n lines.push(' * Create a typed SuitePortal client.');\n lines.push(' * Loads schema.json and provides typed access to all record types.');\n lines.push(' */');\n lines.push('export async function createClient(');\n lines.push(' config: NetSuiteConfig,');\n lines.push(' options?: ClientOptions,');\n lines.push('): Promise<SuitePortalClient> {');\n lines.push(' const client = new BaseClient(config, options);');\n lines.push(' await client.$loadSchema();');\n lines.push(' return client as unknown as SuitePortalClient;');\n lines.push('}');\n lines.push('');\n\n // getClient singleton\n lines.push('/**');\n lines.push(' * Get (or create) a process-wide singleton typed client.');\n lines.push(' * Safe for use across server components, server actions, and API routes.');\n lines.push(' */');\n lines.push('export async function getClient(');\n lines.push(' config: NetSuiteConfig,');\n lines.push(' options?: ClientOptions,');\n lines.push('): Promise<SuitePortalClient> {');\n lines.push(' return baseGetClient(config, options) as Promise<unknown> as Promise<SuitePortalClient>;');\n lines.push('}');\n lines.push('');\n\n // Re-export destroySingleton\n lines.push('export { destroySingleton };');\n lines.push('');\n\n // Re-export types for convenience\n lines.push('export type { FindManyArgs, FindFirstArgs, CountArgs, CreateArgs, UpdateArgs, DeleteArgs, UpsertArgs, IncludeInput } from \\'suiteportal\\';');\n lines.push('');\n\n return lines.join('\\n');\n}\n","import type { NormalizedSchema } from '@suiteportal/introspector';\nimport { toPascalCase } from '../naming.js';\n\n/**\n * Emit the index.ts barrel export file content.\n */\nexport function emitBarrel(schema: NormalizedSchema): string {\n const recordEntries = Object.entries(schema.records);\n const typeNames = recordEntries.map(([id]) => toPascalCase(id));\n\n const lines: string[] = [\n '// Auto-generated by @suiteportal/generator — DO NOT EDIT',\n `// Generated at: ${new Date().toISOString()}`,\n '',\n ];\n\n // Type exports\n if (typeNames.length > 0) {\n const inputTypes = recordEntries.flatMap(([id]) => {\n const name = toPascalCase(id);\n return [`${name}CreateInput`, `${name}UpdateInput`];\n });\n lines.push(`export type { ${[...typeNames, ...inputTypes].join(', ')}, RecordTypeId, RecordTypeMap } from './types';`);\n }\n\n // Client exports\n lines.push(`export type { SuitePortalClient, TypedModelDelegate } from './client';`);\n lines.push(`export { createClient } from './client';`);\n lines.push(`export type { FindManyArgs, FindFirstArgs, CountArgs, CreateArgs, UpdateArgs, DeleteArgs, IncludeInput } from './client';`);\n lines.push('');\n\n return lines.join('\\n');\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/generate.ts","../src/schema-reader.ts","../src/naming.ts","../src/emitters/type-emitter.ts","../src/emitters/client-emitter.ts","../src/emitters/barrel-emitter.ts"],"sourcesContent":["import { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { readSchema } from './schema-reader.js';\nimport { emitTypes } from './emitters/type-emitter.js';\nimport { emitClient } from './emitters/client-emitter.js';\nimport { emitBarrel } from './emitters/barrel-emitter.js';\nimport type { GenerateOptions, GenerateResult } from './types.js';\n\nconst DEFAULT_SCHEMA_PATH = '.suiteportal/schema.json';\nconst DEFAULT_OUTPUT_DIR = '.suiteportal/client';\n\n/**\n * Generate typed client code from a schema.json file.\n *\n * Reads the introspected schema, emits TypeScript interfaces for all records,\n * a typed client wrapper, and a barrel export file.\n */\nexport async function generate(options?: GenerateOptions): Promise<GenerateResult> {\n const schemaPath = options?.schemaPath ?? DEFAULT_SCHEMA_PATH;\n const outputDir = options?.outputDir ?? DEFAULT_OUTPUT_DIR;\n\n // Read schema\n const schema = await readSchema(schemaPath);\n\n // Ensure output directory exists\n await mkdir(outputDir, { recursive: true });\n\n // Generate files\n const typesContent = emitTypes(schema);\n const clientContent = emitClient(schema);\n const barrelContent = emitBarrel(schema);\n\n // Write files\n const typesPath = join(outputDir, 'types.ts');\n const clientPath = join(outputDir, 'client.ts');\n const barrelPath = join(outputDir, 'index.ts');\n\n await Promise.all([\n writeFile(typesPath, typesContent, 'utf-8'),\n writeFile(clientPath, clientContent, 'utf-8'),\n writeFile(barrelPath, barrelContent, 'utf-8'),\n ]);\n\n // Compute stats\n const recordEntries = Object.entries(schema.records);\n const fieldCount = recordEntries.reduce(\n (sum, [, record]) => sum + Object.keys(record.fields).length,\n 0,\n );\n\n return {\n recordCount: recordEntries.length,\n fieldCount,\n files: [typesPath, clientPath, barrelPath],\n outputDir,\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport type { NormalizedSchema } from '@suiteportal/introspector';\n\n/**\n * Read and parse a schema.json file.\n */\nexport async function readSchema(schemaPath: string): Promise<NormalizedSchema> {\n const raw = await readFile(schemaPath, 'utf-8');\n const schema = JSON.parse(raw) as NormalizedSchema;\n\n if (!schema.records || typeof schema.records !== 'object') {\n throw new Error(`Invalid schema: missing \"records\" in ${schemaPath}`);\n }\n\n return schema;\n}\n","import type { FieldType } from '@suiteportal/introspector';\n\n/**\n * Convert a record ID to PascalCase for use as a TypeScript interface name.\n * Examples:\n * 'customer' → 'Customer'\n * 'salesorder' → 'Salesorder'\n * 'customrecord_mytype' → 'CustomrecordMytype'\n */\nexport function toPascalCase(name: string): string {\n return name\n .split('_')\n .map((part) => (part.length > 0 ? part[0]!.toUpperCase() + part.slice(1).toLowerCase() : ''))\n .join('');\n}\n\n/**\n * Map a normalized FieldType to its TypeScript type representation.\n */\nexport function fieldTypeToTS(fieldType: FieldType): string {\n switch (fieldType) {\n case 'string':\n case 'text':\n case 'richtext':\n case 'email':\n case 'url':\n case 'phone':\n return 'string';\n\n case 'integer':\n case 'float':\n case 'currency':\n case 'percent':\n return 'number';\n\n case 'boolean':\n return 'boolean';\n\n case 'date':\n case 'datetime':\n return 'string'; // SuiteQL returns date strings\n\n case 'select':\n return 'string | number';\n\n case 'multiselect':\n return 'string';\n\n case 'unknown':\n default:\n return 'unknown';\n }\n}\n","import type { NormalizedSchema, RecordDefinition, FieldDefinition, SublistDefinition, FieldType } from '@suiteportal/introspector';\nimport { toPascalCase, fieldTypeToTS } from '../naming.js';\n\n/**\n * Map a FieldType to its filter type name and shorthand value type.\n */\nfunction fieldTypeToFilter(fieldType: FieldType): { filterType: string; shorthand: string } {\n switch (fieldType) {\n case 'string':\n case 'text':\n case 'richtext':\n case 'email':\n case 'url':\n case 'phone':\n case 'date':\n case 'datetime':\n case 'multiselect':\n return { filterType: 'StringFilter', shorthand: 'string' };\n\n case 'integer':\n case 'float':\n case 'currency':\n case 'percent':\n return { filterType: 'NumberFilter', shorthand: 'number' };\n\n case 'boolean':\n return { filterType: 'BooleanFilter', shorthand: 'boolean' };\n\n case 'select':\n return { filterType: 'SelectFilter', shorthand: 'string | number' };\n\n case 'unknown':\n default:\n return { filterType: 'StringFilter', shorthand: 'unknown' };\n }\n}\n\n/**\n * Emit shared filter type interfaces used by all per-record WhereInput types.\n */\nfunction emitFilterTypes(): string {\n return `/** String field filter operators. */\nexport interface StringFilter {\n equals?: string | null;\n not?: string | null;\n in?: string[];\n notIn?: string[];\n gt?: string;\n gte?: string;\n lt?: string;\n lte?: string;\n contains?: string;\n startsWith?: string;\n endsWith?: string;\n isNull?: boolean;\n}\n\n/** Number field filter operators. */\nexport interface NumberFilter {\n equals?: number | null;\n not?: number | null;\n in?: number[];\n notIn?: number[];\n gt?: number;\n gte?: number;\n lt?: number;\n lte?: number;\n isNull?: boolean;\n}\n\n/** Boolean field filter operators. */\nexport interface BooleanFilter {\n equals?: boolean | null;\n not?: boolean | null;\n isNull?: boolean;\n}\n\n/** Select (string | number) field filter operators. */\nexport interface SelectFilter {\n equals?: string | number | null;\n not?: string | number | null;\n in?: (string | number)[];\n notIn?: (string | number)[];\n gt?: string | number;\n gte?: string | number;\n lt?: string | number;\n lte?: string | number;\n isNull?: boolean;\n}`;\n}\n\n/**\n * Emit a per-record WhereInput type with typed fields.\n */\nfunction emitWhereInput(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const lines: string[] = [];\n lines.push(`/** Where clause for ${record.label} queries. */`);\n lines.push(`export interface ${name}WhereInput {`);\n\n for (const [fieldId, field] of Object.entries(record.fields)) {\n const { filterType, shorthand } = fieldTypeToFilter(field.type);\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: ${shorthand} | ${filterType};`);\n }\n\n lines.push(` AND?: ${name}WhereInput[];`);\n lines.push(` OR?: ${name}WhereInput[];`);\n lines.push(` NOT?: ${name}WhereInput;`);\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit a per-record Select type.\n */\nfunction emitSelectType(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const lines: string[] = [];\n lines.push(`/** Field selection for ${record.label} queries. */`);\n lines.push(`export interface ${name}Select {`);\n\n for (const [fieldId, field] of Object.entries(record.fields)) {\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: boolean;`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit a per-record OrderByInput type.\n */\nfunction emitOrderByType(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const lines: string[] = [];\n lines.push(`/** Order by clause for ${record.label} queries. */`);\n lines.push(`export interface ${name}OrderByInput {`);\n\n for (const [fieldId, field] of Object.entries(record.fields)) {\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: 'asc' | 'desc';`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit a TypeScript interface for a single record.\n */\nfunction emitRecordInterface(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const fieldEntries = Object.entries(record.fields);\n const fieldCount = fieldEntries.length;\n\n const lines: string[] = [];\n lines.push(`/** ${record.label} — ${fieldCount} fields */`);\n lines.push(`export interface ${name} {`);\n\n for (const [fieldId, field] of fieldEntries) {\n const tsType = fieldTypeToTS(field.type);\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: ${tsType};`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit a TypeScript interface for a single sublist item.\n */\nfunction emitSublistItem(recordId: string, sublistId: string, sublist: SublistDefinition): string {\n const recordName = toPascalCase(recordId);\n const sublistName = toPascalCase(sublistId);\n const interfaceName = `${recordName}${sublistName}Item`;\n const fieldEntries = Object.entries(sublist.fields);\n\n const lines: string[] = [];\n lines.push(`/** ${sublist.label} line item on ${recordName}. */`);\n lines.push(`export interface ${interfaceName} {`);\n\n for (const [fieldId, field] of fieldEntries) {\n const tsType = fieldTypeToTS(field.type);\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: ${tsType};`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit a CreateInput interface for a record.\n * Excludes readOnly fields and `id`. Required writable fields are non-optional.\n */\nfunction emitCreateInput(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const sublistKeys = new Set(Object.keys(record.sublists ?? {}));\n const lines: string[] = [];\n lines.push(`/** Fields for creating a ${record.label}. */`);\n lines.push(`export interface ${name}CreateInput {`);\n\n for (const [fieldId, field] of Object.entries(record.fields)) {\n if (fieldId === 'id' || field.readOnly) continue;\n // Skip fields that collide with sublist names — sublist takes precedence\n if (sublistKeys.has(fieldId)) continue;\n const tsType = fieldTypeToTS(field.type);\n const optional = field.required ? '' : '?';\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}${optional}: ${tsType};`);\n }\n\n // Sublist fields\n const sublistEntries = Object.entries(record.sublists ?? {});\n for (const [sublistId] of sublistEntries) {\n const itemType = `${name}${toPascalCase(sublistId)}Item`;\n lines.push(` /** ${toPascalCase(sublistId)} sublist. */`);\n lines.push(` ${sublistId}?: { items: ${itemType}[] };`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit an UpdateInput interface for a record.\n * Excludes readOnly fields and `id`. All fields are optional.\n */\nfunction emitUpdateInput(recordId: string, record: RecordDefinition): string {\n const name = toPascalCase(recordId);\n const sublistKeys = new Set(Object.keys(record.sublists ?? {}));\n const lines: string[] = [];\n lines.push(`/** Fields for updating a ${record.label}. */`);\n lines.push(`export interface ${name}UpdateInput {`);\n\n for (const [fieldId, field] of Object.entries(record.fields)) {\n if (fieldId === 'id' || field.readOnly) continue;\n // Skip fields that collide with sublist names — sublist takes precedence\n if (sublistKeys.has(fieldId)) continue;\n const tsType = fieldTypeToTS(field.type);\n lines.push(` /** ${field.label} */`);\n lines.push(` ${fieldId}?: ${tsType};`);\n }\n\n // Sublist fields\n const sublistEntries = Object.entries(record.sublists ?? {});\n for (const [sublistId] of sublistEntries) {\n const itemType = `${name}${toPascalCase(sublistId)}Item`;\n lines.push(` /** ${toPascalCase(sublistId)} sublist. */`);\n lines.push(` ${sublistId}?: { items: ${itemType}[] };`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit the full types.ts file content from a schema.\n */\nexport function emitTypes(schema: NormalizedSchema): string {\n const lines: string[] = [\n '// Auto-generated by @suiteportal/generator — DO NOT EDIT',\n `// Generated at: ${new Date().toISOString()}`,\n '',\n ];\n\n const recordEntries = Object.entries(schema.records);\n\n // Emit shared filter types first (used by all WhereInput types)\n if (recordEntries.length > 0) {\n lines.push(emitFilterTypes());\n lines.push('');\n }\n\n for (const [recordId, record] of recordEntries) {\n lines.push(emitRecordInterface(recordId, record));\n lines.push('');\n\n // Emit sublist item interfaces before Create/UpdateInput (they reference the item types)\n const sublistEntries = Object.entries(record.sublists ?? {});\n for (const [sublistId, sublist] of sublistEntries) {\n lines.push(emitSublistItem(recordId, sublistId, sublist));\n lines.push('');\n }\n\n lines.push(emitCreateInput(recordId, record));\n lines.push('');\n lines.push(emitUpdateInput(recordId, record));\n lines.push('');\n\n // Emit per-record query types (WhereInput, Select, OrderByInput)\n lines.push(emitWhereInput(recordId, record));\n lines.push('');\n lines.push(emitSelectType(recordId, record));\n lines.push('');\n lines.push(emitOrderByType(recordId, record));\n lines.push('');\n }\n\n // Export a union type of all record names\n if (recordEntries.length > 0) {\n const names = recordEntries.map(([id]) => `'${id}'`);\n lines.push(`/** All available record type IDs. */`);\n lines.push(`export type RecordTypeId = ${names.join(' | ')};`);\n lines.push('');\n\n // Record type map\n lines.push(`/** Map of record type IDs to their TypeScript interfaces. */`);\n lines.push(`export interface RecordTypeMap {`);\n for (const [recordId] of recordEntries) {\n lines.push(` ${recordId}: ${toPascalCase(recordId)};`);\n }\n lines.push('}');\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","import type { NormalizedSchema } from '@suiteportal/introspector';\nimport { toPascalCase } from '../naming.js';\n\n/**\n * Emit a per-record delegate interface with fully typed query args.\n */\nfunction emitDelegate(recordId: string): string {\n const name = toPascalCase(recordId);\n const lines: string[] = [];\n lines.push(`/** Typed delegate for ${name} records. */`);\n lines.push(`export interface ${name}Delegate {`);\n lines.push(` findMany(args?: { where?: ${name}WhereInput; select?: ${name}Select; orderBy?: ${name}OrderByInput; include?: IncludeInput; take?: number; skip?: number }): Promise<${name}[]>;`);\n lines.push(` findFirst(args?: { where?: ${name}WhereInput; select?: ${name}Select; orderBy?: ${name}OrderByInput; include?: IncludeInput; skip?: number }): Promise<${name} | null>;`);\n lines.push(` count(args?: { where?: ${name}WhereInput }): Promise<number>;`);\n lines.push(` create(args: { data: ${name}CreateInput }): Promise<${name}>;`);\n lines.push(` update(args: { where: { id: { equals: string | number } }; data: ${name}UpdateInput }): Promise<${name}>;`);\n lines.push(` delete(args: { where: { id: { equals: string | number } } }): Promise<void>;`);\n lines.push(` upsert(args: { where: { externalId: string }; data: ${name}CreateInput }): Promise<${name}>;`);\n lines.push('}');\n return lines.join('\\n');\n}\n\n/**\n * Emit the client.ts file content — a typed wrapper around the base SuitePortalClient.\n */\nexport function emitClient(schema: NormalizedSchema): string {\n const recordEntries = Object.entries(schema.records);\n const typeImports = recordEntries.map(([id]) => toPascalCase(id));\n\n const lines: string[] = [\n '// Auto-generated by suiteportal — DO NOT EDIT',\n `// Generated at: ${new Date().toISOString()}`,\n '',\n `import type { NetSuiteConfig } from 'suiteportal';`,\n `import {`,\n ` SuitePortalClient as BaseClient,`,\n ` getClient as baseGetClient,`,\n ` destroySingleton,`,\n ` type IncludeInput,`,\n ` type ClientOptions,`,\n `} from 'suiteportal';`,\n ];\n\n if (typeImports.length > 0) {\n const perRecordImports = recordEntries.flatMap(([id]) => {\n const name = toPascalCase(id);\n return [\n name,\n `${name}CreateInput`,\n `${name}UpdateInput`,\n `${name}WhereInput`,\n `${name}Select`,\n `${name}OrderByInput`,\n ];\n });\n lines.push(`import type { ${perRecordImports.join(', ')} } from './types';`);\n }\n\n lines.push('');\n\n // Per-record delegate interfaces\n for (const [recordId] of recordEntries) {\n lines.push(emitDelegate(recordId));\n lines.push('');\n }\n\n // SuitePortalClient interface\n lines.push('/** Typed SuitePortal client with per-record delegates. */');\n lines.push('export interface SuitePortalClient {');\n\n for (const [recordId] of recordEntries) {\n const typeName = toPascalCase(recordId);\n lines.push(` ${recordId}: ${typeName}Delegate;`);\n }\n\n lines.push(' $queryRaw<T = Record<string, unknown>>(sql: string): Promise<T[]>;');\n lines.push(' $disconnect(): void;');\n lines.push(' $loadSchema(): Promise<void>;');\n lines.push('}');\n lines.push('');\n\n // createClient function\n lines.push('/**');\n lines.push(' * Create a typed SuitePortal client.');\n lines.push(' * Loads schema.json and provides typed access to all record types.');\n lines.push(' */');\n lines.push('export async function createClient(');\n lines.push(' config: NetSuiteConfig,');\n lines.push(' options?: ClientOptions,');\n lines.push('): Promise<SuitePortalClient> {');\n lines.push(' const client = new BaseClient(config, options);');\n lines.push(' await client.$loadSchema();');\n lines.push(' return client as unknown as SuitePortalClient;');\n lines.push('}');\n lines.push('');\n\n // getClient singleton\n lines.push('/**');\n lines.push(' * Get (or create) a process-wide singleton typed client.');\n lines.push(' * Safe for use across server components, server actions, and API routes.');\n lines.push(' */');\n lines.push('export async function getClient(');\n lines.push(' config: NetSuiteConfig,');\n lines.push(' options?: ClientOptions,');\n lines.push('): Promise<SuitePortalClient> {');\n lines.push(' return baseGetClient(config, options) as Promise<unknown> as Promise<SuitePortalClient>;');\n lines.push('}');\n lines.push('');\n\n // Re-export destroySingleton\n lines.push('export { destroySingleton };');\n lines.push('');\n\n // Re-export types for convenience\n lines.push('export type { IncludeInput } from \\'suiteportal\\';');\n lines.push('');\n\n return lines.join('\\n');\n}\n","import type { NormalizedSchema } from '@suiteportal/introspector';\nimport { toPascalCase } from '../naming.js';\n\n/**\n * Emit the index.ts barrel export file content.\n */\nexport function emitBarrel(schema: NormalizedSchema): string {\n const recordEntries = Object.entries(schema.records);\n const typeNames = recordEntries.map(([id]) => toPascalCase(id));\n\n const lines: string[] = [\n '// Auto-generated by @suiteportal/generator — DO NOT EDIT',\n `// Generated at: ${new Date().toISOString()}`,\n '',\n ];\n\n // Type exports\n if (typeNames.length > 0) {\n const perRecordTypes = recordEntries.flatMap(([id]) => {\n const name = toPascalCase(id);\n return [\n `${name}CreateInput`,\n `${name}UpdateInput`,\n `${name}WhereInput`,\n `${name}Select`,\n `${name}OrderByInput`,\n ];\n });\n lines.push(`export type { ${[...typeNames, ...perRecordTypes].join(', ')}, RecordTypeId, RecordTypeMap } from './types';`);\n lines.push(`export type { StringFilter, NumberFilter, BooleanFilter, SelectFilter } from './types';`);\n }\n\n // Client exports\n const delegateTypes = recordEntries.map(([id]) => `${toPascalCase(id)}Delegate`);\n lines.push(`export type { SuitePortalClient${delegateTypes.length > 0 ? ', ' + delegateTypes.join(', ') : ''} } from './client';`);\n lines.push(`export { createClient } from './client';`);\n lines.push(`export type { IncludeInput } from './client';`);\n lines.push('');\n\n return lines.join('\\n');\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suiteportal/generator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Code generator for SuitePortal NetSuite ORM — emits typed queries, mutations, and includes from schema",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"clean": "rm -rf dist"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@suiteportal/introspector": "^0.
|
|
24
|
+
"@suiteportal/introspector": "^0.5.0"
|
|
25
25
|
},
|
|
26
26
|
"license": "MIT",
|
|
27
27
|
"author": "Trey Hulse",
|