@lakeql/schema-generator 0.4.5 → 1.0.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.
@@ -1,35 +1,28 @@
1
1
  import { z } from "zod";
2
-
3
- //#region src/endpoint-schema.d.ts
2
+ import { LoadStrategy, LoadStrategy as LoadStrategy$1 } from "@lakeql/datasource";
4
3
  /**
5
4
  * Regex pattern for field names: alphanumeric + underscore, no leading digit, max 64 chars.
6
5
  */
7
- declare const fieldNamePattern: RegExp;
6
+ export declare const fieldNamePattern: RegExp;
8
7
  /**
9
8
  * Regex pattern for metadata fields (tableName, catalog, schema): alphanumeric + underscore,
10
9
  * no leading digit, max 128 chars.
11
10
  */
12
- declare const metadataFieldPattern: RegExp;
11
+ export declare const metadataFieldPattern: RegExp;
13
12
  /**
14
13
  * Supported load strategies for the mutation write pipeline.
15
14
  */
16
- declare const loadStrategies: readonly ["full_load", "full_load_append", "append"];
17
- type LoadStrategy = (typeof loadStrategies)[number];
18
- /**
19
- * Supported storage adapter types.
20
- */
21
- declare const storageTypes: readonly ["s3", "minio"];
22
- type StorageType = (typeof storageTypes)[number];
15
+ export declare const loadStrategies: readonly ["full_load", "full_load_append", "append"];
23
16
  /**
24
17
  * Supported partitioning format granularities.
25
18
  */
26
- declare const partitioningFormats: readonly ["year", "year/month", "year/month/day"];
27
- type PartitioningFormat = (typeof partitioningFormats)[number];
19
+ export declare const partitioningFormats: readonly ["year", "year/month", "year/month/day"];
20
+ export type PartitioningFormat = (typeof partitioningFormats)[number];
28
21
  /**
29
22
  * Supported date components for custom partition format segments.
30
23
  */
31
- declare const partitioningComponents: readonly ["year", "month", "day", "hour", "minute", "second"];
32
- type PartitioningComponent = (typeof partitioningComponents)[number];
24
+ export declare const partitioningComponents: readonly ["year", "month", "day", "hour", "minute", "second"];
25
+ export type PartitioningComponent = (typeof partitioningComponents)[number];
33
26
  /**
34
27
  * Validates a custom partitioning format string.
35
28
  * - If the value contains no `/` and no `:`, it must match fieldNamePattern (legacy single-field mode).
@@ -40,33 +33,22 @@ type PartitioningComponent = (typeof partitioningComponents)[number];
40
33
  *
41
34
  * Returns null if valid, or an error message string if invalid.
42
35
  */
43
- declare function validatePartitioningFormat(value: string): string | null;
36
+ export declare function validatePartitioningFormat(value: string): string | null;
44
37
  /**
45
38
  * Partitioning configuration value:
46
39
  * - true: partition by write timestamp (default)
47
40
  * - false: no partitioning (flat layout)
48
41
  * - string: partition by named field
49
42
  */
50
- type PartitioningValue = boolean | string;
43
+ export type PartitioningValue = boolean | string;
51
44
  /**
52
45
  * Mutation pipeline configuration for an endpoint.
53
46
  */
