@sudobility/cravings_types 0.0.5
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/CLAUDE.md +105 -0
- package/dist/index.cjs +125 -0
- package/dist/index.d.ts +224 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +119 -0
- package/dist/index.js.map +1 -0
- package/package.json +63 -0
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Cravings Types
|
|
2
|
+
|
|
3
|
+
Shared TypeScript type definitions for the Cravings API ecosystem.
|
|
4
|
+
|
|
5
|
+
**npm**: `@sudobility/cravings_types` (public)
|
|
6
|
+
|
|
7
|
+
## Tech Stack
|
|
8
|
+
|
|
9
|
+
- **Language**: TypeScript (strict mode)
|
|
10
|
+
- **Runtime**: Bun
|
|
11
|
+
- **Package Manager**: Bun (do not use npm/yarn/pnpm for installing dependencies)
|
|
12
|
+
- **Build**: TypeScript compiler (dual ESM/CJS output)
|
|
13
|
+
- **Test**: Vitest
|
|
14
|
+
|
|
15
|
+
## Project Structure
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
src/
|
|
19
|
+
├── index.ts # All types, interfaces, and response helpers
|
|
20
|
+
└── index.test.ts # Tests
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Commands
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
bun run build # Build dual ESM/CJS (build:esm + build:cjs)
|
|
27
|
+
bun run dev # Watch mode
|
|
28
|
+
bun test # Run tests
|
|
29
|
+
bun run typecheck # TypeScript check
|
|
30
|
+
bun run lint # Run ESLint
|
|
31
|
+
bun run verify # All checks + build (use before commit)
|
|
32
|
+
bun run prepublishOnly # Clean + verify (runs on publish)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Key Types
|
|
36
|
+
|
|
37
|
+
### History
|
|
38
|
+
|
|
39
|
+
Core data type with fields: `id`, `user_id`, `datetime`, `value`, `created_at`, `updated_at`.
|
|
40
|
+
|
|
41
|
+
### Request Types
|
|
42
|
+
|
|
43
|
+
- `HistoryCreateRequest` — `{ datetime, value }`
|
|
44
|
+
- `HistoryUpdateRequest` — `{ datetime?, value? }`
|
|
45
|
+
- `HistoryTotalResponse` — `{ total }`
|
|
46
|
+
|
|
47
|
+
### Response Helpers
|
|
48
|
+
|
|
49
|
+
- `successResponse<T>(data)` — wraps data in `BaseResponse<T>` with `success: true`
|
|
50
|
+
- `errorResponse(error)` — wraps error string in `BaseResponse<never>` with `success: false`
|
|
51
|
+
|
|
52
|
+
### Re-exports from @sudobility/types
|
|
53
|
+
|
|
54
|
+
`ApiResponse`, `BaseResponse`, `NetworkClient`, `Optional`
|
|
55
|
+
|
|
56
|
+
## Peer Dependencies
|
|
57
|
+
|
|
58
|
+
- `@sudobility/types` — shared infrastructure types
|
|
59
|
+
|
|
60
|
+
## Architecture
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
@sudobility/cravings_types (this package)
|
|
64
|
+
^
|
|
65
|
+
cravings_api
|
|
66
|
+
cravings_client
|
|
67
|
+
cravings_lib
|
|
68
|
+
cravings_app
|
|
69
|
+
cravings_app_rn
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Foundation layer — all other Cravings projects depend on this package.
|
|
73
|
+
|
|
74
|
+
## Related Projects
|
|
75
|
+
|
|
76
|
+
- **cravings_api** — Backend API server (Hono + PostgreSQL); imports types for request/response validation
|
|
77
|
+
- **cravings_client** — API client SDK with TanStack Query hooks; imports types for API contracts
|
|
78
|
+
- **cravings_lib** — Business logic library with Zustand stores; imports types transitively via cravings_client
|
|
79
|
+
- **cravings_app** — Web application (React + Vite); imports types transitively via cravings_client and cravings_lib
|
|
80
|
+
- **cravings_app_rn** — React Native mobile app (Expo); imports types via file: links
|
|
81
|
+
|
|
82
|
+
All other cravings_* projects depend on this package. This package depends on `@sudobility/types` for base infrastructure types (`BaseResponse`, `NetworkClient`, etc.).
|
|
83
|
+
|
|
84
|
+
## Coding Patterns
|
|
85
|
+
|
|
86
|
+
- Pure type definitions only -- no runtime logic except the `successResponse` and `errorResponse` helper functions
|
|
87
|
+
- Dual CJS/ESM build output: `build:esm` produces ES modules, `build:cjs` produces CommonJS
|
|
88
|
+
- All public types and helpers are exported from a single `src/index.ts` barrel file
|
|
89
|
+
- Re-export base types from `@sudobility/types` so consumers only need to depend on this package
|
|
90
|
+
- Use `interface` for object shapes and `type` for unions/aliases
|
|
91
|
+
- Keep type names consistent with API naming: `History`, `HistoryCreateRequest`, `HistoryUpdateRequest`, `HistoryTotalResponse`
|
|
92
|
+
|
|
93
|
+
## Gotchas
|
|
94
|
+
|
|
95
|
+
- Changes here affect ALL consumer projects (cravings_api, cravings_client, cravings_lib, cravings_app, cravings_app_rn) -- always consider downstream impact
|
|
96
|
+
- Must build both ESM and CJS targets; consumers may use either module system
|
|
97
|
+
- Always run `bun run verify` before publishing to catch type errors, lint issues, and build failures
|
|
98
|
+
- The `BaseResponse<T>` wrapper is the standard API envelope -- all API responses must conform to it
|
|
99
|
+
- Do not add runtime dependencies; this package should remain a lightweight type-only dependency (response helpers are the sole exception)
|
|
100
|
+
|
|
101
|
+
## Testing
|
|
102
|
+
|
|
103
|
+
- Run tests: `bun test`
|
|
104
|
+
- Tests are in `src/index.test.ts`
|
|
105
|
+
- Tests verify that type exports exist, response helpers produce correct `BaseResponse<T>` shapes, and re-exports from `@sudobility/types` are accessible
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.successResponse = successResponse;
|
|
4
|
+
exports.errorResponse = errorResponse;
|
|
5
|
+
exports.isSuccessResponse = isSuccessResponse;
|
|
6
|
+
exports.isErrorResponse = isErrorResponse;
|
|
7
|
+
// =============================================================================
|
|
8
|
+
// Response Helpers
|
|
9
|
+
// =============================================================================
|
|
10
|
+
/**
|
|
11
|
+
* Constructs a successful API response.
|
|
12
|
+
*
|
|
13
|
+
* Creates a {@link BaseResponse} with `success: true`, the provided data payload,
|
|
14
|
+
* and a timestamp set to the current time in ISO 8601 format.
|
|
15
|
+
*
|
|
16
|
+
* @typeParam T - The type of the response payload
|
|
17
|
+
* @param data - The response payload (can be any type, including `undefined` or `null`)
|
|
18
|
+
* @returns A {@link BaseResponse} with `success: true` and `data` property set
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* // Successful single record
|
|
23
|
+
* const response1 = successResponse({ id: '123', name: 'test' });
|
|
24
|
+
*
|
|
25
|
+
* // Array of records
|
|
26
|
+
* const response2 = successResponse([
|
|
27
|
+
* { id: '1', value: 100 },
|
|
28
|
+
* { id: '2', value: 200 },
|
|
29
|
+
* ]);
|
|
30
|
+
*
|
|
31
|
+
* // Null or undefined data (valid, though potentially unusual)
|
|
32
|
+
* const response3 = successResponse(null);
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @internal
|
|
36
|
+
* Timestamp is always included in the response envelope and formatted as ISO 8601.
|
|
37
|
+
*/
|
|
38
|
+
function successResponse(data) {
|
|
39
|
+
return { success: true, data, timestamp: new Date().toISOString() };
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Constructs an error API response.
|
|
43
|
+
*
|
|
44
|
+
* Creates a {@link BaseResponse} with `success: false`, the provided error message,
|
|
45
|
+
* and a timestamp set to the current time in ISO 8601 format.
|
|
46
|
+
*
|
|
47
|
+
* **Note:** This function accepts empty strings as valid error messages. While this
|
|
48
|
+
* is allowed by the runtime and type system, it is generally recommended to provide
|
|
49
|
+
* meaningful, non-empty error descriptions for better debugging and client-side handling.
|
|
50
|
+
*
|
|
51
|
+
* @param error - A descriptive error message (may be empty, though not recommended)
|
|
52
|
+
* @returns A {@link BaseResponse} with `success: false` and `error` property set
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* // Standard error
|
|
57
|
+
* const response1 = errorResponse('User not found');
|
|
58
|
+
*
|
|
59
|
+
* // Error with context
|
|
60
|
+
* const response2 = errorResponse('Invalid datetime format: expected ISO 8601');
|
|
61
|
+
*
|
|
62
|
+
* // Empty string (allowed but not recommended)
|
|
63
|
+
* const response3 = errorResponse('');
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @internal
|
|
67
|
+
* Timestamp is always included in the response envelope and formatted as ISO 8601.
|
|
68
|
+
*/
|
|
69
|
+
function errorResponse(error) {
|
|
70
|
+
return { success: false, error, timestamp: new Date().toISOString() };
|
|
71
|
+
}
|
|
72
|
+
// =============================================================================
|
|
73
|
+
// Type Guards
|
|
74
|
+
// =============================================================================
|
|
75
|
+
/**
|
|
76
|
+
* Type guard to narrow a {@link BaseResponse} to a successful response.
|
|
77
|
+
*
|
|
78
|
+
* Checks if a response has `success: true`, allowing TypeScript to narrow
|
|
79
|
+
* the type to access the `data` property safely.
|
|
80
|
+
*
|
|
81
|
+
* @typeParam T - The expected type of the response data
|
|
82
|
+
* @param response - The response to check
|
|
83
|
+
* @returns `true` if the response is successful, `false` otherwise
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* async function fetchHistory(): Promise<BaseResponse<History[]>> {
|
|
88
|
+
* const response = await client.get('/history');
|
|
89
|
+
* if (isSuccessResponse<History[]>(response)) {
|
|
90
|
+
* // TypeScript now knows response.data is History[]
|
|
91
|
+
* const histories = response.data;
|
|
92
|
+
* return histories;
|
|
93
|
+
* }
|
|
94
|
+
* console.error('Failed:', response.error);
|
|
95
|
+
* }
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
function isSuccessResponse(response) {
|
|
99
|
+
return response.success === true;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Type guard to narrow a {@link BaseResponse} to an error response.
|
|
103
|
+
*
|
|
104
|
+
* Checks if a response has `success: false`, allowing TypeScript to narrow
|
|
105
|
+
* the type to access the `error` property safely.
|
|
106
|
+
*
|
|
107
|
+
* @param response - The response to check
|
|
108
|
+
* @returns `true` if the response is an error, `false` otherwise
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* async function updateHistory(id: string, value: number): Promise<void> {
|
|
113
|
+
* const response = await client.patch(`/history/${id}`, { value });
|
|
114
|
+
* if (isErrorResponse(response)) {
|
|
115
|
+
* // TypeScript now knows response.error is string
|
|
116
|
+
* throw new Error(response.error);
|
|
117
|
+
* }
|
|
118
|
+
* // Success case
|
|
119
|
+
* }
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
function isErrorResponse(response) {
|
|
123
|
+
return response.success === false;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=index.js.map
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
export type { ApiResponse, BaseResponse, NetworkClient, Optional, } from '@sudobility/types';
|
|
2
|
+
import type { BaseResponse } from '@sudobility/types';
|
|
3
|
+
/**
|
|
4
|
+
* ISO 8601 formatted datetime string.
|
|
5
|
+
*
|
|
6
|
+
* @example "2025-01-15T10:30:00.000Z"
|
|
7
|
+
*/
|
|
8
|
+
export type ISODateString = string & {
|
|
9
|
+
readonly __brand: 'ISODateString';
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* User account information.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const user: User = {
|
|
17
|
+
* firebase_uid: 'uid123',
|
|
18
|
+
* email: 'user@example.com',
|
|
19
|
+
* display_name: 'John Doe',
|
|
20
|
+
* created_at: '2025-01-15T10:30:00.000Z',
|
|
21
|
+
* updated_at: '2025-01-15T10:30:00.000Z',
|
|
22
|
+
* };
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export interface User {
|
|
26
|
+
/** Firebase Authentication UID */
|
|
27
|
+
firebase_uid: string;
|
|
28
|
+
/** User email address, nullable */
|
|
29
|
+
email: string | null;
|
|
30
|
+
/** User display name, nullable */
|
|
31
|
+
display_name: string | null;
|
|
32
|
+
/** ISO 8601 timestamp of account creation, nullable */
|
|
33
|
+
created_at: string | null;
|
|
34
|
+
/** ISO 8601 timestamp of last update, nullable */
|
|
35
|
+
updated_at: string | null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Core domain entity representing a historical data point.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const history: History = {
|
|
43
|
+
* id: 'hist-uuid-1',
|
|
44
|
+
* user_id: 'uid123',
|
|
45
|
+
* datetime: '2025-01-15T10:30:00.000Z',
|
|
46
|
+
* value: 42.5,
|
|
47
|
+
* created_at: '2025-01-15T10:30:00.000Z',
|
|
48
|
+
* updated_at: null,
|
|
49
|
+
* };
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export interface History {
|
|
53
|
+
/** Unique identifier for this history record */
|
|
54
|
+
id: string;
|
|
55
|
+
/** Foreign key reference to the owning user */
|
|
56
|
+
user_id: string;
|
|
57
|
+
/** ISO 8601 formatted datetime when the event occurred */
|
|
58
|
+
datetime: string;
|
|
59
|
+
/** Numeric value associated with this history record, must be positive */
|
|
60
|
+
value: number;
|
|
61
|
+
/** ISO 8601 timestamp when the record was created, nullable */
|
|
62
|
+
created_at: string | null;
|
|
63
|
+
/** ISO 8601 timestamp of the last update, nullable */
|
|
64
|
+
updated_at: string | null;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Request body for creating a new history record.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* const createRequest: HistoryCreateRequest = {
|
|
72
|
+
* datetime: '2025-01-15T10:30:00.000Z',
|
|
73
|
+
* value: 100,
|
|
74
|
+
* };
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export interface HistoryCreateRequest {
|
|
78
|
+
/** ISO 8601 formatted datetime when the event occurred */
|
|
79
|
+
datetime: string;
|
|
80
|
+
/** Numeric value associated with the record, must be positive */
|
|
81
|
+
value: number;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Request body for updating an existing history record.
|
|
85
|
+
* All fields are optional; omitted fields are not updated.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* const updateRequest: HistoryUpdateRequest = {
|
|
90
|
+
* value: 150,
|
|
91
|
+
* };
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export interface HistoryUpdateRequest {
|
|
95
|
+
/** ISO 8601 formatted datetime, optional for updates */
|
|
96
|
+
datetime?: string;
|
|
97
|
+
/** Numeric value, optional for updates, must be positive if provided */
|
|
98
|
+
value?: number;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Response containing the total sum of all history records for a user.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* const totalResponse: HistoryTotalResponse = {
|
|
106
|
+
* total: 12345.67,
|
|
107
|
+
* };
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
export interface HistoryTotalResponse {
|
|
111
|
+
/** Sum of all values for the queried history records */
|
|
112
|
+
total: number;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Constructs a successful API response.
|
|
116
|
+
*
|
|
117
|
+
* Creates a {@link BaseResponse} with `success: true`, the provided data payload,
|
|
118
|
+
* and a timestamp set to the current time in ISO 8601 format.
|
|
119
|
+
*
|
|
120
|
+
* @typeParam T - The type of the response payload
|
|
121
|
+
* @param data - The response payload (can be any type, including `undefined` or `null`)
|
|
122
|
+
* @returns A {@link BaseResponse} with `success: true` and `data` property set
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* // Successful single record
|
|
127
|
+
* const response1 = successResponse({ id: '123', name: 'test' });
|
|
128
|
+
*
|
|
129
|
+
* // Array of records
|
|
130
|
+
* const response2 = successResponse([
|
|
131
|
+
* { id: '1', value: 100 },
|
|
132
|
+
* { id: '2', value: 200 },
|
|
133
|
+
* ]);
|
|
134
|
+
*
|
|
135
|
+
* // Null or undefined data (valid, though potentially unusual)
|
|
136
|
+
* const response3 = successResponse(null);
|
|
137
|
+
* ```
|
|
138
|
+
*
|
|
139
|
+
* @internal
|
|
140
|
+
* Timestamp is always included in the response envelope and formatted as ISO 8601.
|
|
141
|
+
*/
|
|
142
|
+
export declare function successResponse<T>(data: T): BaseResponse<T>;
|
|
143
|
+
/**
|
|
144
|
+
* Constructs an error API response.
|
|
145
|
+
*
|
|
146
|
+
* Creates a {@link BaseResponse} with `success: false`, the provided error message,
|
|
147
|
+
* and a timestamp set to the current time in ISO 8601 format.
|
|
148
|
+
*
|
|
149
|
+
* **Note:** This function accepts empty strings as valid error messages. While this
|
|
150
|
+
* is allowed by the runtime and type system, it is generally recommended to provide
|
|
151
|
+
* meaningful, non-empty error descriptions for better debugging and client-side handling.
|
|
152
|
+
*
|
|
153
|
+
* @param error - A descriptive error message (may be empty, though not recommended)
|
|
154
|
+
* @returns A {@link BaseResponse} with `success: false` and `error` property set
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* // Standard error
|
|
159
|
+
* const response1 = errorResponse('User not found');
|
|
160
|
+
*
|
|
161
|
+
* // Error with context
|
|
162
|
+
* const response2 = errorResponse('Invalid datetime format: expected ISO 8601');
|
|
163
|
+
*
|
|
164
|
+
* // Empty string (allowed but not recommended)
|
|
165
|
+
* const response3 = errorResponse('');
|
|
166
|
+
* ```
|
|
167
|
+
*
|
|
168
|
+
* @internal
|
|
169
|
+
* Timestamp is always included in the response envelope and formatted as ISO 8601.
|
|
170
|
+
*/
|
|
171
|
+
export declare function errorResponse(error: string): BaseResponse<never>;
|
|
172
|
+
/**
|
|
173
|
+
* Type guard to narrow a {@link BaseResponse} to a successful response.
|
|
174
|
+
*
|
|
175
|
+
* Checks if a response has `success: true`, allowing TypeScript to narrow
|
|
176
|
+
* the type to access the `data` property safely.
|
|
177
|
+
*
|
|
178
|
+
* @typeParam T - The expected type of the response data
|
|
179
|
+
* @param response - The response to check
|
|
180
|
+
* @returns `true` if the response is successful, `false` otherwise
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* async function fetchHistory(): Promise<BaseResponse<History[]>> {
|
|
185
|
+
* const response = await client.get('/history');
|
|
186
|
+
* if (isSuccessResponse<History[]>(response)) {
|
|
187
|
+
* // TypeScript now knows response.data is History[]
|
|
188
|
+
* const histories = response.data;
|
|
189
|
+
* return histories;
|
|
190
|
+
* }
|
|
191
|
+
* console.error('Failed:', response.error);
|
|
192
|
+
* }
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
export declare function isSuccessResponse<T>(response: BaseResponse<T>): response is BaseResponse<T> & {
|
|
196
|
+
success: true;
|
|
197
|
+
data: T;
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* Type guard to narrow a {@link BaseResponse} to an error response.
|
|
201
|
+
*
|
|
202
|
+
* Checks if a response has `success: false`, allowing TypeScript to narrow
|
|
203
|
+
* the type to access the `error` property safely.
|
|
204
|
+
*
|
|
205
|
+
* @param response - The response to check
|
|
206
|
+
* @returns `true` if the response is an error, `false` otherwise
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```typescript
|
|
210
|
+
* async function updateHistory(id: string, value: number): Promise<void> {
|
|
211
|
+
* const response = await client.patch(`/history/${id}`, { value });
|
|
212
|
+
* if (isErrorResponse(response)) {
|
|
213
|
+
* // TypeScript now knows response.error is string
|
|
214
|
+
* throw new Error(response.error);
|
|
215
|
+
* }
|
|
216
|
+
* // Success case
|
|
217
|
+
* }
|
|
218
|
+
* ```
|
|
219
|
+
*/
|
|
220
|
+
export declare function isErrorResponse(response: BaseResponse<unknown>): response is BaseResponse<never> & {
|
|
221
|
+
success: false;
|
|
222
|
+
error: string;
|
|
223
|
+
};
|
|
224
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,WAAW,EACX,YAAY,EACZ,aAAa,EACb,QAAQ,GACT,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAMtD;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;CAAE,CAAC;AAM3E;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,IAAI;IACnB,kCAAkC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,kCAAkC;IAClC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,uDAAuD;IACvD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,kDAAkD;IAClD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAMD;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,OAAO;IACtB,gDAAgD;IAChD,EAAE,EAAE,MAAM,CAAC;IACX,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,sDAAsD;IACtD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,oBAAoB;IACnC,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,oBAAoB;IACnC,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAoB;IACnC,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;CACf;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAE3D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAEhE;AAMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GACxB,QAAQ,IAAI,YAAY,CAAC,CAAC,CAAC,GAAG;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,CAE1D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,YAAY,CAAC,OAAO,CAAC,GAC9B,QAAQ,IAAI,YAAY,CAAC,KAAK,CAAC,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAErE"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Response Helpers
|
|
3
|
+
// =============================================================================
|
|
4
|
+
/**
|
|
5
|
+
* Constructs a successful API response.
|
|
6
|
+
*
|
|
7
|
+
* Creates a {@link BaseResponse} with `success: true`, the provided data payload,
|
|
8
|
+
* and a timestamp set to the current time in ISO 8601 format.
|
|
9
|
+
*
|
|
10
|
+
* @typeParam T - The type of the response payload
|
|
11
|
+
* @param data - The response payload (can be any type, including `undefined` or `null`)
|
|
12
|
+
* @returns A {@link BaseResponse} with `success: true` and `data` property set
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* // Successful single record
|
|
17
|
+
* const response1 = successResponse({ id: '123', name: 'test' });
|
|
18
|
+
*
|
|
19
|
+
* // Array of records
|
|
20
|
+
* const response2 = successResponse([
|
|
21
|
+
* { id: '1', value: 100 },
|
|
22
|
+
* { id: '2', value: 200 },
|
|
23
|
+
* ]);
|
|
24
|
+
*
|
|
25
|
+
* // Null or undefined data (valid, though potentially unusual)
|
|
26
|
+
* const response3 = successResponse(null);
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @internal
|
|
30
|
+
* Timestamp is always included in the response envelope and formatted as ISO 8601.
|
|
31
|
+
*/
|
|
32
|
+
export function successResponse(data) {
|
|
33
|
+
return { success: true, data, timestamp: new Date().toISOString() };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Constructs an error API response.
|
|
37
|
+
*
|
|
38
|
+
* Creates a {@link BaseResponse} with `success: false`, the provided error message,
|
|
39
|
+
* and a timestamp set to the current time in ISO 8601 format.
|
|
40
|
+
*
|
|
41
|
+
* **Note:** This function accepts empty strings as valid error messages. While this
|
|
42
|
+
* is allowed by the runtime and type system, it is generally recommended to provide
|
|
43
|
+
* meaningful, non-empty error descriptions for better debugging and client-side handling.
|
|
44
|
+
*
|
|
45
|
+
* @param error - A descriptive error message (may be empty, though not recommended)
|
|
46
|
+
* @returns A {@link BaseResponse} with `success: false` and `error` property set
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* // Standard error
|
|
51
|
+
* const response1 = errorResponse('User not found');
|
|
52
|
+
*
|
|
53
|
+
* // Error with context
|
|
54
|
+
* const response2 = errorResponse('Invalid datetime format: expected ISO 8601');
|
|
55
|
+
*
|
|
56
|
+
* // Empty string (allowed but not recommended)
|
|
57
|
+
* const response3 = errorResponse('');
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @internal
|
|
61
|
+
* Timestamp is always included in the response envelope and formatted as ISO 8601.
|
|
62
|
+
*/
|
|
63
|
+
export function errorResponse(error) {
|
|
64
|
+
return { success: false, error, timestamp: new Date().toISOString() };
|
|
65
|
+
}
|
|
66
|
+
// =============================================================================
|
|
67
|
+
// Type Guards
|
|
68
|
+
// =============================================================================
|
|
69
|
+
/**
|
|
70
|
+
* Type guard to narrow a {@link BaseResponse} to a successful response.
|
|
71
|
+
*
|
|
72
|
+
* Checks if a response has `success: true`, allowing TypeScript to narrow
|
|
73
|
+
* the type to access the `data` property safely.
|
|
74
|
+
*
|
|
75
|
+
* @typeParam T - The expected type of the response data
|
|
76
|
+
* @param response - The response to check
|
|
77
|
+
* @returns `true` if the response is successful, `false` otherwise
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* async function fetchHistory(): Promise<BaseResponse<History[]>> {
|
|
82
|
+
* const response = await client.get('/history');
|
|
83
|
+
* if (isSuccessResponse<History[]>(response)) {
|
|
84
|
+
* // TypeScript now knows response.data is History[]
|
|
85
|
+
* const histories = response.data;
|
|
86
|
+
* return histories;
|
|
87
|
+
* }
|
|
88
|
+
* console.error('Failed:', response.error);
|
|
89
|
+
* }
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export function isSuccessResponse(response) {
|
|
93
|
+
return response.success === true;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Type guard to narrow a {@link BaseResponse} to an error response.
|
|
97
|
+
*
|
|
98
|
+
* Checks if a response has `success: false`, allowing TypeScript to narrow
|
|
99
|
+
* the type to access the `error` property safely.
|
|
100
|
+
*
|
|
101
|
+
* @param response - The response to check
|
|
102
|
+
* @returns `true` if the response is an error, `false` otherwise
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* async function updateHistory(id: string, value: number): Promise<void> {
|
|
107
|
+
* const response = await client.patch(`/history/${id}`, { value });
|
|
108
|
+
* if (isErrorResponse(response)) {
|
|
109
|
+
* // TypeScript now knows response.error is string
|
|
110
|
+
* throw new Error(response.error);
|
|
111
|
+
* }
|
|
112
|
+
* // Success case
|
|
113
|
+
* }
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export function isErrorResponse(response) {
|
|
117
|
+
return response.success === false;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA4IA,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,eAAe,CAAI,IAAO;IACxC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;AACtE,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;AACxE,CAAC;AAED,gFAAgF;AAChF,cAAc;AACd,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAyB;IAEzB,OAAO,QAAQ,CAAC,OAAO,KAAK,IAAI,CAAC;AACnC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,eAAe,CAC7B,QAA+B;IAE/B,OAAO,QAAQ,CAAC,OAAO,KAAK,KAAK,CAAC;AACpC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sudobility/cravings_types",
|
|
3
|
+
"version": "0.0.5",
|
|
4
|
+
"description": "TypeScript types for Starter API - template project",
|
|
5
|
+
"main": "./dist/index.cjs",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"require": "./dist/index.cjs",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "bun run build:cjs && bun run build:esm",
|
|
17
|
+
"build:esm": "tsc -p tsconfig.esm.json",
|
|
18
|
+
"build:cjs": "tsc -p tsconfig.cjs.json && bun run build:cjs-rename",
|
|
19
|
+
"build:cjs-rename": "for f in dist/*.js; do mv \"$f\" \"${f%.js}.cjs\"; done",
|
|
20
|
+
"clean": "rimraf dist",
|
|
21
|
+
"dev": "tsc --watch",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"test:watch": "vitest",
|
|
24
|
+
"test:coverage": "vitest --coverage",
|
|
25
|
+
"lint": "eslint src --ext .ts",
|
|
26
|
+
"lint:fix": "eslint src --ext .ts --fix",
|
|
27
|
+
"format": "prettier --write \"src/**/*.{ts,js,json,md}\"",
|
|
28
|
+
"format:check": "prettier --check \"src/**/*.{ts,js,json,md}\"",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
30
|
+
"verify": "bun run typecheck && bun run lint && bun run test && bun run build",
|
|
31
|
+
"prepublishOnly": "bun run clean && bun run verify"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist/**/*",
|
|
35
|
+
"CLAUDE.md"
|
|
36
|
+
],
|
|
37
|
+
"keywords": [
|
|
38
|
+
"typescript",
|
|
39
|
+
"types",
|
|
40
|
+
"cravings",
|
|
41
|
+
"api"
|
|
42
|
+
],
|
|
43
|
+
"author": "Sudobility",
|
|
44
|
+
"license": "BUSL-1.1",
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"@sudobility/types": "^1.9.54"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@eslint/js": "^9.38.0",
|
|
50
|
+
"@sudobility/types": "^1.9.54",
|
|
51
|
+
"@typescript-eslint/eslint-plugin": "^8.46.2",
|
|
52
|
+
"@typescript-eslint/parser": "^8.46.2",
|
|
53
|
+
"eslint": "^9.38.0",
|
|
54
|
+
"globals": "^16.4.0",
|
|
55
|
+
"prettier": "^3.6.2",
|
|
56
|
+
"rimraf": "^6.0.1",
|
|
57
|
+
"typescript": "^5.9.3",
|
|
58
|
+
"vitest": "^4.0.15"
|
|
59
|
+
},
|
|
60
|
+
"publishConfig": {
|
|
61
|
+
"access": "public"
|
|
62
|
+
}
|
|
63
|
+
}
|