@rebasepro/codegen 0.13.0 → 0.13.1-canary.g249daa1

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.es.js CHANGED
@@ -129,7 +129,9 @@ function generateTypedefs(collections) {
129
129
  let resolvedRelations = {};
130
130
  try {
131
131
  resolvedRelations = resolveCollectionRelations(collection);
132
- } catch {}
132
+ } catch (e) {
133
+ console.warn(`[rebase] Could not resolve the relations of "${collection.slug}", so its generated type has no relation fields and none of their foreign-key columns. This is usually a circular import in the collection files — make sure the target is \`() => otherCollection\` and not evaluated at module load.\n ${e instanceof Error ? e.message : String(e)}`);
134
+ }
133
135
  lines.push(` ${toSafeIdentifier(collection.slug)}: {`);
134
136
  lines.push(" Row: {");
135
137
  const emittedKeys = /* @__PURE__ */ new Set();
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","names":[],"sources":["../src/utils.ts","../src/generate-types.ts","../src/index.ts"],"sourcesContent":["/**\n * Utility functions for the SDK generator\n */\n\n/**\n * Convert a slug/snake_case string to PascalCase\n * e.g. \"private_notes\" → \"PrivateNotes\"\n *\n * Capitals already inside a word are meaningful and are kept: lowercasing the\n * tail of every chunk turned \"TestEntities\" into \"Testentities\", which is what\n * ended up in the generated type names. SHOUTING_CASE is the one shape where\n * the tail is not meaningful, so it is folded down.\n */\nexport function toPascalCase(str: string): string {\n return str\n .split(/[_\\-\\s]+/)\n .filter(Boolean)\n .map(word => {\n const rest = /^[A-Z0-9]+$/.test(word) ? word.slice(1).toLowerCase() : word.slice(1);\n return word.charAt(0).toUpperCase() + rest;\n })\n .join(\"\");\n}\n\n/**\n * Convert a slug/snake_case string to camelCase\n * e.g. \"private_notes\" → \"privateNotes\"\n */\nexport function toCamelCase(str: string): string {\n if (!/[_\\-\\s]/.test(str)) {\n return str.charAt(0).toLowerCase() + str.slice(1);\n }\n const pascal = toPascalCase(str);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n\n/**\n * Convert a slug to a safe JS identifier\n * e.g. \"private-notes\" → \"privateNotes\"\n */\nexport function toSafeIdentifier(str: string): string {\n return toCamelCase(str.replace(/[^a-zA-Z0-9_]/g, \"_\"));\n}\n\n/**\n * Indent a block of text by a given number of spaces\n */\nexport function indent(text: string, spaces: number): string {\n const pad = \" \".repeat(spaces);\n return text\n .split(\"\\n\")\n .map(line => (line.trim() ? pad + line : line))\n .join(\"\\n\");\n}\n","import { CollectionConfig, PostgresCollectionConfig, Property, Properties, MapProperty, ArrayProperty, Relation, RelationProperty, StringProperty, NumberProperty, ResolvedRelation } from \"@rebasepro/types\";\nimport { resolveCollectionRelations } from \"@rebasepro/common\";\nimport { toPascalCase, toSafeIdentifier } from \"./utils\";\n\nfunction propertyToTypeScriptType(prop: Property): string {\n switch (prop.type) {\n case \"string\": {\n const sp = prop as StringProperty;\n if (sp.enum) {\n const ids = Array.isArray(sp.enum)\n ? sp.enum.map((e: string | number | { id: string | number }) => typeof e === \"object\" ? String(e.id) : String(e))\n : Object.keys(sp.enum);\n return ids.map(v => `\"${v}\"`).join(\" | \");\n }\n return \"string\";\n }\n case \"number\": {\n const np = prop as NumberProperty;\n if (np.enum) {\n const ids = Array.isArray(np.enum)\n ? np.enum.map((e: string | number | { id: string | number }) => typeof e === \"object\" ? String(e.id) : String(e))\n : Object.keys(np.enum);\n return ids.join(\" | \");\n }\n return \"number\";\n }\n case \"boolean\":\n return \"boolean\";\n case \"date\":\n return \"string\"; // ISO 8601 string over the wire\n case \"geopoint\":\n return \"{ latitude: number; longitude: number; }\";\n case \"reference\":\n return \"string | number\";\n case \"relation\":\n return \"string | number\";\n case \"map\": {\n const mapProp = prop as MapProperty;\n if (mapProp.properties) {\n const inner = Object.entries(mapProp.properties)\n .map(([k, v]) => `${toSafeIdentifier(k)}: ${propertyToTypeScriptType(v as Property)};`)\n .join(\" \");\n return `{ ${inner} }`;\n }\n return \"Record<string, unknown>\";\n }\n case \"array\": {\n const arrProp = prop as ArrayProperty;\n if (arrProp.of) {\n return `Array<${propertyToTypeScriptType(arrProp.of as Property)}>`;\n }\n return \"Array<unknown>\";\n }\n case \"vector\":\n return \"number[]\";\n case \"binary\":\n return \"string\";\n default:\n return \"unknown\";\n }\n}\n\n/**\n * Unwrap a relation target that arrived as a module namespace rather than the\n * collection itself — `target: () => import(\"./authors\")` is a common slip.\n */\nfunction resolveTargetCollection(relation: ResolvedRelation): CollectionConfig | undefined {\n try {\n let target = relation.target() as CollectionConfig & { default?: CollectionConfig; __esModule?: boolean };\n if (target && (target.default || target.__esModule)) {\n target = (target.default ?? target) as typeof target;\n }\n return target;\n } catch {\n return undefined;\n }\n}\n\n/** The TypeScript type of a foreign key: whatever the target's primary key is. */\nfunction foreignKeyType(relation: ResolvedRelation): string {\n const target = resolveTargetCollection(relation);\n if (!target?.properties) return \"string | number\";\n const idProp = Object.entries(target.properties).find(([_, p]) => (p as Record<string, unknown>).isId);\n if (!idProp) return \"string | number\";\n return (idProp[1] as Property).type === \"number\" ? \"number\" : \"string\";\n}\n\n/**\n * The type an *included* relation arrives as: the target's own row, inlined.\n *\n * This is what the read pipeline actually serves — `toRestRow` puts the\n * target's flat columns where the relation was, and the SDK and the HTTP API\n * both go through it. It is deliberately *not* a `{ __type: \"relation\" }`\n * envelope: that shape is the admin's view-model and never reaches a\n * developer's `find()`.\n *\n * Falls back to an open record when the target is not part of this generation\n * run, since there is no `Row` to point at.\n */\nfunction includedRelationType(relation: ResolvedRelation, knownSlugs: Set<string>): string {\n const target = resolveTargetCollection(relation);\n const slug = target?.slug ?? relation.targetSlug;\n const rowType = slug && knownSlugs.has(slug)\n ? `Database[${JSON.stringify(toSafeIdentifier(slug))}][\"Row\"]`\n : \"Record<string, unknown>\";\n return relation.cardinality === \"many\" ? `Array<${rowType}>` : rowType;\n}\n\nexport function generateTypedefs(collections: CollectionConfig[]): string {\n const knownSlugs = new Set(collections.map(c => c.slug).filter(Boolean) as string[]);\n const lines: string[] = [\n \"/**\",\n \" * This file was auto-generated by Rebase.\",\n \" * Do not make direct changes to the file.\",\n \" */\",\n \"\",\n \"export interface Database {\"\n ];\n\n for (const collection of collections) {\n const typeName = toPascalCase(collection.slug);\n const properties = (collection.properties ?? {}) as Properties;\n\n // Resolve relations\n let resolvedRelations: Record<string, ResolvedRelation> = {};\n try {\n resolvedRelations = resolveCollectionRelations(collection);\n } catch { /* ignore */ }\n\n lines.push(` ${toSafeIdentifier(collection.slug)}: {`);\n\n // ── Row Type ──\n lines.push(\" Row: {\");\n const emittedKeys = new Set<string>();\n\n // 1. Direct properties\n for (const [key, rawProp] of Object.entries(properties)) {\n const prop = rawProp as Property;\n if (prop.type === \"relation\") continue;\n\n const tsType = propertyToTypeScriptType(prop);\n const isRequired = prop.validation?.required;\n lines.push(` ${toSafeIdentifier(key)}${isRequired ? \"\" : \"?\"}: ${tsType};`);\n emittedKeys.add(key);\n }\n\n // 2. FK columns from relations\n for (const [relKey, relation] of Object.entries(resolvedRelations)) {\n if (relation.kind === \"belongsTo\" && relation.localKey) {\n const fkKey = relation.localKey;\n if (emittedKeys.has(fkKey)) continue;\n\n const fkType = foreignKeyType(relation);\n\n // A relation addressed by the same name as its own foreign key\n // is served *over* that column when the read includes it: the\n // query nests the target under the relation name, and the\n // scalar it shadows is gone. Both outcomes are real, so the\n // column is typed as both — which is what stops a plain\n // `const id: string = row.author_id` from compiling.\n const shadowedByInclude = relKey === fkKey;\n const tsType = shadowedByInclude\n ? `${fkType} | ${includedRelationType(relation, knownSlugs)}`\n : fkType;\n\n const isRequired = relation.validation?.required && !shadowedByInclude;\n lines.push(` ${toSafeIdentifier(fkKey)}${isRequired ? \"\" : \"?\"}: ${tsType};`);\n emittedKeys.add(fkKey);\n }\n }\n\n // 3. Relation fields — the target's own row, inlined.\n //\n // Optional throughout: a relation is only loaded when the read names it\n // in `include`, so it is absent from every other read.\n for (const [key, relation] of Object.entries(resolvedRelations)) {\n if (emittedKeys.has(key)) continue;\n lines.push(` ${toSafeIdentifier(key)}?: ${includedRelationType(relation, knownSlugs)};`);\n emittedKeys.add(key);\n }\n\n // A `relation` property whose relation could not be resolved — an\n // engine without relation support, or a target that did not load. It is\n // still a column on the row, so it is still typed, just not precisely.\n for (const [key, rawProp] of Object.entries(properties)) {\n if ((rawProp as Property).type !== \"relation\") continue;\n if (emittedKeys.has(key)) continue;\n lines.push(` ${toSafeIdentifier(key)}?: Record<string, unknown>;`);\n emittedKeys.add(key);\n }\n lines.push(\" };\");\n\n // ── Insert Type ──\n lines.push(\" Insert: {\");\n emittedKeys.clear();\n\n for (const [key, rawProp] of Object.entries(properties)) {\n const prop = rawProp as Property;\n if (prop.type === \"relation\") continue;\n const tsType = propertyToTypeScriptType(prop);\n const isRequired = prop.validation?.required;\n const typedProp = prop as StringProperty | NumberProperty;\n const isAutoId = \"isId\" in prop && typedProp.isId && typedProp.isId !== \"manual\" && typedProp.isId !== true;\n const isOptional = !isRequired || isAutoId;\n lines.push(` ${toSafeIdentifier(key)}${isOptional ? \"?\" : \"\"}: ${tsType};`);\n emittedKeys.add(key);\n }\n\n for (const [relKey, relation] of Object.entries(resolvedRelations)) {\n if (relation.kind === \"belongsTo\" && relation.localKey) {\n const fkKey = relation.localKey;\n if (emittedKeys.has(fkKey)) continue;\n const fkType = \"string | number\";\n // simple fallback\n const isRequired = relation.validation?.required;\n lines.push(` ${toSafeIdentifier(fkKey)}${isRequired ? \"\" : \"?\"}: ${fkType};`);\n emittedKeys.add(fkKey);\n }\n }\n lines.push(\" };\");\n\n // ── Update Type ──\n lines.push(\" Update: {\");\n emittedKeys.clear();\n for (const [key, rawProp] of Object.entries(properties)) {\n const prop = rawProp as Property;\n if (prop.type === \"relation\") continue;\n const tsType = propertyToTypeScriptType(prop);\n lines.push(` ${toSafeIdentifier(key)}?: ${tsType};`);\n emittedKeys.add(key);\n }\n for (const [relKey, relation] of Object.entries(resolvedRelations)) {\n if (relation.kind === \"belongsTo\" && relation.localKey) {\n const fkKey = relation.localKey;\n if (emittedKeys.has(fkKey)) continue;\n lines.push(` ${toSafeIdentifier(fkKey)}?: string | number;`);\n emittedKeys.add(fkKey);\n }\n }\n lines.push(\" };\");\n\n lines.push(\" };\");\n }\n\n lines.push(\"}\");\n lines.push(\"\");\n lines.push(\"export type CollectionName = keyof Database;\");\n lines.push(\"export type CollectionsDictionary = { [K in CollectionName]: K };\");\n lines.push(\"\");\n lines.push(\"export const collectionsDictionary = {\");\n for (const collection of collections) {\n lines.push(` ${toSafeIdentifier(collection.slug)}: \"${collection.slug}\",`);\n }\n lines.push(\"} as const;\");\n lines.push(\"\");\n\n return lines.join(\"\\n\");\n}\n","/**\n * @rebasepro/codegen\n *\n * Generates a purely typed Typescript database definition.\n */\n\nimport { CollectionConfig } from \"@rebasepro/types\";\nimport { generateTypedefs } from \"./generate-types\";\n\nexport { generateTypedefs } from \"./generate-types\";\nexport { toPascalCase, toCamelCase, toSafeIdentifier, indent } from \"./utils\";\n\n// ─── Public API ────────────────────────────────────────────────────\n\nexport interface GeneratedFile {\n /** Relative file path within the output directory */\n path: string;\n /** File content */\n content: string;\n}\n\nexport interface GenerateSDKOptions {\n /** Whether to include a README file (default: true) */\n includeReadme?: boolean;\n}\n\nexport function generateSDK(\n collections: CollectionConfig[],\n options: GenerateSDKOptions = {}\n): GeneratedFile[] {\n const files: GeneratedFile[] = [];\n\n files.push({\n path: \"database.types.ts\",\n content: generateTypedefs(collections)\n });\n\n if (options.includeReadme !== false) {\n files.push({\n path: \"README.md\",\n content: `# Rebase SDK\n\n> Auto-generated by \\`rebase generate-sdk\\`. Do not edit manually.\n\n## Usage\n\n1. Install the client package:\n \\`\\`\\`bash\n npm install @rebasepro/client\n \\`\\`\\`\n\n2. Initialize with your generated types:\n \\`\\`\\`typescript\n import { createRebaseClient } from '@rebasepro/client';\n import { Database, collectionsDictionary } from './database.types';\n\n const rebase = createRebaseClient<Database>({\n baseUrl: 'http://localhost:3001',\n collections: collectionsDictionary,\n });\n\n // Both syntax styles are fully typed!\n const { data: users } = await rebase.data.users.find();\n console.log(users[0].email); // flat access — no .values wrapper\n\n const { data: posts } = await rebase.data.collection('posts').find();\n console.log(posts[0].title); // just post.title, not post.values.title\n \\`\\`\\`\n`\n });\n }\n\n return files;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","names":[],"sources":["../src/utils.ts","../src/generate-types.ts","../src/index.ts"],"sourcesContent":["/**\n * Utility functions for the SDK generator\n */\n\n/**\n * Convert a slug/snake_case string to PascalCase\n * e.g. \"private_notes\" → \"PrivateNotes\"\n *\n * Capitals already inside a word are meaningful and are kept: lowercasing the\n * tail of every chunk turned \"TestEntities\" into \"Testentities\", which is what\n * ended up in the generated type names. SHOUTING_CASE is the one shape where\n * the tail is not meaningful, so it is folded down.\n */\nexport function toPascalCase(str: string): string {\n return str\n .split(/[_\\-\\s]+/)\n .filter(Boolean)\n .map(word => {\n const rest = /^[A-Z0-9]+$/.test(word) ? word.slice(1).toLowerCase() : word.slice(1);\n return word.charAt(0).toUpperCase() + rest;\n })\n .join(\"\");\n}\n\n/**\n * Convert a slug/snake_case string to camelCase\n * e.g. \"private_notes\" → \"privateNotes\"\n */\nexport function toCamelCase(str: string): string {\n if (!/[_\\-\\s]/.test(str)) {\n return str.charAt(0).toLowerCase() + str.slice(1);\n }\n const pascal = toPascalCase(str);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n\n/**\n * Convert a slug to a safe JS identifier\n * e.g. \"private-notes\" → \"privateNotes\"\n */\nexport function toSafeIdentifier(str: string): string {\n return toCamelCase(str.replace(/[^a-zA-Z0-9_]/g, \"_\"));\n}\n\n/**\n * Indent a block of text by a given number of spaces\n */\nexport function indent(text: string, spaces: number): string {\n const pad = \" \".repeat(spaces);\n return text\n .split(\"\\n\")\n .map(line => (line.trim() ? pad + line : line))\n .join(\"\\n\");\n}\n","import { CollectionConfig, PostgresCollectionConfig, Property, Properties, MapProperty, ArrayProperty, Relation, RelationProperty, StringProperty, NumberProperty, ResolvedRelation } from \"@rebasepro/types\";\nimport { resolveCollectionRelations } from \"@rebasepro/common\";\nimport { toPascalCase, toSafeIdentifier } from \"./utils\";\n\nfunction propertyToTypeScriptType(prop: Property): string {\n switch (prop.type) {\n case \"string\": {\n const sp = prop as StringProperty;\n if (sp.enum) {\n const ids = Array.isArray(sp.enum)\n ? sp.enum.map((e: string | number | { id: string | number }) => typeof e === \"object\" ? String(e.id) : String(e))\n : Object.keys(sp.enum);\n return ids.map(v => `\"${v}\"`).join(\" | \");\n }\n return \"string\";\n }\n case \"number\": {\n const np = prop as NumberProperty;\n if (np.enum) {\n const ids = Array.isArray(np.enum)\n ? np.enum.map((e: string | number | { id: string | number }) => typeof e === \"object\" ? String(e.id) : String(e))\n : Object.keys(np.enum);\n return ids.join(\" | \");\n }\n return \"number\";\n }\n case \"boolean\":\n return \"boolean\";\n case \"date\":\n return \"string\"; // ISO 8601 string over the wire\n case \"geopoint\":\n return \"{ latitude: number; longitude: number; }\";\n case \"reference\":\n return \"string | number\";\n case \"relation\":\n return \"string | number\";\n case \"map\": {\n const mapProp = prop as MapProperty;\n if (mapProp.properties) {\n const inner = Object.entries(mapProp.properties)\n .map(([k, v]) => `${toSafeIdentifier(k)}: ${propertyToTypeScriptType(v as Property)};`)\n .join(\" \");\n return `{ ${inner} }`;\n }\n return \"Record<string, unknown>\";\n }\n case \"array\": {\n const arrProp = prop as ArrayProperty;\n if (arrProp.of) {\n return `Array<${propertyToTypeScriptType(arrProp.of as Property)}>`;\n }\n return \"Array<unknown>\";\n }\n case \"vector\":\n return \"number[]\";\n case \"binary\":\n return \"string\";\n default:\n return \"unknown\";\n }\n}\n\n/**\n * Unwrap a relation target that arrived as a module namespace rather than the\n * collection itself — `target: () => import(\"./authors\")` is a common slip.\n */\nfunction resolveTargetCollection(relation: ResolvedRelation): CollectionConfig | undefined {\n try {\n let target = relation.target() as CollectionConfig & { default?: CollectionConfig; __esModule?: boolean };\n if (target && (target.default || target.__esModule)) {\n target = (target.default ?? target) as typeof target;\n }\n return target;\n } catch {\n return undefined;\n }\n}\n\n/** The TypeScript type of a foreign key: whatever the target's primary key is. */\nfunction foreignKeyType(relation: ResolvedRelation): string {\n const target = resolveTargetCollection(relation);\n if (!target?.properties) return \"string | number\";\n const idProp = Object.entries(target.properties).find(([_, p]) => (p as Record<string, unknown>).isId);\n if (!idProp) return \"string | number\";\n return (idProp[1] as Property).type === \"number\" ? \"number\" : \"string\";\n}\n\n/**\n * The type an *included* relation arrives as: the target's own row, inlined.\n *\n * This is what the read pipeline actually serves — `toRestRow` puts the\n * target's flat columns where the relation was, and the SDK and the HTTP API\n * both go through it. It is deliberately *not* a `{ __type: \"relation\" }`\n * envelope: that shape is the admin's view-model and never reaches a\n * developer's `find()`.\n *\n * Falls back to an open record when the target is not part of this generation\n * run, since there is no `Row` to point at.\n */\nfunction includedRelationType(relation: ResolvedRelation, knownSlugs: Set<string>): string {\n const target = resolveTargetCollection(relation);\n const slug = target?.slug ?? relation.targetSlug;\n const rowType = slug && knownSlugs.has(slug)\n ? `Database[${JSON.stringify(toSafeIdentifier(slug))}][\"Row\"]`\n : \"Record<string, unknown>\";\n return relation.cardinality === \"many\" ? `Array<${rowType}>` : rowType;\n}\n\nexport function generateTypedefs(collections: CollectionConfig[]): string {\n const knownSlugs = new Set(collections.map(c => c.slug).filter(Boolean) as string[]);\n const lines: string[] = [\n \"/**\",\n \" * This file was auto-generated by Rebase.\",\n \" * Do not make direct changes to the file.\",\n \" */\",\n \"\",\n \"export interface Database {\"\n ];\n\n for (const collection of collections) {\n const typeName = toPascalCase(collection.slug);\n const properties = (collection.properties ?? {}) as Properties;\n\n // Resolve relations\n let resolvedRelations: Record<string, ResolvedRelation> = {};\n try {\n resolvedRelations = resolveCollectionRelations(collection);\n } catch (e) {\n // Swallowed before, which made this the quietest way to ship a\n // wrong type. The foreign-key columns are emitted from the resolved\n // relations rather than from the properties, so losing them drops\n // both the relation fields *and* columns that exist in the\n // database — and the resulting error surfaces in the user's code,\n // typechecking against a `Database` that is missing `author_id`,\n // with nothing pointing back at generation.\n //\n // A target thunk usually throws because of a circular import; the\n // boot-time relation validator names the same cause.\n console.warn(\n `[rebase] Could not resolve the relations of \"${collection.slug}\", so its generated ` +\n \"type has no relation fields and none of their foreign-key columns. This is usually a \" +\n \"circular import in the collection files — make sure the target is `() => otherCollection` \" +\n `and not evaluated at module load.\\n ${e instanceof Error ? e.message : String(e)}`\n );\n }\n\n lines.push(` ${toSafeIdentifier(collection.slug)}: {`);\n\n // ── Row Type ──\n lines.push(\" Row: {\");\n const emittedKeys = new Set<string>();\n\n // 1. Direct properties\n for (const [key, rawProp] of Object.entries(properties)) {\n const prop = rawProp as Property;\n if (prop.type === \"relation\") continue;\n\n const tsType = propertyToTypeScriptType(prop);\n const isRequired = prop.validation?.required;\n lines.push(` ${toSafeIdentifier(key)}${isRequired ? \"\" : \"?\"}: ${tsType};`);\n emittedKeys.add(key);\n }\n\n // 2. FK columns from relations\n for (const [relKey, relation] of Object.entries(resolvedRelations)) {\n if (relation.kind === \"belongsTo\" && relation.localKey) {\n const fkKey = relation.localKey;\n if (emittedKeys.has(fkKey)) continue;\n\n const fkType = foreignKeyType(relation);\n\n // A relation addressed by the same name as its own foreign key\n // is served *over* that column when the read includes it: the\n // query nests the target under the relation name, and the\n // scalar it shadows is gone. Both outcomes are real, so the\n // column is typed as both — which is what stops a plain\n // `const id: string = row.author_id` from compiling.\n const shadowedByInclude = relKey === fkKey;\n const tsType = shadowedByInclude\n ? `${fkType} | ${includedRelationType(relation, knownSlugs)}`\n : fkType;\n\n const isRequired = relation.validation?.required && !shadowedByInclude;\n lines.push(` ${toSafeIdentifier(fkKey)}${isRequired ? \"\" : \"?\"}: ${tsType};`);\n emittedKeys.add(fkKey);\n }\n }\n\n // 3. Relation fields — the target's own row, inlined.\n //\n // Optional throughout: a relation is only loaded when the read names it\n // in `include`, so it is absent from every other read.\n for (const [key, relation] of Object.entries(resolvedRelations)) {\n if (emittedKeys.has(key)) continue;\n lines.push(` ${toSafeIdentifier(key)}?: ${includedRelationType(relation, knownSlugs)};`);\n emittedKeys.add(key);\n }\n\n // A `relation` property whose relation could not be resolved — an\n // engine without relation support, or a target that did not load. It is\n // still a column on the row, so it is still typed, just not precisely.\n for (const [key, rawProp] of Object.entries(properties)) {\n if ((rawProp as Property).type !== \"relation\") continue;\n if (emittedKeys.has(key)) continue;\n lines.push(` ${toSafeIdentifier(key)}?: Record<string, unknown>;`);\n emittedKeys.add(key);\n }\n lines.push(\" };\");\n\n // ── Insert Type ──\n lines.push(\" Insert: {\");\n emittedKeys.clear();\n\n for (const [key, rawProp] of Object.entries(properties)) {\n const prop = rawProp as Property;\n if (prop.type === \"relation\") continue;\n const tsType = propertyToTypeScriptType(prop);\n const isRequired = prop.validation?.required;\n const typedProp = prop as StringProperty | NumberProperty;\n const isAutoId = \"isId\" in prop && typedProp.isId && typedProp.isId !== \"manual\" && typedProp.isId !== true;\n const isOptional = !isRequired || isAutoId;\n lines.push(` ${toSafeIdentifier(key)}${isOptional ? \"?\" : \"\"}: ${tsType};`);\n emittedKeys.add(key);\n }\n\n for (const [relKey, relation] of Object.entries(resolvedRelations)) {\n if (relation.kind === \"belongsTo\" && relation.localKey) {\n const fkKey = relation.localKey;\n if (emittedKeys.has(fkKey)) continue;\n const fkType = \"string | number\";\n // simple fallback\n const isRequired = relation.validation?.required;\n lines.push(` ${toSafeIdentifier(fkKey)}${isRequired ? \"\" : \"?\"}: ${fkType};`);\n emittedKeys.add(fkKey);\n }\n }\n lines.push(\" };\");\n\n // ── Update Type ──\n lines.push(\" Update: {\");\n emittedKeys.clear();\n for (const [key, rawProp] of Object.entries(properties)) {\n const prop = rawProp as Property;\n if (prop.type === \"relation\") continue;\n const tsType = propertyToTypeScriptType(prop);\n lines.push(` ${toSafeIdentifier(key)}?: ${tsType};`);\n emittedKeys.add(key);\n }\n for (const [relKey, relation] of Object.entries(resolvedRelations)) {\n if (relation.kind === \"belongsTo\" && relation.localKey) {\n const fkKey = relation.localKey;\n if (emittedKeys.has(fkKey)) continue;\n lines.push(` ${toSafeIdentifier(fkKey)}?: string | number;`);\n emittedKeys.add(fkKey);\n }\n }\n lines.push(\" };\");\n\n lines.push(\" };\");\n }\n\n lines.push(\"}\");\n lines.push(\"\");\n lines.push(\"export type CollectionName = keyof Database;\");\n lines.push(\"export type CollectionsDictionary = { [K in CollectionName]: K };\");\n lines.push(\"\");\n lines.push(\"export const collectionsDictionary = {\");\n for (const collection of collections) {\n lines.push(` ${toSafeIdentifier(collection.slug)}: \"${collection.slug}\",`);\n }\n lines.push(\"} as const;\");\n lines.push(\"\");\n\n return lines.join(\"\\n\");\n}\n","/**\n * @rebasepro/codegen\n *\n * Generates a purely typed Typescript database definition.\n */\n\nimport { CollectionConfig } from \"@rebasepro/types\";\nimport { generateTypedefs } from \"./generate-types\";\n\nexport { generateTypedefs } from \"./generate-types\";\nexport { toPascalCase, toCamelCase, toSafeIdentifier, indent } from \"./utils\";\n\n// ─── Public API ────────────────────────────────────────────────────\n\nexport interface GeneratedFile {\n /** Relative file path within the output directory */\n path: string;\n /** File content */\n content: string;\n}\n\nexport interface GenerateSDKOptions {\n /** Whether to include a README file (default: true) */\n includeReadme?: boolean;\n}\n\nexport function generateSDK(\n collections: CollectionConfig[],\n options: GenerateSDKOptions = {}\n): GeneratedFile[] {\n const files: GeneratedFile[] = [];\n\n files.push({\n path: \"database.types.ts\",\n content: generateTypedefs(collections)\n });\n\n if (options.includeReadme !== false) {\n files.push({\n path: \"README.md\",\n content: `# Rebase SDK\n\n> Auto-generated by \\`rebase generate-sdk\\`. Do not edit manually.\n\n## Usage\n\n1. Install the client package:\n \\`\\`\\`bash\n npm install @rebasepro/client\n \\`\\`\\`\n\n2. Initialize with your generated types:\n \\`\\`\\`typescript\n import { createRebaseClient } from '@rebasepro/client';\n import { Database, collectionsDictionary } from './database.types';\n\n const rebase = createRebaseClient<Database>({\n baseUrl: 'http://localhost:3001',\n collections: collectionsDictionary,\n });\n\n // Both syntax styles are fully typed!\n const { data: users } = await rebase.data.users.find();\n console.log(users[0].email); // flat access — no .values wrapper\n\n const { data: posts } = await rebase.data.collection('posts').find();\n console.log(posts[0].title); // just post.title, not post.values.title\n \\`\\`\\`\n`\n });\n }\n\n return files;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rebasepro/codegen",
3
- "version": "0.13.0",
3
+ "version": "0.13.1-canary.g249daa1",
4
4
  "description": "Generate a typed JS SDK from Rebase collection definitions",
5
5
  "main": "./dist/index.es.js",
6
6
  "module": "./dist/index.es.js",
@@ -22,8 +22,8 @@
22
22
  "author": "rebase.pro",
23
23
  "license": "MIT",
24
24
  "peerDependencies": {
25
- "@rebasepro/common": "0.13.0",
26
- "@rebasepro/types": "0.13.0"
25
+ "@rebasepro/common": "0.13.1-canary.g249daa1",
26
+ "@rebasepro/types": "0.13.1-canary.g249daa1"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@jest/globals": "^30.4.1",
@@ -33,8 +33,8 @@
33
33
  "ts-jest": "^29.4.12",
34
34
  "typescript": "^6.0.3",
35
35
  "vite": "^8.1.5",
36
- "@rebasepro/types": "0.13.0",
37
- "@rebasepro/common": "0.13.0"
36
+ "@rebasepro/types": "0.13.1-canary.g249daa1",
37
+ "@rebasepro/common": "0.13.1-canary.g249daa1"
38
38
  },
39
39
  "exports": {
40
40
  ".": {
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "gitHead": "d935eefa5aa8d1009a2398cfac2c1e4ee9aeb6b6",
46
46
  "dependencies": {
47
- "@rebasepro/client": "0.13.0"
47
+ "@rebasepro/client": "0.13.1-canary.g249daa1"
48
48
  },
49
49
  "repository": {
50
50
  "type": "git",