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 🙏

© 2025 – Pkg Stats / Ryan Hefner

kintone-as-code

v0.6.2

Published

A CLI tool for managing kintone applications as code with type-safe TypeScript schemas

Readme

kintone-as-code

npm version CI License: MIT

日本語

Manage kintone app configurations as code with type safety using Effect-TS.

Architecture (Summary)

  • Functional Core, Imperative Shell
  • Core (pure functions in src/query/*): expressions, fields, FP builder, validation
  • Shell (side effects): CLI/commands and code generator
  • Public API is FP-only. No OO facade is provided. The method-chaining createQuery() is a helper emitted in generated files apps/{name}.query.ts, not a public package API.

Features

  • 🔒 Type-safe - Full TypeScript support with kintone-effect-schema
  • 📝 Export from kintone - Generate schema files from existing apps
  • 🚀 Apply changes - Update existing apps with schema changes and automatically add new fields
  • Create apps - Create new kintone apps from schema definitions
  • 🔧 Environment management - Support multiple kintone environments
  • 🎯 Effect-TS powered - Leverage the power of Effect-TS for schema validation
  • 📋 Record Schema Generation - Generates static, copy-paste-friendly record schemas for customization

Installation

npm install -g kintone-as-code

Prerequisites

  • Node.js 18 or higher
  • kintone environment with API access

Quick Start

1. Initialize project

kintone-as-code init

This creates a kintone-as-code.config.js file with your environment settings.

2. Export an existing app

# Default: generates query and record-schema as well
kintone-as-code export --app-id 123 --name customer-app

# Suppress generation (backward-compatible --with-* also supported)
kintone-as-code export --app-id 123 --name customer-app --no-query
kintone-as-code export --app-id 123 --name customer-app --no-record-schema

# Include related/subtable fields as dot-notation (minimal: in/not in only)
kintone-as-code export --app-id 123 --name customer-app \
  --include-related \
  --include-subtable

This generates:

  • apps/customer-app.schema.ts - Fully typed field definitions
  • apps/customer-app.record-schema.ts - Static, type-safe record validation schema (copy-paste friendly)
  • apps/customer-app.query.ts - Type-safe query builder for kintone API (generated by default)
    • With --include-related, REFERENCE_TABLE displayFields are exposed minimally via createTableSubField('parent.child') (in/not in only)
    • With --include-subtable, subtable child fields are exposed with the same minimal API

3. Apply changes to existing app

kintone-as-code apply --app-id 123 --schema apps/customer-app.schema.ts

This updates the app with any schema changes and automatically adds new fields.

4. Create a new app from schema

kintone-as-code create --schema apps/customer-app.schema.ts --name "Customer App Copy"

This creates a new app with all fields defined in the schema.

5. Define app schema

The exported schema uses kintone-effect-schema for complete type safety:

import { defineAppSchema } from 'kintone-as-code';
import { APP_IDS } from './utils/app-ids';
import type {
  SingleLineTextFieldProperties,
  NumberFieldProperties,
  SubtableFieldProperties,
} from 'kintone-effect-schema';

// Individual field definitions with complete type information
export const companyNameField: SingleLineTextFieldProperties = {
  type: 'SINGLE_LINE_TEXT',
  code: '会社名',
  label: '会社名',
  required: true,
  unique: true,
  maxLength: '100',
};

export const revenueField: NumberFieldProperties = {
  type: 'NUMBER',
  code: '売上高',
  label: '年間売上高',
  unit: '円',
  unitPosition: 'AFTER',
};

// Subtable with nested fields
export const productsField: SubtableFieldProperties = {
  type: 'SUBTABLE',
  code: 'products',
  fields: {
    productName: {
      type: 'SINGLE_LINE_TEXT',
      code: 'productName',
      label: '商品名',
      required: true,
    },
    price: {
      type: 'NUMBER',
      code: 'price',
      label: '単価',
      unit: '円',
    },
  },
};

// App fields configuration
export const appFieldsConfig = {
  properties: {
    会社名: companyNameField,
    売上高: revenueField,
    products: productsField,
  },
};

// App schema definition
export default defineAppSchema({
  // APP_IDS central registry (recommended to align with generated files)
  appId: APP_IDS.CUSTOMER_APP,
  name: 'Customer Management',
  description: 'Customer information management app',
  fieldsConfig: appFieldsConfig,
});

Configuration

App ID management

Use utils/app-ids.ts to centrally manage app IDs. It is automatically updated by the export command.

Configuration File

kintone-as-code.config.js:

export default {
  default: 'production',
  environments: {
    production: {
      auth: {
        baseUrl: process.env.KINTONE_BASE_URL,
        username: process.env.KINTONE_USERNAME,
        password: process.env.KINTONE_PASSWORD,
      },
    },
    development: {
      auth: {
        baseUrl: process.env.KINTONE_BASE_URL,
        username: process.env.KINTONE_USERNAME,
        password: process.env.KINTONE_PASSWORD,
      },
    },
  },
};

Integration with kintone-effect-schema

This tool is designed to work seamlessly with kintone-effect-schema, which provides:

  • Complete type definitions for all kintone field types
  • Runtime validation using Effect-TS
  • Support for Japanese field codes
  • Automatic handling of empty values

Commands

Docs index

  • Overview (IaC): docs/overview.ja.md
  • Config: docs/config.ja.md
  • Converter & Schemas: docs/converter-and-schemas.ja.md
  • Export/Apply/Create: docs/export-apply-create.ja.md
  • Query Builder: docs/query-builder.ja.md
  • Query Cookbook: docs/query-cookbook.ja.md
  • Architecture: docs/architecture.ja.md

init

Initialize a new kintone-as-code project:

kintone-as-code init [options]

Options:
  -f, --force  Force overwrite existing files

export

Export kintone app configuration to TypeScript:

kintone-as-code export [options]

Options:
  --app-id <id>             App ID to export (required)
  --name <name>             Schema file name (required)
  --env <env>               Environment name
  --output <dir>            Output directory (default: "apps")
  --with-record-schema      Generate record schema file (default: true)
  --no-record-schema        Skip record schema generation
  --with-query              Generate query builder file (default: true)
  --no-query                Skip query builder generation

The export command now generates three files by default:

  1. Field Schema ({name}.schema.ts) - Field definitions and configurations
  2. Record Schema ({name}.record-schema.ts) - Type-safe record validation with Effect Schema
  3. Query Builder ({name}.query.ts) - Type-safe query builder for kintone REST API

apply

Apply schema changes to an existing kintone app:

kintone-as-code apply [options]

Options:
  --app-id <id>    App ID to update (optional; if omitted, uses appId from schema)
  --schema <path>  Path to schema file (required)
  --env <env>      Environment name

Features:

  • Updates existing fields with type-safe validation
  • Automatically detects and adds new fields
  • Deploys changes after successful update

create

Create a new kintone app from a schema file:

kintone-as-code create [options]

Options:
  --schema <path>   Path to schema file (required)
  --name <name>     Override app name from schema
  --space <id>      Create app in specific space
  --thread <id>     Thread ID in the space (when creating inside a space)
  --env <env>       Environment name

Features:

  • Creates new app with all fields defined in schema
  • Supports creating apps in specific spaces
  • Automatically deploys the app after creation

Record Schema Usage

The generated record schema provides type-safe validation for kintone records with automatic normalization:

import { KintoneRestAPIClient } from '@kintone/rest-api-client';
import {
  validateRecord,
  type AppRecord,
} from './apps/customer-app.record-schema';

// Initialize client
const client = new KintoneRestAPIClient({
  baseUrl: process.env.KINTONE_BASE_URL!,
  auth: {
    username: process.env.KINTONE_USERNAME!,
    password: process.env.KINTONE_PASSWORD!,
  },
});

// Fetch and validate record with automatic normalization
const response = await client.record.getRecord({
  app: 123,
  id: 1,
});
const validatedRecord: AppRecord = validateRecord(response.record);
// validatedRecord is fully typed and normalized (no type assertions needed)
// Empty strings in number fields → null, undefined → '', etc.

Example of generated Record Schema (simple)

import { Schema } from 'effect';
import {
  SingleLineTextFieldSchema,
  NumberFieldSchema,
  decodeKintoneRecord,
} from 'kintone-effect-schema';

// Static output example
export const RecordSchema = Schema.Struct({
  title: SingleLineTextFieldSchema,
  amount: NumberFieldSchema,
});

export type AppRecord = Schema.Schema.Type<typeof RecordSchema>;

export const validateRecord = (record: Record<string, unknown>): AppRecord => {
  const normalized = decodeKintoneRecord(record);
  return Schema.decodeUnknownSync(RecordSchema)(normalized);
};

JavaScript API Usage (Customization)

import {
  validateRecord,
  type AppRecord,
} from './apps/customer-app.record-schema';

kintone.events.on('app.record.detail.show', (event) => {
  // Same function works for JavaScript API
  const validatedRecord: AppRecord = validateRecord(event.record);
  // Handles all empty value inconsistencies automatically
  return event;
});

Query Builder Usage

The generated query builder provides type-safe query construction with IDE auto-completion:

import { QueryFields, createQuery } from './apps/customer-app.query';
import { and, or } from 'kintone-as-code';

// All field names are auto-completed
const { 会社名, ステータス, 売上高, 担当者 } = QueryFields;

// Build type-safe queries
// OO facade (method-chain)
const query = createQuery()
  .where(
    and(
      会社名.like('*サイボウズ*'),
      売上高.greaterThan(1000000),
      ステータス.in(['商談中', '受注'])
    )
  )
  .orderBy('売上高', 'desc')
  .limit(100)
  .build();

// Use with kintone REST API
const client = new KintoneRestAPIClient({
  /* ... */
});

