npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kodeme-io/next-core-odoo-types

v0.8.4

Published

TypeScript type definitions for Odoo models - Use @kodeme-io/next-core-codegen to generate from your Odoo instance

Readme

@kodeme-io/next-core-odoo-types

TypeScript type definitions for Odoo ERP models - Ensuring type safety and data integrity across your Next-Core applications.

🎯 Purpose

This package solves the critical problem of type mismatches between mock data and real Odoo data by providing:

  1. Single Source of Truth: Types generated directly from Odoo schema
  2. Type Safety: Compile-time errors if mock data doesn't match Odoo
  3. Runtime Validation: Zod schemas for runtime data validation
  4. Auto-Generated: Types stay in sync with Odoo models
  5. Well-Documented: Complete field documentation and helpers

📦 Installation

pnpm add @kodeme-io/next-core-odoo-types

🚀 Quick Start

Usage Patterns

✅ Recommended: Type-Only Imports (Components)

// For React components that only need types
import type {
  ResPartner,
  SaleOrder,
  SfaVisit,
} from '@kodeme-io/next-core-odoo-types'

// Use in your code - 0KB runtime overhead!
const customer: ResPartner = {
  id: 1,
  name: 'ABC Corporation',
  email: '[email protected]',
  is_company: true,
  customer_rank: 1,
  // ... TypeScript enforces correct structure!
}

✅ Recommended: Combined Imports (Services)

// For services that need both types and API
import { OdooAdapter } from '@kodeme-io/next-core-odoo-api'
import type { ResPartner } from '@kodeme-io/next-core-odoo-types'

const adapter = new OdooAdapter({...})
const customers = await adapter.searchRead<ResPartner>('res.partner')

⚠️ Avoid: Importing Everything

// ❌ Don't do this - pulls in unused code
import * as OdooTypes from '@kodeme-io/next-core-odoo-types'

Runtime Validation

import {
  ResPartnerSchema,
  validateOdooData,
} from '@kodeme-io/next-core-odoo-types'

// Validate data from API
const rawData = await fetch('/api/customers/1').then(r => r.json())
const customer = validateOdooData(ResPartnerSchema, rawData)
// ✅ Throws if data doesn't match schema

Use in Mock Generators

import type { SfaVisit } from '@kodeme-io/next-core-odoo-types'

export function generateVisits(count: number): SfaVisit[] {
  return Array.from({ length: count }, (_, i) => ({
    id: i + 1,
    name: `VIS${String(i + 1).padStart(4, '0')}`,
    customer_id: [faker.number.int(), faker.company.name()],
    user_id: [1, 'John Doe'],
    scheduled_date: new Date().toISOString(),
    state: faker.helpers.arrayElement(['draft', 'scheduled', 'done', 'cancelled']),
    // ✅ TypeScript error if we use invalid state!
    visit_type: 'sales_visit',
    duration: 1,
    company_id: [1, 'My Company'],
    active: true,
  }))
}

📚 Available Types

Common Types

import type {
  Many2One,
  One2Many,
  Many2Many,
  Selection,
  OdooDate,
  OdooDateTime,
  Monetary,
} from '@kodeme-io/next-core-odoo-types'

Many2One: [id, display_name] or false

customer_id: [123, "ABC Corporation"]
customer_id: false  // No relation

One2Many / Many2Many: Array of IDs

order_line: [1, 2, 3, 4]

Selection: String literal union

state: 'draft' | 'confirmed' | 'done'

Base Models

res.partner (Contact/Customer)

import type { ResPartner } from '@kodeme-io/next-core-odoo-types'

interface ResPartner {
  id: number
  name: string
  email?: string | false
  phone?: string | false
  is_company: boolean
  customer_rank: number
  partner_latitude?: number
  partner_longitude?: number
  // ... 40+ more fields
}

sale.order (Sales Order)

import type { SaleOrder, SaleOrderLine } from '@kodeme-io/next-core-odoo-types'

interface SaleOrder {
  id: number
  name: string  // SO001
  partner_id: Many2One<'res.partner'>
  date_order: OdooDateTime
  state: 'draft' | 'sent' | 'sale' | 'done' | 'cancel'
  order_line: One2Many  // sale.order.line IDs
  amount_total: Monetary
  // ... 60+ more fields
}

sfa.visit (Field Visit)

import type { SfaVisit } from '@kodeme-io/next-core-odoo-types'

interface SfaVisit {
  id: number
  name: string  // VIS001
  customer_id: Many2One<'res.partner'>
  user_id: Many2One<'res.users'>
  scheduled_date: OdooDateTime
  state: 'draft' | 'scheduled' | 'done' | 'cancelled'
  check_in_latitude?: number
  check_in_longitude?: number
  // ... 40+ more fields
}

🛠️ Validation Schemas

Every type has a corresponding Zod schema:

import {
  ResPartnerSchema,
  SaleOrderSchema,
  SfaVisitSchema,
} from '@kodeme-io/next-core-odoo-types'

