npm package: @heppy21/notion-core-utils
Description: Reusable Notion client helpers, ID parsers, and block extraction utilities.
Latest version: 1.0.0

# `@heppy21/notion-core-utils`

Reusable Notion helpers extracted from the API app in this monorepo. The package focuses on the reusable core only:

- Notion API client helpers
- Notion database/page ID parsing and normalization
- block text extraction
- section extraction for description, success criteria, and resources
- exported TypeScript types

It intentionally does not include Express routes, Prisma persistence, environment access, or app-specific task enum mapping.

## Public API

### Named exports

- `createNotionClient`
- `fetchNotionDatabase`
- `queryNotionDatabase`
- `fetchNotionPageBlocks`
- `extractNotionDatabaseId`
- `normalizeNotionDatabaseId`
- `normalizeNotionPageId`
- `extractBlockText`
- `extractDescriptionFromBlocks`
- `extractSuccessCriteriaFromBlocks`
- `extractResourcesFromBlocks`

### Default export

The default export is `notionCoreUtils`, a convenience object that groups the named utilities together.

### Type exports

The package also exports types such as:

- `NotionBlock`
- `NotionPage`
- `NotionDatabaseQueryResponse`
- `NotionSectionTodo`
- `NotionSectionResource`

## Example

```ts
import notionCoreUtils, {
  extractNotionDatabaseId,
  extractDescriptionFromBlocks,
  type NotionBlock,
} from "@heppy21/notion-core-utils";

const databaseId = extractNotionDatabaseId(
  "https://www.notion.so/MyWorkspace/Tasks-34eafb7bbe0b411c820817be8bd9ef69",
);

const blocks: NotionBlock[] = [
  {
    type: "heading_2",
    heading_2: {
      rich_text: [{ plain_text: "Description" }],
    },
  },
  {
    type: "paragraph",
    paragraph: {
      rich_text: [{ plain_text: "Ship the reusable package." }],
    },
  },
];

const description = extractDescriptionFromBlocks(blocks);
const normalizedId = notionCoreUtils.normalizeNotionDatabaseId(databaseId);
```

## Local development in this monorepo

### Build the package

```bash
pnpm --filter @heppy21/notion-core-utils build
```

### Use it through the workspace

1. Add the package as a dependency in the consumer app with `workspace:*`.
2. Run `pnpm install` at the repo root.
3. Import the package in `apps/api` or `apps/playground`.

## `npm link` demo flow

This repository already supports workspace consumption, but if you need to demonstrate `npm link` explicitly:

1. Build the package.
2. In `packages/notion-core-utils`, run:

```bash
npm link
```

3. In the consumer app directory, run:

```bash
npm link @heppy21/notion-core-utils
```

4. Start the consumer app and use the linked package.
5. Rebuild the package after changes to demonstrate the update loop.

## Publishing from this same repository

You do not need a separate Git repository. npm publishes the package from the package folder because that folder has its own `package.json`.

### Before the first publish

1. Run `npm login`.
2. Make sure the package builds successfully.
3. Confirm the package contents with `npm pack --dry-run`.
4. Update `version` and `CHANGELOG.md`.

### Publish steps

From `packages/notion-core-utils`:

```bash
npm publish --access public
```

Notes:

- Public packages are supported on the free npm plan.
- `publishConfig.access` is already set to `public`.
- Do not set `"private": true` in `package.json`, or npm will refuse to publish.

## Semver

- `1.0.0`: first stable release
- `1.0.1`: backward-compatible bug fix
- `1.1.0`: backward-compatible new feature
- `2.0.0`: breaking API change

## Changelog and tags

For each release:

1. Update `CHANGELOG.md`.
2. Bump the package version.
3. Commit the changes.
4. Create a git tag such as `v1.0.0`.
5. Publish the package.

That gives you a clear link between the source code, the package version, and the mentor explanation.