genjutsu-db 0.1.0
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/LICENSE +21 -0
- package/README.md +360 -0
- package/dist/client.d.ts +7 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +370 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +38 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +59 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/migrations.d.ts +11 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +163 -0
- package/dist/migrations.js.map +1 -0
- package/dist/model.d.ts +27 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +138 -0
- package/dist/model.js.map +1 -0
- package/dist/relations.d.ts +17 -0
- package/dist/relations.d.ts.map +1 -0
- package/dist/relations.js +114 -0
- package/dist/relations.js.map +1 -0
- package/dist/transport.d.ts +32 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +232 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +104 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +14 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +57 -0
- package/dist/utils.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level HTTP transport for Google Sheets v4 REST API.
|
|
3
|
+
* Supports token provider pattern, 401 retry, 403→PERMISSION_ERROR, apiKey for public sheets.
|
|
4
|
+
*/
|
|
5
|
+
import { authError, permissionError, rateLimitError, networkError, apiError, } from "./errors";
|
|
6
|
+
export const SHEETS_API = "https://sheets.googleapis.com/v4/spreadsheets";
|
|
7
|
+
async function resolveToken(auth) {
|
|
8
|
+
return typeof auth === "function" ? auth() : auth;
|
|
9
|
+
}
|
|
10
|
+
export function extractSpreadsheetId(urlOrId) {
|
|
11
|
+
const match = urlOrId.match(/\/d\/([a-zA-Z0-9-_]+)/);
|
|
12
|
+
if (match)
|
|
13
|
+
return match[1];
|
|
14
|
+
// If no slashes, treat as a bare ID
|
|
15
|
+
if (!urlOrId.includes("/"))
|
|
16
|
+
return urlOrId;
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
function parseRetryAfterMs(res) {
|
|
20
|
+
const header = res.headers.get("Retry-After");
|
|
21
|
+
if (!header)
|
|
22
|
+
return undefined;
|
|
23
|
+
const seconds = parseInt(header, 10);
|
|
24
|
+
return Number.isNaN(seconds) ? undefined : seconds * 1000;
|
|
25
|
+
}
|
|
26
|
+
function wrapHttpError(status, body, cause) {
|
|
27
|
+
if (status === 401) {
|
|
28
|
+
throw authError(`Authentication failed: ${status} ${body}`, cause);
|
|
29
|
+
}
|
|
30
|
+
if (status === 403) {
|
|
31
|
+
throw permissionError(`Permission denied: ${status} ${body}`, cause);
|
|
32
|
+
}
|
|
33
|
+
if (status === 429) {
|
|
34
|
+
throw rateLimitError(`Rate limited: ${status} ${body}`, undefined, cause);
|
|
35
|
+
}
|
|
36
|
+
throw apiError(`Sheets API error: ${status} ${body}`, cause);
|
|
37
|
+
}
|
|
38
|
+
async function buildAuthHeaders(ctx) {
|
|
39
|
+
if (ctx.auth) {
|
|
40
|
+
const token = await resolveToken(ctx.auth);
|
|
41
|
+
return { Authorization: `Bearer ${token}` };
|
|
42
|
+
}
|
|
43
|
+
return {};
|
|
44
|
+
}
|
|
45
|
+
function buildApiKeyParam(ctx) {
|
|
46
|
+
if (ctx.apiKey && !ctx.auth) {
|
|
47
|
+
return `key=${encodeURIComponent(ctx.apiKey)}`;
|
|
48
|
+
}
|
|
49
|
+
return "";
|
|
50
|
+
}
|
|
51
|
+
function appendParams(url, extra) {
|
|
52
|
+
if (!extra)
|
|
53
|
+
return url;
|
|
54
|
+
return url.includes("?") ? `${url}&${extra}` : `${url}?${extra}`;
|
|
55
|
+
}
|
|
56
|
+
async function fetchWithErrorHandling(url, init, ctx, retryOn401 = true) {
|
|
57
|
+
let res;
|
|
58
|
+
try {
|
|
59
|
+
res = await fetch(url, init);
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
throw networkError(`Network request failed: ${err instanceof Error ? err.message : String(err)}`, err);
|
|
63
|
+
}
|
|
64
|
+
// 401 retry: if auth is a function, call it again for a fresh token and retry once
|
|
65
|
+
if (res.status === 401 && retryOn401 && typeof ctx.auth === "function") {
|
|
66
|
+
const freshToken = await ctx.auth();
|
|
67
|
+
const retryInit = {
|
|
68
|
+
...init,
|
|
69
|
+
headers: {
|
|
70
|
+
...init.headers,
|
|
71
|
+
Authorization: `Bearer ${freshToken}`,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
let retryRes;
|
|
75
|
+
try {
|
|
76
|
+
retryRes = await fetch(url, retryInit);
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
throw networkError(`Network request failed on retry: ${err instanceof Error ? err.message : String(err)}`, err);
|
|
80
|
+
}
|
|
81
|
+
if (!retryRes.ok) {
|
|
82
|
+
const body = await retryRes.text();
|
|
83
|
+
if (retryRes.status === 429) {
|
|
84
|
+
throw rateLimitError(`Rate limited: ${retryRes.status} ${body}`, parseRetryAfterMs(retryRes), retryRes);
|
|
85
|
+
}
|
|
86
|
+
wrapHttpError(retryRes.status, body, retryRes);
|
|
87
|
+
}
|
|
88
|
+
return retryRes;
|
|
89
|
+
}
|
|
90
|
+
if (!res.ok) {
|
|
91
|
+
const body = await res.text();
|
|
92
|
+
if (res.status === 429) {
|
|
93
|
+
throw rateLimitError(`Rate limited: ${res.status} ${body}`, parseRetryAfterMs(res), res);
|
|
94
|
+
}
|
|
95
|
+
wrapHttpError(res.status, body, res);
|
|
96
|
+
}
|
|
97
|
+
return res;
|
|
98
|
+
}
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
// Read Operations
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
export async function getSheetValues(ctx, range, valueRenderOption = "FORMATTED_VALUE") {
|
|
103
|
+
const params = new URLSearchParams({ valueRenderOption });
|
|
104
|
+
let url = `${SHEETS_API}/${ctx.spreadsheetId}/values/${encodeURIComponent(range)}?${params}`;
|
|
105
|
+
url = appendParams(url, buildApiKeyParam(ctx));
|
|
106
|
+
const headers = await buildAuthHeaders(ctx);
|
|
107
|
+
const res = await fetchWithErrorHandling(url, { headers }, ctx);
|
|
108
|
+
const data = (await res.json());
|
|
109
|
+
const values = data.values;
|
|
110
|
+
if (!Array.isArray(values) || values.length === 0)
|
|
111
|
+
return [];
|
|
112
|
+
return values.map((row) => (Array.isArray(row) ? [...row] : []));
|
|
113
|
+
}
|
|
114
|
+
export async function batchGetValues(ctx, ranges, valueRenderOption = "FORMATTED_VALUE") {
|
|
115
|
+
if (ranges.length === 0)
|
|
116
|
+
return new Map();
|
|
117
|
+
const params = new URLSearchParams({ valueRenderOption });
|
|
118
|
+
for (const r of ranges)
|
|
119
|
+
params.append("ranges", r);
|
|
120
|
+
let url = `${SHEETS_API}/${ctx.spreadsheetId}/values:batchGet?${params}`;
|
|
121
|
+
url = appendParams(url, buildApiKeyParam(ctx));
|
|
122
|
+
const headers = await buildAuthHeaders(ctx);
|
|
123
|
+
const res = await fetchWithErrorHandling(url, { headers }, ctx);
|
|
124
|
+
const data = (await res.json());
|
|
125
|
+
const result = new Map();
|
|
126
|
+
const valueRanges = data.valueRanges ?? [];
|
|
127
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
128
|
+
const vr = valueRanges[i];
|
|
129
|
+
const values = vr?.values ?? [];
|
|
130
|
+
result.set(ranges[i], values.map((row) => (Array.isArray(row) ? [...row] : [])));
|
|
131
|
+
}
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
// Write Operations
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
export async function updateSheet(ctx, range, values, append) {
|
|
138
|
+
const url = append
|
|
139
|
+
? `${SHEETS_API}/${ctx.spreadsheetId}/values/${encodeURIComponent(range)}:append?valueInputOption=USER_ENTERED`
|
|
140
|
+
: `${SHEETS_API}/${ctx.spreadsheetId}/values/${encodeURIComponent(range)}?valueInputOption=USER_ENTERED`;
|
|
141
|
+
const method = append ? "POST" : "PUT";
|
|
142
|
+
const headers = {
|
|
143
|
+
...(await buildAuthHeaders(ctx)),
|
|
144
|
+
"Content-Type": "application/json",
|
|
145
|
+
};
|
|
146
|
+
await fetchWithErrorHandling(url, { method, headers, body: JSON.stringify({ values }) }, ctx);
|
|
147
|
+
}
|
|
148
|
+
export async function clearRange(ctx, range) {
|
|
149
|
+
const url = `${SHEETS_API}/${ctx.spreadsheetId}/values/${encodeURIComponent(range)}:clear`;
|
|
150
|
+
const headers = {
|
|
151
|
+
...(await buildAuthHeaders(ctx)),
|
|
152
|
+
"Content-Type": "application/json",
|
|
153
|
+
};
|
|
154
|
+
await fetchWithErrorHandling(url, { method: "POST", headers, body: JSON.stringify({}) }, ctx);
|
|
155
|
+
}
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
// Batch Operations
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
export async function batchClear(ctx, ranges) {
|
|
160
|
+
const url = `${SHEETS_API}/${ctx.spreadsheetId}/values:batchClear`;
|
|
161
|
+
const headers = {
|
|
162
|
+
...(await buildAuthHeaders(ctx)),
|
|
163
|
+
"Content-Type": "application/json",
|
|
164
|
+
};
|
|
165
|
+
const res = await fetchWithErrorHandling(url, { method: "POST", headers, body: JSON.stringify({ ranges }) }, ctx);
|
|
166
|
+
// Response consumed by fetchWithErrorHandling
|
|
167
|
+
void res;
|
|
168
|
+
}
|
|
169
|
+
export async function batchUpdate(ctx, data) {
|
|
170
|
+
const url = `${SHEETS_API}/${ctx.spreadsheetId}/values:batchUpdate`;
|
|
171
|
+
const headers = {
|
|
172
|
+
...(await buildAuthHeaders(ctx)),
|
|
173
|
+
"Content-Type": "application/json",
|
|
174
|
+
};
|
|
175
|
+
const res = await fetchWithErrorHandling(url, {
|
|
176
|
+
method: "POST",
|
|
177
|
+
headers,
|
|
178
|
+
body: JSON.stringify({ data, valueInputOption: "USER_ENTERED" }),
|
|
179
|
+
}, ctx);
|
|
180
|
+
void res;
|
|
181
|
+
}
|
|
182
|
+
// ---------------------------------------------------------------------------
|
|
183
|
+
// Spreadsheet Metadata
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
export async function getSpreadsheetMetadata(ctx) {
|
|
186
|
+
let url = `${SHEETS_API}/${ctx.spreadsheetId}?fields=sheets.properties(sheetId,title)`;
|
|
187
|
+
url = appendParams(url, buildApiKeyParam(ctx));
|
|
188
|
+
const headers = await buildAuthHeaders(ctx);
|
|
189
|
+
const res = await fetchWithErrorHandling(url, { headers }, ctx);
|
|
190
|
+
const data = (await res.json());
|
|
191
|
+
return {
|
|
192
|
+
sheets: (data.sheets ?? []).map((s) => ({
|
|
193
|
+
sheetId: s.properties.sheetId,
|
|
194
|
+
title: s.properties.title,
|
|
195
|
+
})),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
// ---------------------------------------------------------------------------
|
|
199
|
+
// Structural Operations (for migrations)
|
|
200
|
+
// ---------------------------------------------------------------------------
|
|
201
|
+
export async function structuralBatchUpdate(ctx, requests) {
|
|
202
|
+
const url = `${SHEETS_API}/${ctx.spreadsheetId}:batchUpdate`;
|
|
203
|
+
const headers = {
|
|
204
|
+
...(await buildAuthHeaders(ctx)),
|
|
205
|
+
"Content-Type": "application/json",
|
|
206
|
+
};
|
|
207
|
+
await fetchWithErrorHandling(url, { method: "POST", headers, body: JSON.stringify({ requests }) }, ctx);
|
|
208
|
+
}
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
// Spreadsheet Creation
|
|
211
|
+
// ---------------------------------------------------------------------------
|
|
212
|
+
export async function createSpreadsheet(title, auth) {
|
|
213
|
+
const token = await resolveToken(auth);
|
|
214
|
+
const res = await fetch(SHEETS_API, {
|
|
215
|
+
method: "POST",
|
|
216
|
+
headers: {
|
|
217
|
+
Authorization: `Bearer ${token}`,
|
|
218
|
+
"Content-Type": "application/json",
|
|
219
|
+
},
|
|
220
|
+
body: JSON.stringify({ properties: { title } }),
|
|
221
|
+
});
|
|
222
|
+
if (!res.ok) {
|
|
223
|
+
const body = await res.text();
|
|
224
|
+
throw apiError(`Failed to create spreadsheet: ${res.status} ${body}`);
|
|
225
|
+
}
|
|
226
|
+
const data = (await res.json());
|
|
227
|
+
return {
|
|
228
|
+
spreadsheetId: data.spreadsheetId,
|
|
229
|
+
spreadsheetUrl: data.spreadsheetUrl,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic types for the genjutsu-db library.
|
|
3
|
+
* Schema-driven API: SheetSchema<T>, Repository<T>, GenjutsuClient<S>, and supporting types.
|
|
4
|
+
*/
|
|
5
|
+
export interface FormattingRule {
|
|
6
|
+
startCol: number;
|
|
7
|
+
endCol: number;
|
|
8
|
+
startRow?: number;
|
|
9
|
+
endRow?: number;
|
|
10
|
+
bold?: boolean;
|
|
11
|
+
fontSize?: number;
|
|
12
|
+
horizontalAlignment?: "LEFT" | "CENTER" | "RIGHT";
|
|
13
|
+
numberFormat?: {
|
|
14
|
+
type: string;
|
|
15
|
+
pattern?: string;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export interface HeaderFormat {
|
|
19
|
+
bold?: boolean;
|
|
20
|
+
fontSize?: number;
|
|
21
|
+
horizontalAlignment?: "LEFT" | "CENTER" | "RIGHT";
|
|
22
|
+
}
|
|
23
|
+
export interface FieldDefinition {
|
|
24
|
+
name: string;
|
|
25
|
+
type: "string" | "number" | "date" | "boolean";
|
|
26
|
+
isPrimaryKey?: boolean;
|
|
27
|
+
isOptional?: boolean;
|
|
28
|
+
defaultValue?: unknown;
|
|
29
|
+
references?: {
|
|
30
|
+
model: string;
|
|
31
|
+
field: string;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export interface RelationDefinition {
|
|
35
|
+
sourceField: string;
|
|
36
|
+
targetModel: string;
|
|
37
|
+
targetField: string;
|
|
38
|
+
type: "many-to-one";
|
|
39
|
+
}
|
|
40
|
+
export interface SheetSchema<T> {
|
|
41
|
+
sheetName: string;
|
|
42
|
+
headers: string[];
|
|
43
|
+
readRange: string;
|
|
44
|
+
writeRange: string;
|
|
45
|
+
clearRange: string;
|
|
46
|
+
parseRow(row: unknown[], rowIndex: number): T | null;
|
|
47
|
+
toRow(entity: T): unknown[];
|
|
48
|
+
validate?: (entity: T) => void;
|
|
49
|
+
appendSupported?: boolean;
|
|
50
|
+
formatting?: FormattingRule[];
|
|
51
|
+
headerFormatting?: HeaderFormat;
|
|
52
|
+
primaryKey?: string;
|
|
53
|
+
fields?: FieldDefinition[];
|
|
54
|
+
relations?: RelationDefinition[];
|
|
55
|
+
}
|
|
56
|
+
export type InferEntity<S> = S extends SheetSchema<infer T> ? T : never;
|
|
57
|
+
export interface FindOptions {
|
|
58
|
+
include?: Record<string, true>;
|
|
59
|
+
}
|
|
60
|
+
export interface ReadOptions {
|
|
61
|
+
include?: Record<string, true>;
|
|
62
|
+
}
|
|
63
|
+
export interface WriteOptions {
|
|
64
|
+
skipFkValidation?: boolean;
|
|
65
|
+
}
|
|
66
|
+
export interface Repository<T> {
|
|
67
|
+
create(record: Partial<T>, options?: WriteOptions): Promise<T>;
|
|
68
|
+
findById(id: string | number): Promise<T | null>;
|
|
69
|
+
findMany(filter?: (item: T) => boolean, options?: FindOptions): Promise<T[]>;
|
|
70
|
+
update(id: string | number, changes: Partial<T>, options?: WriteOptions): Promise<T>;
|
|
71
|
+
delete(id: string | number): Promise<void>;
|
|
72
|
+
readAll(options?: ReadOptions): Promise<T[]>;
|
|
73
|
+
writeAll(records: T[]): Promise<void>;
|
|
74
|
+
append(records: T[]): Promise<void>;
|
|
75
|
+
}
|
|
76
|
+
export interface ClientConfig<S extends Record<string, SheetSchema<any>>> {
|
|
77
|
+
spreadsheetId: string;
|
|
78
|
+
auth?: string | (() => Promise<string>);
|
|
79
|
+
apiKey?: string;
|
|
80
|
+
schemas: S;
|
|
81
|
+
}
|
|
82
|
+
export interface GenjutsuClient<S extends Record<string, SheetSchema<any>>> {
|
|
83
|
+
repo<K extends keyof S & string>(key: K): Repository<InferEntity<S[K]>>;
|
|
84
|
+
batchSync(payload: Partial<{
|
|
85
|
+
[K in keyof S]: InferEntity<S[K]>[];
|
|
86
|
+
}>): Promise<void>;
|
|
87
|
+
ensureSchema(): Promise<void>;
|
|
88
|
+
applyFormatting(): Promise<void>;
|
|
89
|
+
migrate(migrations: Migration[]): Promise<void>;
|
|
90
|
+
extractSpreadsheetId(urlOrId: string): string | null;
|
|
91
|
+
}
|
|
92
|
+
export interface Migration {
|
|
93
|
+
version: number;
|
|
94
|
+
name: string;
|
|
95
|
+
up: (ctx: MigrationContext) => Promise<void>;
|
|
96
|
+
}
|
|
97
|
+
export interface MigrationContext {
|
|
98
|
+
createSheet(name: string): Promise<void>;
|
|
99
|
+
addColumn(sheet: string, column: string, afterIndex?: number): Promise<void>;
|
|
100
|
+
removeColumn(sheet: string, columnIndex: number): Promise<void>;
|
|
101
|
+
renameColumn(sheet: string, columnIndex: number, newName: string): Promise<void>;
|
|
102
|
+
renameSheet(oldName: string, newName: string): Promise<void>;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic utility functions for the genjutsu-db library.
|
|
3
|
+
* Domain-agnostic helpers for date parsing, amount parsing,
|
|
4
|
+
* header validation, ID generation, and row detection.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isValidDate(date: string): boolean;
|
|
7
|
+
export declare function tryRepairDate(value: string): string | null;
|
|
8
|
+
export declare function normalizeDate(value: unknown): string | null;
|
|
9
|
+
export declare function looksLikeIsoDate(value: string): boolean;
|
|
10
|
+
export declare function parseAmount(value: unknown): number | null;
|
|
11
|
+
export declare function hasIdColumn(row: unknown[], minLength: number, looksLikeDate: (v: string) => boolean): boolean;
|
|
12
|
+
export declare function findMissingHeaders(actualHeaders: string[], requiredHeaders: string[]): string[];
|
|
13
|
+
export declare function generateId(): string;
|
|
14
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAYD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAO1D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAK3D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAKzD;AAED,wBAAgB,WAAW,CACzB,GAAG,EAAE,OAAO,EAAE,EACd,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,GACpC,OAAO,CAGT;AAED,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,EAAE,EACvB,eAAe,EAAE,MAAM,EAAE,GACxB,MAAM,EAAE,CAGV;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic utility functions for the genjutsu-db library.
|
|
3
|
+
* Domain-agnostic helpers for date parsing, amount parsing,
|
|
4
|
+
* header validation, ID generation, and row detection.
|
|
5
|
+
*/
|
|
6
|
+
const ISO_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
7
|
+
export function isValidDate(date) {
|
|
8
|
+
return ISO_DATE_PATTERN.test(date);
|
|
9
|
+
}
|
|
10
|
+
function serialToIsoDate(serial) {
|
|
11
|
+
const epoch = new Date(1899, 11, 30).getTime();
|
|
12
|
+
const ms = serial * 86400000 + epoch;
|
|
13
|
+
const d = new Date(ms);
|
|
14
|
+
const y = d.getFullYear();
|
|
15
|
+
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
16
|
+
const day = String(d.getDate()).padStart(2, "0");
|
|
17
|
+
return `${y}-${m}-${day}`;
|
|
18
|
+
}
|
|
19
|
+
export function tryRepairDate(value) {
|
|
20
|
+
if (ISO_DATE_PATTERN.test(value.trim()))
|
|
21
|
+
return value.trim();
|
|
22
|
+
const num = parseFloat(value.replace(/[$,\s]/g, ""));
|
|
23
|
+
if (!Number.isNaN(num) && num > 0 && num < 1000000) {
|
|
24
|
+
return serialToIsoDate(num);
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
export function normalizeDate(value) {
|
|
29
|
+
if (value == null)
|
|
30
|
+
return null;
|
|
31
|
+
const s = String(value).trim();
|
|
32
|
+
if (ISO_DATE_PATTERN.test(s))
|
|
33
|
+
return s;
|
|
34
|
+
return tryRepairDate(s);
|
|
35
|
+
}
|
|
36
|
+
export function looksLikeIsoDate(value) {
|
|
37
|
+
return ISO_DATE_PATTERN.test(value.trim());
|
|
38
|
+
}
|
|
39
|
+
export function parseAmount(value) {
|
|
40
|
+
if (typeof value === "number" && !Number.isNaN(value))
|
|
41
|
+
return value;
|
|
42
|
+
const s = String(value ?? "").replace(/[$,\s]/g, "");
|
|
43
|
+
const n = parseFloat(s);
|
|
44
|
+
return Number.isNaN(n) ? null : n;
|
|
45
|
+
}
|
|
46
|
+
export function hasIdColumn(row, minLength, looksLikeDate) {
|
|
47
|
+
const first = String(row[0] ?? "").trim();
|
|
48
|
+
return row.length >= minLength && first.length > 0 && !looksLikeDate(first);
|
|
49
|
+
}
|
|
50
|
+
export function findMissingHeaders(actualHeaders, requiredHeaders) {
|
|
51
|
+
const normalized = new Set(actualHeaders.map((h) => h.trim().toLowerCase()));
|
|
52
|
+
return requiredHeaders.filter((h) => !normalized.has(h.toLowerCase()));
|
|
53
|
+
}
|
|
54
|
+
export function generateId() {
|
|
55
|
+
return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "genjutsu-db",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "A TypeScript-first Google Sheets database library with zero runtime dependencies",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist/"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc -p tsconfig.build.json",
|
|
19
|
+
"test": "bun test",
|
|
20
|
+
"lint": "tsc --noEmit",
|
|
21
|
+
"prepublishOnly": "bun test && bun run build"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"google-sheets",
|
|
25
|
+
"database",
|
|
26
|
+
"orm",
|
|
27
|
+
"typescript",
|
|
28
|
+
"spreadsheet"
|
|
29
|
+
],
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"author": "Ayaz Uddin",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/Ayaz2589/Genjutsu-DB.git"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://github.com/Ayaz2589/Genjutsu-DB#readme",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/Ayaz2589/Genjutsu-DB/issues"
|
|
39
|
+
},
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=18"
|
|
42
|
+
},
|
|
43
|
+
"sideEffects": false,
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"typescript": "^5.7.0",
|
|
46
|
+
"@types/bun": "^1.2.0"
|
|
47
|
+
}
|
|
48
|
+
}
|