// Validate data
const customer = ResPartnerSchema.parse(rawData)

// Safe validation (returns result object)
const result = ResPartnerSchema.safeParse(rawData)
if (result.success) {
  console.log('Valid:', result.data)
} else {
  console.error('Invalid:', result.error)
}

🎨 Field Metadata

For building dynamic UIs (forms, tables):

import { SfaVisitFields } from '@kodeme-io/next-core-odoo-types'

SfaVisitFields.customer_id
// {
//   name: 'customer_id',
//   type: 'many2one',
//   label: 'Customer',
//   required: true
// }

Use with FormBuilder:

import { FormBuilder } from '@kodeme-io/next-core-forms'
import { SfaVisitFields } from '@kodeme-io/next-core-odoo-types'

<FormBuilder
  fields={[
    SfaVisitFields.customer_id,
    SfaVisitFields.scheduled_date,
    SfaVisitFields.purpose,
  ]}
  onSubmit={handleSubmit}
/>

🔄 Type Generation Workflow

Current State (v0.8.0)

This package currently contains hand-crafted TypeScript types for common Odoo models. These provide a good starting point and serve as templates.

Future: Auto-Generation with Codegen

In future versions, use @kodeme-io/next-core-codegen to auto-generate types from YOUR Odoo instance:

┌─────────────────────────────────────────┐
│ 1. YOUR Odoo ERP Instance               │
│    - Your custom models                 │
│    - Your custom fields                 │
│    - Your specific configuration        │
└─────────────────────────────────────────┘
                 ↓
    [Introspect via fields_get API]
                 ↓
┌─────────────────────────────────────────┐
│ 2. @kodeme-io/next-core-codegen         │
│    CLI TOOL (the generator)             │
│    - Connects to your Odoo              │
│    - Introspects model schemas          │
│    - Generates TypeScript code          │
└─────────────────────────────────────────┘
                 ↓
    [Generates types into your project]
                 ↓
┌─────────────────────────────────────────┐
│ 3. Your Project's src/types/odoo.ts     │
│    GENERATED OUTPUT                     │
│    - TypeScript interfaces              │
│    - Zod validation schemas             │
│    - Field metadata                     │
└─────────────────────────────────────────┘
                 ↓
    [Import in your components]
                 ↓
┌─────────────────────────────────────────┐
│ 4. Your Next.js App                     │
│    import type { ResPartner }           │
│    from '@/types/odoo'                  │
│    - Type-safe data access              │
│    - Compile-time validation            │
└─────────────────────────────────────────┘

Why Separate Packages?

Our architecture separates runtime behavior from compile-time safety for optimal performance:

| Package | Purpose | Bundle Size | When to Use | |---------|---------|-------------|-------------| | @kodeme-io/next-core-odoo-api | Runtime JSON-RPC client | 112K | Services, API calls, data fetching | | @kodeme-io/next-core-odoo-types | TypeScript types & validation | 220K | Components, type safety, validation | | @kodeme-io/next-core-codegen | Generator tool (CLI) | - | Generate types from your Odoo |

Benefits of Separation:

  • Tree-shaking: Components import only types (0KB runtime)
  • Independent versioning: Types can evolve faster than API
  • Clear boundaries: Runtime vs compile-time concerns
  • Better testing: Test types without network code

| Package | Purpose | You Should... | |---------|---------|---------------| | @kodeme-io/next-core-codegen | Generator tool (CLI) | Install as devDependency and run to generate types | | @kodeme-io/next-core-odoo-types | Template/reference types | Use as reference or starting point for your types |

Example Workflow:

# 1. Install the generator tool
pnpm add -D @kodeme-io/next-core-codegen

# 2. Generate types from YOUR Odoo instance
npx next-core-codegen generate-types \
  --odoo-url=https://your-odoo.com \
  --database=your-database \
  --output=src/types/odoo.ts

# 3. Use the generated types in your app
import type { ResPartner } from '@/types/odoo'

📖 Model Registry

import {
  OdooModelRegistry,
  ModelType,
  ModelName,
  isModelName,
  getModelSchema,
  validateModelRecord,
} from '@kodeme-io/next-core-odoo-types'

// Type-safe model access
type Customer = ModelType<'res.partner'>  // = ResPartner

// Check if valid model name
if (isModelName('res.partner')) {
  const schema = getModelSchema('res.partner')
}

// Validate record
const customer = validateModelRecord('res.partner', rawData)

🎯 Benefits

Before (Manual Types)

// ❌ Manual type definition (might not match Odoo)
type Visit = {
  state: 'pending' | 'done' | 'cancelled'  // Wrong! Odoo has 'scheduled'
}

// ❌ No validation
const visit = mockData as Visit  // Type cast, no checks

// ❌ Mock drifts from Odoo
// Mock has 'pending', Odoo has 'scheduled' → Runtime errors!

After (Generated Types)