// Functional API (pure functions)
import {
  createQueryState,
  setWhere,
  appendOrder,
  withLimit,
  build,
} from 'kintone-as-code';

const query2 = build(
  withLimit(100)(
    appendOrder(
      '売上高',
      'desc'
    )(
      setWhere(
        and(
          会社名.like('*サイボウズ*'),
          売上高.greaterThan(1000000),
          ステータス.in(['商談中', '受注'])
        )
      )(createQueryState())
    )
  )
);
const records = await client.record.getRecords({
  app: 123,
  query: query,
});

Helper methods

  • Strings: contains()/startsWith()/endsWith()
  • Numbers, Date, DateTime, and Time: between(min, max)
  • Custom function names: customDateFunction(name, ...args) / customUserFunction(name, ...args)

Query Features

  • Type-safe field access: All fields are typed based on their kintone field types
  • Field-specific operators: Only valid operators for each field type are available
  • kintone functions: Support for TODAY(), LOGINUSER(), THIS_MONTH(), etc.
  • Complex conditions: Combine with and(), or(), not()
  • Auto-completion: IDE provides suggestions for fields and methods

Note: The query builder is not exposed as a public API. Internally we follow FP design; if we expose it in the future, the FP API will be the only supported style.

Note: No raw() escape hatch

Direct raw query insertion via raw() is not provided. Instead, use contains/startsWith/endsWith, between(min, max), and customDateFunction/customUserFunction as escape hatches.

Field Type Examples

// String fields support like/not like
会社名.like('*株式会社*');
会社名.notLike('*test*');

// Number fields support comparison operators
売上高.greaterThan(1000000);
売上高.lessThanOrEqual(5000000);

// Dropdown fields use in/not in
ステータス.in(['商談中', '受注']);
ステータス.notIn(['失注', 'キャンセル']);

// Date fields support date functions
契約日.equals(TODAY());
期限日.lessThan(FROM_TODAY(7, 'DAYS'));
登録日.in([THIS_MONTH()]);

// User fields support user functions
担当者.equals(LOGINUSER());
作成者.in(['user1', 'user2']);

Best Practices

  1. Version Control: Commit your schema files to track app configuration changes
  2. Centralized APP_IDS: Manage app IDs in utils/app-ids.ts (kept up-to-date by export)
  3. Type Safety: Leverage TypeScript's type checking to catch configuration errors early
  4. Code Review: Review schema changes as part of your development process
  5. Record Validation: Use generated record schemas in your customization code for type-safe data handling

License

MIT