54
- interface MutationConfig {
47
+ export interface MutationConfig {
55
48
  /** Load strategy for the write pipeline. */
56
- loadStrategy: LoadStrategy;
57
- /**
58
- * Storage adapter type.
59
- * @default "s3"
60
- */
61
- type: StorageType;
62
- /** S3/MinIO bucket name for endpoint data. */
63
- bucket: string;
49
+ loadStrategy: LoadStrategy$1;
64
50
  /** Base path for endpoint data. */
65
51
  basePath: string;
66
- /** Optional region override (falls back to AWS_DEFAULT_REGION env var for S3). */
67
- region?: string;
68
- /** Optional custom endpoint. Required for MinIO, optional for S3. */
69
- endpoint?: string;
70
52
  /**
71
53
  * Partitioning mode. `true` partitions by write timestamp, `false` disables partitioning, or a string for field-based/custom partitioning.
72
54
  * @default true
@@ -81,52 +63,38 @@ interface MutationConfig {
81
63
  /**
82
64
  * Zod schema for the mutation configuration object.
83
65
  */
84
- declare const mutationConfigSchema: z.ZodObject<{
66
+ export declare const mutationConfigSchema: z.ZodObject<{
85
67
  loadStrategy: z.ZodEnum<{
86
68
  full_load: "full_load";
87
69
  full_load_append: "full_load_append";
88
70
  append: "append";
89
71
  }>;
90
- type: z.ZodDefault<z.ZodEnum<{
91
- s3: "s3";
92
- minio: "minio";
93
- }>>;
94
- bucket: z.ZodString;
95
72
  basePath: z.ZodString;
96
- region: z.ZodOptional<z.ZodString>;
97
- endpoint: z.ZodOptional<z.ZodString>;
98
73
  partitioning: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
99
74
  partitioningFormat: z.ZodOptional<z.ZodString>;
100
75
  }, z.core.$strip>;
101
76
  /**
102
77
  * Zod schema for the mutation field: either `false` (disabled) or a config object (enabled).
103
78
  */
104
- declare const mutationSchema: z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
79
+ export declare const mutationSchema: z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
105
80
  loadStrategy: z.ZodEnum<{
106
81
  full_load: "full_load";
107
82
  full_load_append: "full_load_append";
108
83
  append: "append";
109
84
  }>;
110
- type: z.ZodDefault<z.ZodEnum<{
111
- s3: "s3";
112
- minio: "minio";
113
- }>>;
114
- bucket: z.ZodString;
115
85
  basePath: z.ZodString;
116
- region: z.ZodOptional<z.ZodString>;
117
- endpoint: z.ZodOptional<z.ZodString>;
118
86
  partitioning: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
119
87
  partitioningFormat: z.ZodOptional<z.ZodString>;
120
88
  }, z.core.$strip>]>;
121
89
  /**
122
90
  * Supported primitive types for field definitions.
123
91
  */
124
- declare const primitiveTypes: readonly ["String", "Integer", "Float", "Boolean", "Date", "DateTime"];
125
- type PrimitiveType = (typeof primitiveTypes)[number];
92
+ export declare const primitiveTypes: readonly ["String", "Integer", "Float", "Boolean", "Date", "DateTime"];
93
+ export type PrimitiveType = (typeof primitiveTypes)[number];
126
94
  /**
127
95
  * Field-level validation refinement types.
128
96
  */
129
- type FieldValidation = {
97
+ export type FieldValidation = {
130
98
  type: "email";
131
99
  } | {
132
100
  type: "url";
@@ -145,7 +113,7 @@ type FieldValidation = {
145
113
  /**
146
114
  * Field-level options for mutation input validation.
147
115
  */
148
- interface FieldOptions {
116
+ export interface FieldOptions {
149
117
  /**
150
118
  * Whether the field is required in mutation input.
151
119
  * @default false
@@ -165,16 +133,16 @@ interface FieldOptions {
165
133
  /**
166
134
  * Zod schema for field validation refinements.
167
135
  */
168
- declare const fieldValidationSchema: z.ZodType<FieldValidation>;
136
+ export declare const fieldValidationSchema: z.ZodType<FieldValidation>;
169
137
  /**
170
138
  * Zod schema for field-level options.
171
139
  */
172
- declare const fieldOptionsSchema: z.ZodType<FieldOptions>;
173
- interface ArrayItemDefinition {
140
+ export declare const fieldOptionsSchema: z.ZodType<FieldOptions>;
141
+ export interface ArrayItemDefinition {
174
142
  type: PrimitiveType | "Object";
175
143
  fields?: FieldDefinition[];
176
144
  }
177
- interface FieldDefinition {
145
+ export interface FieldDefinition {
178
146
  name: string;
179
147
  type: PrimitiveType | "Object" | "Array";
180
148
  fields?: FieldDefinition[];
@@ -185,15 +153,16 @@ interface FieldDefinition {
185
153
  * Zod schema for field definitions using a discriminated union on "type".
186
154
  * Supports recursive nesting via z.lazy for Object fields and Array items.
187
155
  */
188
- declare const fieldDefinitionSchema: z.ZodType<FieldDefinition>;
156
+ export declare const fieldDefinitionSchema: z.ZodType<FieldDefinition>;
189
157
  /**
190
158
  * Zod schema for the complete endpoint definition format.
191
159
  */
192
- declare const endpointDefinitionSchema: z.ZodObject<{
160
+ export declare const endpointDefinitionSchema: z.ZodObject<{
193
161
  version: z.ZodLiteral<"1.0">;
194
162
  tableName: z.ZodString;
195
163
  catalog: z.ZodString;
196
164
  schema: z.ZodString;
165
+ dataSource: z.ZodOptional<z.ZodString>;
197
166
  fields: z.ZodArray<z.ZodType<FieldDefinition, unknown, z.core.$ZodTypeInternals<FieldDefinition, unknown>>>;
198
167
  mutation: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
199
168
  loadStrategy: z.ZodEnum<{
@@ -201,26 +170,18 @@ declare const endpointDefinitionSchema: z.ZodObject<{
201
170
  full_load_append: "full_load_append";
202
171
  append: "append";
203
172
  }>;
204
- type: z.ZodDefault<z.ZodEnum<{
205
- s3: "s3";
206
- minio: "minio";
207
- }>>;
208
- bucket: z.ZodString;
209
173
  basePath: z.ZodString;
210
- region: z.ZodOptional<z.ZodString>;
211
- endpoint: z.ZodOptional<z.ZodString>;
212
174
  partitioning: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
213
175
  partitioningFormat: z.ZodOptional<z.ZodString>;
214
176
  }, z.core.$strip>]>>;
215
177
  }, z.core.$strip>;
216
- type EndpointDefinitionFormat = z.infer<typeof endpointDefinitionSchema>;
178
+ export type EndpointDefinitionFormat = z.infer<typeof endpointDefinitionSchema>;
217
179
  /**
218
180
  * Checks for duplicate field names at the same nesting level within a list of field definitions.
219
181
  * Returns an array of objects describing each duplicate found, including the field name and path.
220
182
  */
221
- declare function findDuplicateFieldNames(fields: FieldDefinition[], path?: string[]): {
183
+ export declare function findDuplicateFieldNames(fields: FieldDefinition[], path?: string[]): {
222
184
  name: string;
223
185
  path: string[];
224
186
  }[];
225
- //#endregion
226
- export { ArrayItemDefinition, EndpointDefinitionFormat, FieldDefinition, FieldOptions, FieldValidation, LoadStrategy, MutationConfig, PartitioningComponent, PartitioningFormat, PartitioningValue, PrimitiveType, StorageType, endpointDefinitionSchema, fieldDefinitionSchema, fieldNamePattern, fieldOptionsSchema, fieldValidationSchema, findDuplicateFieldNames, loadStrategies, metadataFieldPattern, mutationConfigSchema, mutationSchema, partitioningComponents, partitioningFormats, primitiveTypes, storageTypes, validatePartitioningFormat };
187
+ export type { LoadStrategy };
@@ -1 +1 @@
1
- import{z as e}from"zod";const t=/^[a-zA-Z_][a-zA-Z0-9_]{0,63}$/u,n=/^[a-zA-Z_][a-zA-Z0-9_]{0,127}$/u,r=[`full_load`,`full_load_append`,`append`],i=[`s3`,`minio`],a=[`year`,`year/month`,`year/month/day`],o=[`year`,`month`,`day`,`hour`,`minute`,`second`];function s(e){if(!(e.includes(`/`)||e.includes(`:`)))return t.test(e)?null:`Invalid partition field name "${e}". Must match pattern: letters/underscores, no leading digit, max 64 chars.`;let n=e.split(`/`);for(let r of n){if(r===``)return`Invalid partition format: empty segment found in "${e}".`;if(r.includes(`:`)){let e=r.split(`:`);if(e.length!==2)return`Invalid partition segment "${r}": expected format "fieldname:component".`;let[n,i]=e;if(!t.test(n))return`Invalid field name "${n}" in partition segment "${r}".`;if(!o.includes(i))return`Invalid date component "${i}" in partition segment "${r}". Expected one of: ${o.join(`, `)}.`}else if(!t.test(r))return`Invalid field name "${r}" in partition format.`}return null}const c=e.object({loadStrategy:e.enum(r),type:e.enum(i).default(`s3`),bucket:e.string().min(1),basePath:e.string().min(1),region:e.string().optional(),endpoint:e.string().optional(),partitioning:e.union([e.boolean(),e.string().min(1)]).optional(),partitioningFormat:e.string().optional()}).superRefine((e,t)=>{if(e.type===`minio`&&!e.endpoint&&t.addIssue({code:`custom`,path:[`endpoint`],message:`Endpoint is required when storage type is 'minio'. Provide the MinIO server URL (e.g. http://minio:9000).`}),e.partitioning!==!1){if(typeof e.partitioning==`string`){let n=s(e.partitioning);if(n){t.addIssue({code:`custom`,path:[`partitioning`],message:n});return}if(e.partitioning.includes(`/`)||e.partitioning.includes(`:`))return}e.partitioningFormat!==void 0&&!a.includes(e.partitioningFormat)&&t.addIssue({code:`invalid_value`,values:[...a],path:[`partitioningFormat`],message:`Invalid partitioning format. Expected one of: ${a.join(`, `)}`})}}),l=e.union([e.literal(!1),c]),u=[`String`,`Integer`,`Float`,`Boolean`,`Date`,`DateTime`],d=e.union([e.object({type:e.literal(`email`)}),e.object({type:e.literal(`url`)}),e.object({type:e.literal(`uuid`)}),e.object({type:e.literal(`min`),value:e.number()}),e.object({type:e.literal(`max`),value:e.number()}),e.object({type:e.literal(`regex`),pattern:e.string()})]),f=e.object({required:e.boolean().optional(),validations:e.array(d).optional(),readOnly:e.boolean().optional()}),p=e.lazy(()=>e.discriminatedUnion(`type`,[e.object({name:e.string().regex(t),type:e.literal(`String`),options:f.optional()}),e.object({name:e.string().regex(t),type:e.literal(`Integer`),options:f.optional()}),e.object({name:e.string().regex(t),type:e.literal(`Float`),options:f.optional()}),e.object({name:e.string().regex(t),type:e.literal(`Boolean`),options:f.optional()}),e.object({name:e.string().regex(t),type:e.literal(`Date`),options:f.optional()}),e.object({name:e.string().regex(t),type:e.literal(`DateTime`),options:f.optional()}),e.object({name:e.string().regex(t),type:e.literal(`Object`),fields:e.array(p).min(1),options:f.optional()}),e.object({name:e.string().regex(t),type:e.literal(`Array`),items:e.union([e.object({type:e.enum(u)}),e.object({type:e.literal(`Object`),fields:e.array(p).min(1)})]),options:f.optional()})])),m=e.object({version:e.literal(`1.0`),tableName:e.string().regex(n),catalog:e.string().regex(n),schema:e.string().regex(n),fields:e.array(p),mutation:l.optional()});function h(e,t=[]){let n=[],r=new Set;for(let i of e)r.has(i.name)?n.push({name:i.name,path:t}):r.add(i.name),i.type===`Object`&&i.fields&&n.push(...h(i.fields,[...t,i.name])),i.type===`Array`&&i.items?.type===`Object`&&i.items.fields&&n.push(...h(i.items.fields,[...t,i.name,`items`]));return n}export{m as endpointDefinitionSchema,p as fieldDefinitionSchema,t as fieldNamePattern,f as fieldOptionsSchema,d as fieldValidationSchema,h as findDuplicateFieldNames,r as loadStrategies,n as metadataFieldPattern,c as mutationConfigSchema,l as mutationSchema,o as partitioningComponents,a as partitioningFormats,u as primitiveTypes,i as storageTypes,s as validatePartitioningFormat};
1
+ import{z as e}from"zod";const t=/^[a-zA-Z_][a-zA-Z0-9_]{0,63}$/u,n=/^[a-zA-Z_][a-zA-Z0-9_]{0,127}$/u,r=[`full_load`,`full_load_append`,`append`],i=[`year`,`year/month`,`year/month/day`],a=[`year`,`month`,`day`,`hour`,`minute`,`second`];function o(e){if(!(e.includes(`/`)||e.includes(`:`)))return t.test(e)?null:`Invalid partition field name "${e}". Must match pattern: letters/underscores, no leading digit, max 64 chars.`;let n=e.split(`/`);for(let r of n){if(r===``)return`Invalid partition format: empty segment found in "${e}".`;if(r.includes(`:`)){let e=r.split(`:`);if(e.length!==2)return`Invalid partition segment "${r}": expected format "fieldname:component".`;let[n,i]=e;if(!t.test(n))return`Invalid field name "${n}" in partition segment "${r}".`;if(!a.includes(i))return`Invalid date component "${i}" in partition segment "${r}". Expected one of: ${a.join(`, `)}.`}else if(!t.test(r))return`Invalid field name "${r}" in partition format.`}return null}const s=e.object({loadStrategy:e.enum(r),basePath:e.string().min(1),partitioning:e.union([e.boolean(),e.string().min(1)]).optional(),partitioningFormat:e.string().optional()}).superRefine((e,t)=>{if(e.partitioning!==!1){if(typeof e.partitioning==`string`){let n=o(e.partitioning);if(n){t.addIssue({code:`custom`,path:[`partitioning`],message:n});return}if(e.partitioning.includes(`/`)||e.partitioning.includes(`:`))return}e.partitioningFormat!==void 0&&!i.includes(e.partitioningFormat)&&t.addIssue({code:`invalid_value`,values:[...i],path:[`partitioningFormat`],message:`Invalid partitioning format. Expected one of: ${i.join(`, `)}`})}}),c=e.union([e.literal(!1),s]),l=[`String`,`Integer`,`Float`,`Boolean`,`Date`,`DateTime`],u=e.union([e.object({type:e.literal(`email`)}),e.object({type:e.literal(`url`)}),e.object({type:e.literal(`uuid`)}),e.object({type:e.literal(`min`),value:e.number()}),e.object({type:e.literal(`max`),value:e.number()}),e.object({type:e.literal(`regex`),pattern:e.string()})]),d=e.object({required:e.boolean().optional(),validations:e.array(u).optional(),readOnly:e.boolean().optional()}),f=e.lazy(()=>e.discriminatedUnion(`type`,[e.object({name:e.string().regex(t),type:e.literal(`String`),options:d.optional()}),e.object({name:e.string().regex(t),type:e.literal(`Integer`),options:d.optional()}),e.object({name:e.string().regex(t),type:e.literal(`Float`),options:d.optional()}),e.object({name:e.string().regex(t),type:e.literal(`Boolean`),options:d.optional()}),e.object({name:e.string().regex(t),type:e.literal(`Date`),options:d.optional()}),e.object({name:e.string().regex(t),type:e.literal(`DateTime`),options:d.optional()}),e.object({name:e.string().regex(t),type:e.literal(`Object`),fields:e.array(f).min(1),options:d.optional()}),e.object({name:e.string().regex(t),type:e.literal(`Array`),items:e.union([e.object({type:e.enum(l)}),e.object({type:e.literal(`Object`),fields:e.array(f).min(1)})]),options:d.optional()})])),p=e.object({version:e.literal(`1.0`),tableName:e.string().regex(n),catalog:e.string().regex(n),schema:e.string().regex(n),dataSource:e.string().min(1).optional(),fields:e.array(f),mutation:c.optional()});function m(e,t=[]){let n=[],r=/* @__PURE__ */ new Set;for(let i of e)r.has(i.name)?n.push({name:i.name,path:t}):r.add(i.name),i.type===`Object`&&i.fields&&n.push(...m(i.fields,[...t,i.name])),i.type===`Array`&&i.items?.type===`Object`&&i.items.fields&&n.push(...m(i.items.fields,[...t,i.name,`items`]));return n}export{p as endpointDefinitionSchema,f as fieldDefinitionSchema,t as fieldNamePattern,d as fieldOptionsSchema,u as fieldValidationSchema,m as findDuplicateFieldNames,r as loadStrategies,n as metadataFieldPattern,s as mutationConfigSchema,c as mutationSchema,a as partitioningComponents,i as partitioningFormats,l as primitiveTypes,o as validatePartitioningFormat};
@@ -1,7 +1,5 @@
1
- import { t as JSONSchema7 } from "./index-CGZiTFRE.mjs";
2
-
3
- //#region src/graphql-schema.d.ts
4
- interface CurrentModelResponse {
1
+ import { JSONSchema7 } from "json-schema";
2
+ export interface CurrentModelResponse {
5
3
  name: string;
6
4
  rawFieldName: string;
7
5
  transformed: boolean;
@@ -13,7 +11,7 @@ interface CurrentModelResponse {
13
11
  nullable: boolean;
14
12
  filter: boolean;
15
13
  }
16
- interface ModelResponse {
14
+ export interface ModelResponse {
17
15
  root: boolean;
18
16
  modelName: string;
19
17
  interfaceName: string;
@@ -21,11 +19,11 @@ interface ModelResponse {
21
19
  transformFields: string[][];
22
20
  dateTimeFields: string[];
23
21
  }
24
- interface FilterFieldInput {
22
+ export interface FilterFieldInput {
25
23
  name: string;
26
24
  type: string;
27
25
  }
28
- type FieldDefinitionResponse = {
26
+ export type FieldDefinitionResponse = {
29
27
  graphqlType: string;
30
28
  graphqlTplType: string;
31
29
  interfaceType: string;
@@ -45,7 +43,7 @@ type FieldDefinitionResponse = {
45
43
  /**
46
44
  * Parameters for generateModel.
47
45
  */
48
- interface GenerateModelProps {
46
+ export interface GenerateModelProps {
49
47
  /** The JSON Schema source definition to generate a model from. */
50
48
  source: JSONSchema7;
51
49
  /** The name of the model being generated. */
@@ -60,21 +58,15 @@ interface GenerateModelProps {
60
58
  /**
61
59
  * Sanitizes a raw field name into a valid GraphQL/TypeScript identifier-like key.
62
60
  */
63
- declare function sanitizeFieldName(rawFieldName: string): string;
61
+ export declare function sanitizeFieldName(rawFieldName: string): string;
64
62
  /**
65
63
  * Generates a GraphQL model definition from JSON Schema.
66
64
  */
67
- declare const generateModel: ({
68
- source,
69
- name,
70
- parent,
71
- models,
72
- isRoot
73
- }: GenerateModelProps) => Record<string, ModelResponse>;
65
+ export declare const generateModel: ({ source, name, parent, models, isRoot }: GenerateModelProps) => Record<string, ModelResponse>;
74
66
  /**
75
67
  * Parameters for generateFieldDefinition.
76
68
  */
77
- interface GenerateFieldDefinitionProps {
69
+ export interface GenerateFieldDefinitionProps {
78
70
  /** The sanitized field name. */
79
71
  fieldName: string;
80
72
  /** The original raw field name from the schema. */
@@ -87,11 +79,4 @@ interface GenerateFieldDefinitionProps {
87
79
  /**
88
80
  * Generates field definitions for a single model property.
89
81
  */
90
- declare const generateFieldDefinition: ({
91
- fieldName,
92
- rawFieldName,
93
- fieldDefinition,
94
- parent
95
- }: GenerateFieldDefinitionProps) => FieldDefinitionResponse;
96
- //#endregion
97
- export { CurrentModelResponse, FieldDefinitionResponse, FilterFieldInput, GenerateFieldDefinitionProps, GenerateModelProps, ModelResponse, generateFieldDefinition, generateModel, sanitizeFieldName };
82
+ export declare const generateFieldDefinition: ({ fieldName, rawFieldName, fieldDefinition, parent }: GenerateFieldDefinitionProps) => FieldDefinitionResponse;
@@ -1 +1 @@
1
- import e from"@lakeql/helpers/special-characters";import{capitalize as t,omit as n}from"lodash-es";function r(t){let n=e(t).replaceAll(/[^a-zA-Z0-9_]/gu,`_`).replaceAll(/_+/gu,`_`).replaceAll(/^_+|_+$/gu,``);return n.length===0?`field`:n.replace(/^(?<digit>\d)/u,`_$<digit>`)}function i(e,t,n){if(!t.has(e))return t.add(e),e;throw Error(`Field name collision after normalization: "${n}" -> "${e}".`)}const a=({source:e,name:s,parent:c,models:l={},isRoot:u=!0})=>{let d=n(e,[`additionalProperties`]),f={...l},p=new Set,m={};for(let[e,t]of Object.entries(d.properties)){let n=i(r(e),p,e),l=o({fieldDefinition:t,fieldName:n,parent:c??s,rawFieldName:e});m[n]={filter:l.filter,graphqlTplType:l.graphqlTplType,graphqlType:l.graphqlType,interfaceName:l.interfaceName,interfaceType:l.interfaceType,isArray:l.isArray??!1,name:n,nullable:!0,rawFieldName:e,transformed:n!==e},l.subModel!==!1&&Object.assign(f,a({isRoot:!1,models:f,name:n,parent:c??s,source:l.subModel}))}let h=u?s:`${c}_${t(s)}`;return f[h]={dateTimeFields:Object.values(m).filter(e=>e.graphqlType===`DateTime`).map(e=>e.rawFieldName),fields:m,interfaceName:`${h}Interface`,modelName:h,root:u,transformFields:Object.values(m).filter(e=>e.transformed).map(e=>[e.name,e.rawFieldName])},f},o=({fieldName:e,rawFieldName:n,fieldDefinition:r,parent:i})=>{let a=t(e);switch(r.type){case`string`:switch(r.format){case`date`:return{filter:!0,graphqlTplType:`'Date'`,graphqlType:`Date`,interfaceType:`Date`,subModel:!1};case`date-time`:return{filter:!0,graphqlTplType:`'DateTime'`,graphqlType:`DateTime`,interfaceType:`Date`,subModel:!1};default:return{filter:!0,graphqlTplType:`'String'`,graphqlType:`String`,interfaceType:`string`,subModel:!1}}case`number`:return{filter:!0,graphqlTplType:`'Float'`,graphqlType:`Float`,interfaceType:`number`,subModel:!1};case`integer`:return{filter:!0,graphqlTplType:`'Int'`,graphqlType:`Int`,interfaceType:`number`,subModel:!1};case`boolean`:return{filter:!0,graphqlTplType:`'Boolean'`,graphqlType:`Boolean`,interfaceType:`boolean`,subModel:!1};case`array`:if(r.items.type!==`object`){let t=o({fieldDefinition:r.items,fieldName:e,rawFieldName:n});return{filter:!1,graphqlTplType:`['${t.graphqlType}']`,graphqlType:`[${t.graphqlType}]`,interfaceType:`${t.interfaceType}[]`,isArray:!0,subModel:!1}}return{filter:!1,graphqlTplType:`[${i}_${a}]`,graphqlType:`[${i}_${a}]`,interfaceName:`${i}_${a}Interface[]`,interfaceType:`${i}_${a}[]`,isArray:!0,subModel:r.items};case`object`:return{filter:!1,graphqlTplType:`${i}_${a}`,graphqlType:`${i}_${a}`,interfaceName:`${i}_${a}Interface`,interfaceType:`${i}_${a}`,subModel:r};default:return{filter:!1,graphqlTplType:`Null`,graphqlType:`Null`,interfaceType:`null`,subModel:!1}}};export{o as generateFieldDefinition,a as generateModel,r as sanitizeFieldName};
1
+ import e from"@lakeql/helpers/special-characters";import{toCapitalize as t}from"@lakeql/helpers/string-case";import{omit as n}from"es-toolkit";function r(t){let n=e(t).replaceAll(/[^a-zA-Z0-9_]/gu,`_`).replaceAll(/_+/gu,`_`).replaceAll(/^_+|_+$/gu,``);return n.length===0?`field`:n.replace(/^(?<digit>\d)/u,`_$<digit>`)}function i(e,t,n){if(!t.has(e))return t.add(e),e;throw Error(`Field name collision after normalization: "${n}" -> "${e}".`)}const a=({source:e,name:s,parent:c,models:l={},isRoot:u=!0})=>{let d=n(e,[`additionalProperties`]),f={...l},p=/* @__PURE__ */ new Set,m={};for(let[e,t]of Object.entries(d.properties)){let n=i(r(e),p,e),l=o({fieldDefinition:t,fieldName:n,parent:c??s,rawFieldName:e});m[n]={filter:l.filter,graphqlTplType:l.graphqlTplType,graphqlType:l.graphqlType,interfaceName:l.interfaceName,interfaceType:l.interfaceType,isArray:l.isArray??!1,name:n,nullable:!0,rawFieldName:e,transformed:n!==e},l.subModel!==!1&&Object.assign(f,a({isRoot:!1,models:f,name:n,parent:c??s,source:l.subModel}))}let h=u?s:`${c}_${t(s)}`;return f[h]={dateTimeFields:Object.values(m).filter(e=>e.graphqlType===`DateTime`).map(e=>e.rawFieldName),fields:m,interfaceName:`${h}Interface`,modelName:h,root:u,transformFields:Object.values(m).filter(e=>e.transformed).map(e=>[e.name,e.rawFieldName])},f},o=({fieldName:e,rawFieldName:n,fieldDefinition:r,parent:i})=>{let a=t(e);switch(r.type){case`string`:switch(r.format){case`date`:return{filter:!0,graphqlTplType:`'Date'`,graphqlType:`Date`,interfaceType:`Date`,subModel:!1};case`date-time`:return{filter:!0,graphqlTplType:`'DateTime'`,graphqlType:`DateTime`,interfaceType:`Date`,subModel:!1};default:return{filter:!0,graphqlTplType:`'String'`,graphqlType:`String`,interfaceType:`string`,subModel:!1}}case`number`:return{filter:!0,graphqlTplType:`'Float'`,graphqlType:`Float`,interfaceType:`number`,subModel:!1};case`integer`:return{filter:!0,graphqlTplType:`'Int'`,graphqlType:`Int`,interfaceType:`number`,subModel:!1};case`boolean`:return{filter:!0,graphqlTplType:`'Boolean'`,graphqlType:`Boolean`,interfaceType:`boolean`,subModel:!1};case`array`:if(r.items.type!==`object`){let t=o({fieldDefinition:r.items,fieldName:e,rawFieldName:n});return{filter:!1,graphqlTplType:`['${t.graphqlType}']`,graphqlType:`[${t.graphqlType}]`,interfaceType:`${t.interfaceType}[]`,isArray:!0,subModel:!1}}return{filter:!1,graphqlTplType:`[${i}_${a}]`,graphqlType:`[${i}_${a}]`,interfaceName:`${i}_${a}Interface[]`,interfaceType:`${i}_${a}[]`,isArray:!0,subModel:r.items};case`object`:return{filter:!1,graphqlTplType:`${i}_${a}`,graphqlType:`${i}_${a}`,interfaceName:`${i}_${a}Interface`,interfaceType:`${i}_${a}`,subModel:r};default:return{filter:!1,graphqlTplType:`Null`,graphqlType:`Null`,interfaceType:`null`,subModel:!1}}};export{o as generateFieldDefinition,a as generateModel,r as sanitizeFieldName};
@@ -1,6 +1,4 @@
1
- import { t as JSONSchema7 } from "./index-CGZiTFRE.mjs";
2
-
3
- //#region src/hive-table.d.ts
1
+ import { JSONSchema7 } from "json-schema";
4
2
  type SqlFieldDefinition = [string, string];
5
3
  interface SchemaDefinition {
6
4
  type: string;
@@ -16,33 +14,29 @@ type ParquetField = Record<string, string | [string, ParquetField] | [string, {
16
14
  /**
17
15
  * Parameters for generateSqlSchema.
18
16
  */
19
- interface GenerateSqlSchemaProps {
17
+ export interface GenerateSqlSchemaProps {
20
18
  /** The JSON Schema property definitions to generate SQL columns from. */
21
19
  definition: Record<string, SchemaDefinition>;
22
20
  }
23
21
  /**
24
22
  * Generates SQL column definitions from parsed columns.
25
23
  */
26
- declare function generateSqlSchema({
27
- definition
28
- }: GenerateSqlSchemaProps): SqlFieldDefinition[];
24
+ export declare function generateSqlSchema({ definition }: GenerateSqlSchemaProps): SqlFieldDefinition[];
29
25
  /**
30
26
  * Parameters for parquetTransformer.
31
27
  */
32
- interface ParquetTransformerProps {
28
+ export interface ParquetTransformerProps {
33
29
  /** The JSON Schema property definitions to transform for Parquet format. */
34
30
  definition: Record<string, JSONSchema7>;
35
31
  }
36
32
  /**
37
33
  * Transforms column definitions for Parquet format.
38
34
  */
39
- declare function parquetTransformer({
40
- definition
41
- }: ParquetTransformerProps): ParquetField;
35
+ export declare function parquetTransformer({ definition }: ParquetTransformerProps): ParquetField;
42
36
  /**
43
37
  * Parameters for generateCreateTableStatement.
44
38
  */
45
- interface GenerateCreateTableStatementProps {
39
+ export interface GenerateCreateTableStatementProps {
46
40
  /** The Hive schema name. */
47
41
  schema: string;
48
42
  /** The table name. */
@@ -57,12 +51,5 @@ interface GenerateCreateTableStatementProps {
57
51
  /**
58
52
  * Generates a full CREATE TABLE DDL statement.
59
53
  */
60
- declare function generateCreateTableStatement({
61
- schema,
62
- tableName,
63
- bucketName,
64
- bucketPath,
65
- definition
66
- }: GenerateCreateTableStatementProps): string;
67
- //#endregion
68
- export { GenerateCreateTableStatementProps, GenerateSqlSchemaProps, ParquetTransformerProps, generateCreateTableStatement, generateSqlSchema, parquetTransformer };
54
+ export declare function generateCreateTableStatement({ schema, tableName, bucketName, bucketPath, definition }: GenerateCreateTableStatementProps): string;
55
+ export {};
@@ -1,9 +1,7 @@
1
1
  import { FieldDefinition } from "./endpoint-schema.mjs";
2
- import { t as JSONSchema7 } from "./index-CGZiTFRE.mjs";
2
+ import { JSONSchema7 } from "json-schema";
3
3
  import { JSONType } from "json-column-parser/lib/common/types/type.common";
4
-
5
- //#region src/json-schema.d.ts
6
- declare function generateJsonSchema(parsedColumns: Record<string, JSONType>): JSONSchema7;
4
+ export declare function generateJsonSchema(parsedColumns: Record<string, JSONType>): JSONSchema7;
7
5
  /**
8
6
  * Converts an array of FieldDefinitions to a complete JSON Schema Draft-07 document.
9
7
  *
@@ -19,6 +17,4 @@ declare function generateJsonSchema(parsedColumns: Record<string, JSONType>): JS
19
17
  * - Array (primitive) → {type: "array", items: {primitive schema}}
20
18
  * - Array (object) → {type: "array", items: {type: "object", properties: {...}, additionalProperties: false}}
21
19
  */
22
- declare function generateJsonSchemaFromFields(fields: FieldDefinition[]): JSONSchema7;
23
- //#endregion
24
- export { generateJsonSchema, generateJsonSchemaFromFields };
20
+ export declare function generateJsonSchemaFromFields(fields: FieldDefinition[]): JSONSchema7;
@@ -1 +1 @@
1
- import{isObject as e}from"@lakeql/helpers/object-helper";import{createRegExp as t,global as n,not as r}from"magic-regexp";function i(e){return{$schema:`https://json-schema.org/draft-07/schema#`,...s(e),additionalProperties:!1}}function a(e){let i=t(r.letter,[n]),a=e.toString().replace(i,``);switch(a){case`varchar`:return{type:`string`};case`decimal`:case`double`:case`float`:return{type:`number`};case`integer`:case`bigint`:return{type:`integer`};case`boolean`:return{type:`boolean`};case`timestamp`:return{format:`date-time`,type:`string`};case`date`:return{format:`date`,type:`string`};default:throw Error(`Type ${a.toString()} is unknown.`)}}function o(t){if(t.length>1)throw Error("We expect that an array has only one element ( e.g. a primitive like `varchar` or an object like `row()`.");if(Array.isArray(t[0]))throw TypeError(`We currently do not support 'array of array'. Feel free to raise an issue.`);if(typeof t[0]==`string`)return{items:a(t[0]),type:`array`};if(e(t[0]))return{items:s(t[0]),type:`array`};throw Error("Unexpected case in `json-generator.handleArray`")}function s(t){let n={additionalProperties:!1,properties:{},type:`object`};for(let[r,i]of Object.entries(t))typeof i==`string`&&(n.properties[r]=a(i)),Array.isArray(i)&&(n.properties[r]=o(i)),e(i)&&(n.properties[r]=s(i));return n}function c(e){switch(e){case`String`:return{type:`string`};case`Integer`:return{type:`integer`};case`Float`:return{type:`number`};case`Boolean`:return{type:`boolean`};case`Date`:return{type:`string`,format:`date`};case`DateTime`:return{type:`string`,format:`date-time`};default:return{type:`string`}}}function l(e){return e.type===`Object`&&e.fields?{type:`object`,properties:d(e.fields),additionalProperties:!1}:c(e.type)}function u(e){switch(e.type){case`Object`:return{type:`object`,properties:d(e.fields??[]),additionalProperties:!1};case`Array`:return{type:`array`,items:e.items?l(e.items):{type:`string`}};default:return c(e.type)}}function d(e){let t={};for(let n of e)t[n.name]=u(n);return t}function f(e){return{$schema:`https://json-schema.org/draft-07/schema#`,type:`object`,properties:d(e),additionalProperties:!1}}export{i as generateJsonSchema,f as generateJsonSchemaFromFields};
1
+ import{isObject as e}from"@lakeql/helpers/object-helper";const t=/[^a-zA-Z]/gu;function n(e){return{$schema:`https://json-schema.org/draft-07/schema#`,...a(e),additionalProperties:!1}}function r(e){let n=e.toString().replaceAll(t,``);switch(n){case`varchar`:return{type:`string`};case`decimal`:case`double`:case`float`:return{type:`number`};case`integer`:case`bigint`:return{type:`integer`};case`boolean`:return{type:`boolean`};case`timestamp`:return{format:`date-time`,type:`string`};case`date`:return{format:`date`,type:`string`};default:throw Error(`Type ${n.toString()} is unknown.`)}}function i(t){if(t.length>1)throw Error("We expect that an array has only one element ( e.g. a primitive like `varchar` or an object like `row()`.");if(Array.isArray(t[0]))throw TypeError(`We currently do not support 'array of array'. Feel free to raise an issue.`);if(typeof t[0]==`string`)return{items:r(t[0]),type:`array`};if(e(t[0]))return{items:a(t[0]),type:`array`};throw Error("Unexpected case in `json-generator.handleArray`")}function a(t){let n={additionalProperties:!1,properties:{},type:`object`};for(let[o,s]of Object.entries(t))typeof s==`string`&&(n.properties[o]=r(s)),Array.isArray(s)&&(n.properties[o]=i(s)),e(s)&&(n.properties[o]=a(s));return n}function o(e){switch(e){case`String`:return{type:`string`};case`Integer`:return{type:`integer`};case`Float`:return{type:`number`};case`Boolean`:return{type:`boolean`};case`Date`:return{type:`string`,format:`date`};case`DateTime`:return{type:`string`,format:`date-time`};default:return{type:`string`}}}function s(e){return e.type===`Object`&&e.fields?{type:`object`,properties:l(e.fields),additionalProperties:!1}:o(e.type)}function c(e){switch(e.type){case`Object`:return{type:`object`,properties:l(e.fields??[]),additionalProperties:!1};case`Array`:return{type:`array`,items:e.items?s(e.items):{type:`string`}};default:return o(e.type)}}function l(e){let t={};for(let n of e)t[n.name]=c(n);return t}function u(e){return{$schema:`https://json-schema.org/draft-07/schema#`,type:`object`,properties:l(e),additionalProperties:!1}}export{n as generateJsonSchema,u as generateJsonSchemaFromFields};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lakeql/schema-generator",
3
- "version": "0.4.5",
4
- "description": "Generates GraphQL schemas, Hive table definitions, and JSON schemas from Trino metadata",
3
+ "version": "1.0.0",
4
+ "description": "Generates GraphQL schemas, Hive table definitions, and JSON schemas from data source metadata",
5
5
  "keywords": [
6
6
  "codegen",
7
7
  "graphql",
@@ -51,22 +51,21 @@
51
51
  }
52
52
  },
53
53
  "dependencies": {
54
- "kysely": "0.29.2",
55
- "lodash-es": "4.18.1",
56
- "magic-regexp": "0.11.0",
57
- "zod": "4.4.3",
58
- "@lakeql/helpers": "0.1.6"
54
+ "@lakeql/datasource": "1.0.0",
55
+ "@lakeql/helpers": "1.0.0",
56
+ "es-toolkit": "1.53.2",
57
+ "zod": "4.6.7"
59
58
  },
60
59
  "devDependencies": {
60
+ "@lakeql/tsconfig": "0.1.0",
61
+ "@lakeql/vitest-config": "0.1.0",
61
62
  "@types/json-schema": "7.0.15",
62
- "@types/lodash-es": "4.17.12",
63
- "@types/node": "24.13.2",
64
- "fast-check": "^4.8.0",
63
+ "@types/node": "24.19.2",
64
+ "fast-check": "4.10.2",
65
65
  "json-column-parser": "2.0.0",
66
- "tsdown": "0.22.3",
66
+ "tsdown": "0.23.7",
67
67
  "typescript": "6.0.3",
68
- "vitest": "4.1.9",
69
- "@lakeql/tsconfig": "0.1.0"
68
+ "vitest": "5.1.0"
70
69
  },
71
70
  "scripts": {
72
71
  "build": "tsdown",
@@ -1,140 +0,0 @@
1
- //#region ../../node_modules/.pnpm/@types+json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts
2
- // ==================================================================================================
3
- // JSON Schema Draft 07
4
- // ==================================================================================================
5
- // https://tools.ietf.org/html/draft-handrews-json-schema-validation-01
6
- // --------------------------------------------------------------------------------------------------
7
- /**
8
- * Primitive type
9
- * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.1.1
10
- */
11
- type JSONSchema7TypeName = "string" //
12
- | "number" | "integer" | "boolean" | "object" | "array" | "null";
13
- /**
14
- * Primitive type
15
- * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.1.1
16
- */
17
- type JSONSchema7Type = string //
18
- | number | boolean | JSONSchema7Object | JSONSchema7Array | null;
19
- // Workaround for infinite type recursion
20
- interface JSONSchema7Object {
21
- [key: string]: JSONSchema7Type;
22
- }
23
- // Workaround for infinite type recursion
24
- // https://github.com/Microsoft/TypeScript/issues/3496#issuecomment-128553540
25
- interface JSONSchema7Array extends Array<JSONSchema7Type> {}
26
- /**
27
- * Meta schema
28
- *
29
- * Recommended values:
30
- * - 'http://json-schema.org/schema#'
31
- * - 'http://json-schema.org/hyper-schema#'
32
- * - 'http://json-schema.org/draft-07/schema#'
33
- * - 'http://json-schema.org/draft-07/hyper-schema#'
34
- *
35
- * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-5
36
- */
37
- type JSONSchema7Version = string;
38
- /**
39
- * JSON Schema v7
40
- * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01
41
- */
42
- type JSONSchema7Definition = JSONSchema7 | boolean;
43
- interface JSONSchema7 {
44
- $id?: string | undefined;
45
- $ref?: string | undefined;
46
- $schema?: JSONSchema7Version | undefined;
47
- $comment?: string | undefined;
48
- /**
49
- * @see https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-00#section-8.2.4
50
- * @see https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validation-00#appendix-A
51
- */
52
- $defs?: {
53
- [key: string]: JSONSchema7Definition;
54
- } | undefined;
55
- /**
56
- * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.1
57
- */
58
- type?: JSONSchema7TypeName | JSONSchema7TypeName[] | undefined;
59
- enum?: JSONSchema7Type[] | undefined;
60
- const?: JSONSchema7Type | undefined;
61
- /**
62
- * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.2
63
- */
64
- multipleOf?: number | undefined;
65
- maximum?: number | undefined;
66
- exclusiveMaximum?: number | undefined;
67
- minimum?: number | undefined;
68
- exclusiveMinimum?: number | undefined;
69
- /**
70
- * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.3
71
- */
72
- maxLength?: number | undefined;
73
- minLength?: number | undefined;
74
- pattern?: string | undefined;
75
- /**
76
- * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.4
77
- */
78
- items?: JSONSchema7Definition | JSONSchema7Definition[] | undefined;
79
- additionalItems?: JSONSchema7Definition | undefined;
80
- maxItems?: number | undefined;
81
- minItems?: number | undefined;
82
- uniqueItems?: boolean | undefined;
83
- contains?: JSONSchema7Definition | undefined;
84
- /**
85
- * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.5
86
- */
87
- maxProperties?: number | undefined;
88
- minProperties?: number | undefined;
89
- required?: string[] | undefined;
90
- properties?: {
91
- [key: string]: JSONSchema7Definition;
92
- } | undefined;
93
- patternProperties?: {
94
- [key: string]: JSONSchema7Definition;
95
- } | undefined;
96
- additionalProperties?: JSONSchema7Definition | undefined;
97
- dependencies?: {
98
- [key: string]: JSONSchema7Definition | string[];
99
- } | undefined;
100
- propertyNames?: JSONSchema7Definition | undefined;
101
- /**
102
- * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.6
103
- */
104
- if?: JSONSchema7Definition | undefined;
105
- then?: JSONSchema7Definition | undefined;
106
- else?: JSONSchema7Definition | undefined;
107
- /**
108
- * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.7
109
- */
110
- allOf?: JSONSchema7Definition[] | undefined;
111
- anyOf?: JSONSchema7Definition[] | undefined;
112
- oneOf?: JSONSchema7Definition[] | undefined;
113
- not?: JSONSchema7Definition | undefined;
114
- /**
115
- * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-7
116
- */
117
- format?: string | undefined;
118
- /**
119
- * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-8
120
- */
121
- contentMediaType?: string | undefined;
122
- contentEncoding?: string | undefined;
123
- /**
124
- * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-9
125
- */
126
- definitions?: {
127
- [key: string]: JSONSchema7Definition;
128
- } | undefined;
129
- /**
130
- * @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-10
131
- */
132
- title?: string | undefined;
133
- description?: string | undefined;
134
- default?: JSONSchema7Type | undefined;
135
- readOnly?: boolean | undefined;
136
- writeOnly?: boolean | undefined;
137
- examples?: JSONSchema7Type | undefined;
138
- }
139
- //#endregion
140
- export { JSONSchema7 as t };