// ✅ Type generated from Odoo
import type { SfaVisit } from '@kodeme-io/next-core-odoo-types'

// ✅ Compile-time validation
const visit: SfaVisit = {
  state: 'pending'  // ❌ TypeScript error! Invalid state
}

// ✅ Runtime validation
const visit = validateOdooData(SfaVisitSchema, rawData)

// ✅ Mock guaranteed to match Odoo
// Both use same type definition from this package

🔧 Utilities

Helper Functions

import {
  calculateVisitDuration,
  isVisitCompleted,
  getVisitStatusColor,
} from '@kodeme-io/next-core-odoo-types'

const visit: SfaVisit = { /* ... */ }

const duration = calculateVisitDuration(visit)
// Returns: number | null (hours)

const isCompleted = isVisitCompleted(visit)
// Returns: boolean

const color = getVisitStatusColor(visit)
// Returns: 'gray' | 'blue' | 'green' | 'red'

Type Utilities

import type {
  PartialRecord,
  OmitMetadata,
  WritableFields,
} from '@kodeme-io/next-core-odoo-types'

// Partial update (all fields optional)
type UpdateVisit = PartialRecord<SfaVisit>

// Without metadata fields
type CleanVisit = OmitMetadata<SfaVisit>

// Only writable fields
type CreateVisit = WritableFields<SfaVisit>

📝 Required Odoo Modules

Different models require different Odoo modules:

| Model | Required Module | Description | |-------|----------------|-------------| | res.partner | Base (built-in) | Contacts/Customers | | sale.order | sale | Sales Management | | crm.lead | crm | CRM/Leads | | sfa.visit | sfa_management | Custom SFA module | | sfa.target | sfa_management | Custom SFA module | | hr.employee | hr | HR Management | | hr.attendance | hr_attendance | Attendance Tracking |

Note: Install required modules in your Odoo instance before generating types.

🚀 Type Generation

Recommended: Use Codegen Package

Generate types from YOUR Odoo instance using @kodeme-io/next-core-codegen:

# 1. Install codegen (as dev dependency)
pnpm add -D @kodeme-io/next-core-codegen

# 2. Create configuration file (.next-core.json)
{
  "odoo": {
    "url": "https://your-odoo.com",
    "db": "your_database",
    "username": "admin",
    "password": "admin"
  },
  "models": ["res.partner", "sale.order", "sfa.visit"],
  "output": "src/types/odoo.ts"
}

# 3. Generate types
npx next-core-codegen generate-types

# 4. Import generated types in your app
import type { ResPartner, SaleOrder } from '@/types/odoo'

Generated output structure:

// src/types/odoo.ts (auto-generated)

export type Many2one<T = any> = [number, string] | false
export type One2many = number[]
export type Many2many = number[]

export interface ResPartner {
  id?: number
  name: string
  email?: string
  phone?: string
  // ... all fields from YOUR Odoo instance
}

export const ResPartnerSchema = z.object({
  name: z.string(),
  email: z.string().email().optional(),
  // ... validation schemas
})

Current Package: Reference Types

This package (@kodeme-io/next-core-odoo-types) provides hand-crafted types for common models as:

  • Reference implementation - See how types should be structured
  • Starting templates - Copy and customize for your needs
  • Development aid - Use while setting up codegen

Files in this package:

src/models/
├── base/
│   └── res.partner.ts      (hand-crafted example)
├── sales/
│   └── sale.order.ts       (hand-crafted example)
└── sfa/
    └── sfa.visit.ts        (hand-crafted example)

🤝 Integration

With MockAdapter

import { MockAdapter } from '@next-core/shared-mock-data'
import type { SfaVisit } from '@kodeme-io/next-core-odoo-types'
import { SfaVisitSchema } from '@kodeme-io/next-core-odoo-types'

const adapter = new MockAdapter()

// Generate type-safe mock data
const visits: SfaVisit[] = generateVisits(100)

// Validate before seeding
visits.forEach(visit => {
  SfaVisitSchema.parse(visit)  // Ensures mock matches Odoo
})

adapter.seed({ 'sfa.visit': visits })

With OdooAdapter

import { OdooAdapter } from '@kodeme-io/next-core-odoo-api'
import type { SfaVisit } from '@kodeme-io/next-core-odoo-types'
import { SfaVisitSchema } from '@kodeme-io/next-core-odoo-types'

const adapter = new OdooAdapter({
  url: 'https://your-odoo.com',
  database: 'your-db',
})

// Type-safe data access
const visits = await adapter.searchRead<SfaVisit>(
  'sfa.visit',
  [['state', '=', 'scheduled']],
  ['customer_id', 'scheduled_date', 'state']
)

// Validate response
visits.forEach(visit => {
  SfaVisitSchema.parse(visit)
})

📄 License

MIT

🙏 Credits

Built with ❤️ by the Next-Core Team


Next: See @next-core/shared-mock-data for mock data generation using these types