@b2bc-devkit/sheetorm 1.2.3 → 1.2.4
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/dist/npm/SheetOrm.d.ts +41 -0
- package/dist/npm/SheetOrm.d.ts.map +1 -0
- package/dist/npm/SheetOrm.js +41 -0
- package/dist/npm/SheetOrm.js.map +1 -0
- package/dist/npm/core/Decorators.d.ts +145 -0
- package/dist/npm/core/Decorators.d.ts.map +1 -0
- package/dist/npm/core/Decorators.js +226 -0
- package/dist/npm/core/Decorators.js.map +1 -0
- package/dist/npm/core/Record.d.ts +184 -0
- package/dist/npm/core/Record.d.ts.map +1 -0
- package/dist/npm/core/Record.js +321 -0
- package/dist/npm/core/Record.js.map +1 -0
- package/dist/npm/core/RecordConstructor.d.ts +20 -0
- package/dist/npm/core/RecordConstructor.d.ts.map +1 -0
- package/dist/npm/core/RecordConstructor.js +2 -0
- package/dist/npm/core/RecordConstructor.js.map +1 -0
- package/dist/npm/core/RecordStatic.d.ts +25 -0
- package/dist/npm/core/RecordStatic.d.ts.map +1 -0
- package/dist/npm/core/RecordStatic.js +2 -0
- package/dist/npm/core/RecordStatic.js.map +1 -0
- package/dist/npm/core/Registry.d.ts +101 -0
- package/dist/npm/core/Registry.d.ts.map +1 -0
- package/dist/npm/core/Registry.js +231 -0
- package/dist/npm/core/Registry.js.map +1 -0
- package/dist/npm/core/SheetRepository.d.ts +331 -0
- package/dist/npm/core/SheetRepository.d.ts.map +1 -0
- package/dist/npm/core/SheetRepository.js +1041 -0
- package/dist/npm/core/SheetRepository.js.map +1 -0
- package/dist/npm/core/cache/MemoryCache.d.ts +67 -0
- package/dist/npm/core/cache/MemoryCache.d.ts.map +1 -0
- package/dist/npm/core/cache/MemoryCache.js +112 -0
- package/dist/npm/core/cache/MemoryCache.js.map +1 -0
- package/dist/npm/core/types/Entity.d.ts +21 -0
- package/dist/npm/core/types/Entity.d.ts.map +1 -0
- package/dist/npm/core/types/Entity.js +2 -0
- package/dist/npm/core/types/Entity.js.map +1 -0
- package/dist/npm/core/types/FieldDefinition.d.ts +21 -0
- package/dist/npm/core/types/FieldDefinition.d.ts.map +1 -0
- package/dist/npm/core/types/FieldDefinition.js +2 -0
- package/dist/npm/core/types/FieldDefinition.js.map +1 -0
- package/dist/npm/core/types/FieldType.d.ts +12 -0
- package/dist/npm/core/types/FieldType.d.ts.map +1 -0
- package/dist/npm/core/types/FieldType.js +2 -0
- package/dist/npm/core/types/FieldType.js.map +1 -0
- package/dist/npm/core/types/Filter.d.ts +16 -0
- package/dist/npm/core/types/Filter.d.ts.map +1 -0
- package/dist/npm/core/types/Filter.js +2 -0
- package/dist/npm/core/types/Filter.js.map +1 -0
- package/dist/npm/core/types/FilterOperator.d.ts +16 -0
- package/dist/npm/core/types/FilterOperator.d.ts.map +1 -0
- package/dist/npm/core/types/FilterOperator.js +2 -0
- package/dist/npm/core/types/FilterOperator.js.map +1 -0
- package/dist/npm/core/types/GroupResult.d.ts +14 -0
- package/dist/npm/core/types/GroupResult.d.ts.map +1 -0
- package/dist/npm/core/types/GroupResult.js +2 -0
- package/dist/npm/core/types/GroupResult.js.map +1 -0
- package/dist/npm/core/types/ICacheProvider.d.ts +20 -0
- package/dist/npm/core/types/ICacheProvider.d.ts.map +1 -0
- package/dist/npm/core/types/ICacheProvider.js +2 -0
- package/dist/npm/core/types/ICacheProvider.js.map +1 -0
- package/dist/npm/core/types/ISheetAdapter.d.ts +53 -0
- package/dist/npm/core/types/ISheetAdapter.d.ts.map +1 -0
- package/dist/npm/core/types/ISheetAdapter.js +2 -0
- package/dist/npm/core/types/ISheetAdapter.js.map +1 -0
- package/dist/npm/core/types/ISpreadsheetAdapter.d.ts +49 -0
- package/dist/npm/core/types/ISpreadsheetAdapter.d.ts.map +1 -0
- package/dist/npm/core/types/ISpreadsheetAdapter.js +2 -0
- package/dist/npm/core/types/ISpreadsheetAdapter.js.map +1 -0
- package/dist/npm/core/types/IndexDefinition.d.ts +16 -0
- package/dist/npm/core/types/IndexDefinition.d.ts.map +1 -0
- package/dist/npm/core/types/IndexDefinition.js +2 -0
- package/dist/npm/core/types/IndexDefinition.js.map +1 -0
- package/dist/npm/core/types/LifecycleHooks.d.ts +32 -0
- package/dist/npm/core/types/LifecycleHooks.d.ts.map +1 -0
- package/dist/npm/core/types/LifecycleHooks.js +2 -0
- package/dist/npm/core/types/LifecycleHooks.js.map +1 -0
- package/dist/npm/core/types/PaginatedResult.d.ts +18 -0
- package/dist/npm/core/types/PaginatedResult.d.ts.map +1 -0
- package/dist/npm/core/types/PaginatedResult.js +2 -0
- package/dist/npm/core/types/PaginatedResult.js.map +1 -0
- package/dist/npm/core/types/QueryOptions.d.ts +21 -0
- package/dist/npm/core/types/QueryOptions.d.ts.map +1 -0
- package/dist/npm/core/types/QueryOptions.js +2 -0
- package/dist/npm/core/types/QueryOptions.js.map +1 -0
- package/dist/npm/core/types/SortClause.d.ts +10 -0
- package/dist/npm/core/types/SortClause.d.ts.map +1 -0
- package/dist/npm/core/types/SortClause.js +2 -0
- package/dist/npm/core/types/SortClause.js.map +1 -0
- package/dist/npm/core/types/SystemColumns.d.ts +16 -0
- package/dist/npm/core/types/SystemColumns.d.ts.map +1 -0
- package/dist/npm/core/types/SystemColumns.js +16 -0
- package/dist/npm/core/types/SystemColumns.js.map +1 -0
- package/dist/npm/core/types/TableSchema.d.ts +24 -0
- package/dist/npm/core/types/TableSchema.d.ts.map +1 -0
- package/dist/npm/core/types/TableSchema.js +2 -0
- package/dist/npm/core/types/TableSchema.js.map +1 -0
- package/dist/npm/index/IndexMeta.d.ts +16 -0
- package/dist/npm/index/IndexMeta.d.ts.map +1 -0
- package/dist/npm/index/IndexMeta.js +2 -0
- package/dist/npm/index/IndexMeta.js.map +1 -0
- package/dist/npm/index/IndexStore.d.ts +397 -0
- package/dist/npm/index/IndexStore.d.ts.map +1 -0
- package/dist/npm/index/IndexStore.js +1102 -0
- package/dist/npm/index/IndexStore.js.map +1 -0
- package/dist/npm/index.d.ts +117 -0
- package/dist/npm/index.d.ts.map +1 -0
- package/dist/npm/index.js +371 -0
- package/dist/npm/index.js.map +1 -0
- package/dist/npm/query/Query.d.ts +176 -0
- package/dist/npm/query/Query.d.ts.map +1 -0
- package/dist/npm/query/Query.js +270 -0
- package/dist/npm/query/Query.js.map +1 -0
- package/dist/npm/query/QueryEngine.d.ts +140 -0
- package/dist/npm/query/QueryEngine.d.ts.map +1 -0
- package/dist/npm/query/QueryEngine.js +453 -0
- package/dist/npm/query/QueryEngine.js.map +1 -0
- package/dist/npm/storage/GoogleSheetAdapter.d.ts +119 -0
- package/dist/npm/storage/GoogleSheetAdapter.d.ts.map +1 -0
- package/dist/npm/storage/GoogleSheetAdapter.js +238 -0
- package/dist/npm/storage/GoogleSheetAdapter.js.map +1 -0
- package/dist/npm/storage/GoogleSpreadsheetAdapter.d.ts +71 -0
- package/dist/npm/storage/GoogleSpreadsheetAdapter.d.ts.map +1 -0
- package/dist/npm/storage/GoogleSpreadsheetAdapter.js +131 -0
- package/dist/npm/storage/GoogleSpreadsheetAdapter.js.map +1 -0
- package/dist/npm/testing/ParityCatalog.d.ts +38 -0
- package/dist/npm/testing/ParityCatalog.d.ts.map +1 -0
- package/dist/npm/testing/ParityCatalog.js +407 -0
- package/dist/npm/testing/ParityCatalog.js.map +1 -0
- package/dist/npm/testing/RuntimeBenchmark.d.ts +37 -0
- package/dist/npm/testing/RuntimeBenchmark.d.ts.map +1 -0
- package/dist/npm/testing/RuntimeBenchmark.js +449 -0
- package/dist/npm/testing/RuntimeBenchmark.js.map +1 -0
- package/dist/npm/testing/RuntimeParity.d.ts +66 -0
- package/dist/npm/testing/RuntimeParity.d.ts.map +1 -0
- package/dist/npm/testing/RuntimeParity.js +4193 -0
- package/dist/npm/testing/RuntimeParity.js.map +1 -0
- package/dist/npm/utils/Serialization.d.ts +111 -0
- package/dist/npm/utils/Serialization.d.ts.map +1 -0
- package/dist/npm/utils/Serialization.js +281 -0
- package/dist/npm/utils/Serialization.js.map +1 -0
- package/dist/npm/utils/SheetOrmLogger.d.ts +31 -0
- package/dist/npm/utils/SheetOrmLogger.d.ts.map +1 -0
- package/dist/npm/utils/SheetOrmLogger.js +42 -0
- package/dist/npm/utils/SheetOrmLogger.js.map +1 -0
- package/dist/npm/utils/Uuid.d.ts +29 -0
- package/dist/npm/utils/Uuid.d.ts.map +1 -0
- package/dist/npm/utils/Uuid.js +86 -0
- package/dist/npm/utils/Uuid.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module SheetOrm
|
|
3
|
+
*
|
|
4
|
+
* NPM package entry point for the SheetORM library.
|
|
5
|
+
*
|
|
6
|
+
* Re-exports the core public API surface as static members of a single
|
|
7
|
+
* namespace class. Consumer code imports from this module:
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { SheetOrm } from "sheetorm";
|
|
11
|
+
* const { Record, Query, Decorators, IndexStore, Registry } = SheetOrm;
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* This file is referenced by `tsconfig.npm.json` and the npm build
|
|
15
|
+
* script; it does **not** include GAS-specific helpers (e.g. demos,
|
|
16
|
+
* test runners) that live in `index.ts`.
|
|
17
|
+
*/
|
|
18
|
+
import { Decorators } from "./core/Decorators.js";
|
|
19
|
+
import { Record } from "./core/Record.js";
|
|
20
|
+
import { Registry } from "./core/Registry.js";
|
|
21
|
+
import { IndexStore } from "./index/IndexStore.js";
|
|
22
|
+
import { Query } from "./query/Query.js";
|
|
23
|
+
/**
|
|
24
|
+
* Top-level namespace class that bundles every public SheetORM artifact.
|
|
25
|
+
*
|
|
26
|
+
* Designed as a single default import so consumers can destructure
|
|
27
|
+
* only the parts they need without deep import paths.
|
|
28
|
+
*/
|
|
29
|
+
export declare class SheetOrm {
|
|
30
|
+
/** ActiveRecord base class — extend this to define entity models. */
|
|
31
|
+
static readonly Record: typeof Record;
|
|
32
|
+
/** Fluent query builder for filtering, sorting, and paginating records. */
|
|
33
|
+
static readonly Query: typeof Query;
|
|
34
|
+
/** Property decorators: `@Field`, `@Indexed`, `@Required`. */
|
|
35
|
+
static readonly Decorators: typeof Decorators;
|
|
36
|
+
/** Secondary-index manager with n-gram text search. */
|
|
37
|
+
static readonly IndexStore: typeof IndexStore;
|
|
38
|
+
/** Singleton registry that tracks all registered entity classes. */
|
|
39
|
+
static readonly Registry: typeof Registry;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=SheetOrm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SheetOrm.d.ts","sourceRoot":"","sources":["../../src/SheetOrm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC;;;;;GAKG;AACH,qBAAa,QAAQ;IACnB,qEAAqE;IACrE,MAAM,CAAC,QAAQ,CAAC,MAAM,gBAAU;IAChC,2EAA2E;IAC3E,MAAM,CAAC,QAAQ,CAAC,KAAK,eAAS;IAC9B,8DAA8D;IAC9D,MAAM,CAAC,QAAQ,CAAC,UAAU,oBAAc;IACxC,uDAAuD;IACvD,MAAM,CAAC,QAAQ,CAAC,UAAU,oBAAc;IACxC,oEAAoE;IACpE,MAAM,CAAC,QAAQ,CAAC,QAAQ,kBAAY;CACrC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module SheetOrm
|
|
3
|
+
*
|
|
4
|
+
* NPM package entry point for the SheetORM library.
|
|
5
|
+
*
|
|
6
|
+
* Re-exports the core public API surface as static members of a single
|
|
7
|
+
* namespace class. Consumer code imports from this module:
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { SheetOrm } from "sheetorm";
|
|
11
|
+
* const { Record, Query, Decorators, IndexStore, Registry } = SheetOrm;
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* This file is referenced by `tsconfig.npm.json` and the npm build
|
|
15
|
+
* script; it does **not** include GAS-specific helpers (e.g. demos,
|
|
16
|
+
* test runners) that live in `index.ts`.
|
|
17
|
+
*/
|
|
18
|
+
import { Decorators } from "./core/Decorators.js";
|
|
19
|
+
import { Record } from "./core/Record.js";
|
|
20
|
+
import { Registry } from "./core/Registry.js";
|
|
21
|
+
import { IndexStore } from "./index/IndexStore.js";
|
|
22
|
+
import { Query } from "./query/Query.js";
|
|
23
|
+
/**
|
|
24
|
+
* Top-level namespace class that bundles every public SheetORM artifact.
|
|
25
|
+
*
|
|
26
|
+
* Designed as a single default import so consumers can destructure
|
|
27
|
+
* only the parts they need without deep import paths.
|
|
28
|
+
*/
|
|
29
|
+
export class SheetOrm {
|
|
30
|
+
}
|
|
31
|
+
/** ActiveRecord base class — extend this to define entity models. */
|
|
32
|
+
SheetOrm.Record = Record;
|
|
33
|
+
/** Fluent query builder for filtering, sorting, and paginating records. */
|
|
34
|
+
SheetOrm.Query = Query;
|
|
35
|
+
/** Property decorators: `@Field`, `@Indexed`, `@Required`. */
|
|
36
|
+
SheetOrm.Decorators = Decorators;
|
|
37
|
+
/** Secondary-index manager with n-gram text search. */
|
|
38
|
+
SheetOrm.IndexStore = IndexStore;
|
|
39
|
+
/** Singleton registry that tracks all registered entity classes. */
|
|
40
|
+
SheetOrm.Registry = Registry;
|
|
41
|
+
//# sourceMappingURL=SheetOrm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SheetOrm.js","sourceRoot":"","sources":["../../src/SheetOrm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,OAAO,QAAQ;;AACnB,qEAAqE;AACrD,eAAM,GAAG,MAAM,CAAC;AAChC,2EAA2E;AAC3D,cAAK,GAAG,KAAK,CAAC;AAC9B,8DAA8D;AAC9C,mBAAU,GAAG,UAAU,CAAC;AACxC,uDAAuD;AACvC,mBAAU,GAAG,UAAU,CAAC;AACxC,oEAAoE;AACpD,iBAAQ,GAAG,QAAQ,CAAC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decorator-based metadata system for declaring Record model fields and indexes.
|
|
3
|
+
*
|
|
4
|
+
* Provides three property decorators:
|
|
5
|
+
* - `@Indexed()` — mark a field for secondary indexing (lookups via IndexStore).
|
|
6
|
+
* - `@Required()` — shorthand for `@Field({ required: true })`.
|
|
7
|
+
* - `@Field()` — override field metadata (type, required, defaultValue, etc.).
|
|
8
|
+
*
|
|
9
|
+
* And two discovery helpers:
|
|
10
|
+
* - `getFields(ctor)` — return all FieldDefinition[] for a class.
|
|
11
|
+
* - `getIndexes(ctor)` — return all IndexDefinition[] for a class.
|
|
12
|
+
*
|
|
13
|
+
* Metadata is stored in module-scoped Maps keyed by constructor:
|
|
14
|
+
* - `indexedMeta` — primary @Indexed entries.
|
|
15
|
+
* - `fieldMeta` — primary @Field / @Required / @Indexed field patches.
|
|
16
|
+
* - `fieldsCache` — derived FieldDefinition[] (invalidated on decoration).
|
|
17
|
+
* - `indexesCache` — derived IndexDefinition[] (invalidated on decoration).
|
|
18
|
+
*
|
|
19
|
+
* @module Decorators
|
|
20
|
+
*/
|
|
21
|
+
import type { FieldDefinition } from "./types/FieldDefinition.js";
|
|
22
|
+
import type { FieldType } from "./types/FieldType.js";
|
|
23
|
+
import type { IndexDefinition } from "./types/IndexDefinition.js";
|
|
24
|
+
/** Constructor shape accepted by the decorators (any class that produces an object). */
|
|
25
|
+
interface DecoratedModelCtor {
|
|
26
|
+
new (): object;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Mark a field as indexed for faster lookups via IndexStore.
|
|
30
|
+
*
|
|
31
|
+
* When a Record subclass has fields decorated with `@Indexed()`, SheetORM
|
|
32
|
+
* creates a combined index sheet (e.g. `idx_Cars`) and maintains index entries
|
|
33
|
+
* during save/delete operations. The `search` filter operator leverages the
|
|
34
|
+
* index for n-gram full-text search.
|
|
35
|
+
*
|
|
36
|
+
* @param options.unique - Enforce unique values across all entities (default: false).
|
|
37
|
+
* @param options.type - Storage type hint for the index ("string" | "number" | "date").
|
|
38
|
+
* @returns A standard TypeScript property decorator.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* class Car extends Record {
|
|
42
|
+
* @Indexed({ unique: true })
|
|
43
|
+
* vin!: string;
|
|
44
|
+
*
|
|
45
|
+
* @Indexed()
|
|
46
|
+
* make!: string;
|
|
47
|
+
* }
|
|
48
|
+
*/
|
|
49
|
+
declare function Indexed(options?: {
|
|
50
|
+
unique?: boolean;
|
|
51
|
+
type?: "string" | "number" | "date";
|
|
52
|
+
}): PropertyDecorator;
|
|
53
|
+
/**
|
|
54
|
+
* Mark a field as required — shorthand for `@Field({ required: true })`.
|
|
55
|
+
*
|
|
56
|
+
* Required fields are validated during save(); an error is thrown if the
|
|
57
|
+
* value is null, undefined, or an empty string.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* class User extends Record {
|
|
61
|
+
* @Required()
|
|
62
|
+
* email!: string;
|
|
63
|
+
* }
|
|
64
|
+
*/
|
|
65
|
+
declare function Required(): PropertyDecorator;
|
|
66
|
+
/**
|
|
67
|
+
* Override field metadata: storage type, required flag, default value, or
|
|
68
|
+
* reference table name.
|
|
69
|
+
*
|
|
70
|
+
* Fields that do not carry any decorator are still auto-discovered from a
|
|
71
|
+
* temporary instance's own properties. Use `@Field()` when you need to
|
|
72
|
+
* explicitly set the storage type or a default value.
|
|
73
|
+
*
|
|
74
|
+
* @param options.type - Storage type ("string" | "number" | "boolean" | "date" | "json" | "reference").
|
|
75
|
+
* @param options.required - Validate non-empty on save (default: false).
|
|
76
|
+
* @param options.defaultValue - Fallback value when the field is undefined.
|
|
77
|
+
* @param options.referenceTable - Related table name (for "reference" type fields).
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* class Product extends Record {
|
|
81
|
+
* @Field({ type: "number", defaultValue: 0 })
|
|
82
|
+
* price!: number;
|
|
83
|
+
*
|
|
84
|
+
* @Field({ type: "json" })
|
|
85
|
+
* metadata!: Record<string, unknown>;
|
|
86
|
+
* }
|
|
87
|
+
*/
|
|
88
|
+
declare function Field(options?: {
|
|
89
|
+
type?: FieldType;
|
|
90
|
+
required?: boolean;
|
|
91
|
+
defaultValue?: unknown;
|
|
92
|
+
referenceTable?: string;
|
|
93
|
+
}): PropertyDecorator;
|
|
94
|
+
/**
|
|
95
|
+
* Discover all user-defined fields for a Record subclass.
|
|
96
|
+
*
|
|
97
|
+
* Merges two sources:
|
|
98
|
+
* 1. **Own properties** from a temporary instance — captures ESNext [[Define]]
|
|
99
|
+
* class fields that become own properties without a decorator.
|
|
100
|
+
* 2. **Decorator metadata** from `@Indexed` / `@Field` / `@Required` — captures
|
|
101
|
+
* fields declared with [[Set]] semantics (TypeScript `useDefineForClassFields: false`).
|
|
102
|
+
*
|
|
103
|
+
* Results are cached per constructor and invalidated whenever a decorator fires.
|
|
104
|
+
*
|
|
105
|
+
* @param ctor - Model constructor to inspect.
|
|
106
|
+
* @returns Array of FieldDefinition objects (one per user-defined property).
|
|
107
|
+
*/
|
|
108
|
+
declare function getFields(ctor: DecoratedModelCtor): FieldDefinition[];
|
|
109
|
+
/**
|
|
110
|
+
* Get all index definitions for a Record subclass (from `@Indexed` decorators).
|
|
111
|
+
*
|
|
112
|
+
* @param ctor - Model constructor to inspect.
|
|
113
|
+
* @returns Array of IndexDefinition objects.
|
|
114
|
+
*/
|
|
115
|
+
declare function getIndexes(ctor: DecoratedModelCtor): IndexDefinition[];
|
|
116
|
+
/**
|
|
117
|
+
* Reset derived decorator caches (fieldsCache and indexesCache).
|
|
118
|
+
*
|
|
119
|
+
* Called by `Registry.reset()` during testing to ensure a clean state.
|
|
120
|
+
* Primary metadata (`fieldMeta` and `indexedMeta`) is set at class-definition
|
|
121
|
+
* time by decorators and must NOT be cleared here — only derived caches.
|
|
122
|
+
*/
|
|
123
|
+
declare function resetDecoratorCaches(): void;
|
|
124
|
+
/**
|
|
125
|
+
* Public decorator utility class.
|
|
126
|
+
*
|
|
127
|
+
* Wraps the three property decorators and two discovery functions
|
|
128
|
+
* as static methods, following the SheetORM one-export-per-file pattern.
|
|
129
|
+
*/
|
|
130
|
+
export declare class Decorators {
|
|
131
|
+
/** Property decorator: mark a field for secondary indexing. */
|
|
132
|
+
static Indexed: typeof Indexed;
|
|
133
|
+
/** Property decorator: mark a field as required (shorthand). */
|
|
134
|
+
static Required: typeof Required;
|
|
135
|
+
/** Property decorator: set explicit field metadata. */
|
|
136
|
+
static Field: typeof Field;
|
|
137
|
+
/** Discover all field definitions for a model class. */
|
|
138
|
+
static getFields: typeof getFields;
|
|
139
|
+
/** Discover all index definitions for a model class. */
|
|
140
|
+
static getIndexes: typeof getIndexes;
|
|
141
|
+
/** Reset derived caches (for testing). */
|
|
142
|
+
static resetDecoratorCaches: typeof resetDecoratorCaches;
|
|
143
|
+
}
|
|
144
|
+
export {};
|
|
145
|
+
//# sourceMappingURL=Decorators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Decorators.d.ts","sourceRoot":"","sources":["../../../src/core/Decorators.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAElE,wFAAwF;AACxF,UAAU,kBAAkB;IAC1B,QAAQ,MAAM,CAAC;CAChB;AAmDD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,iBAAS,OAAO,CAAC,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAA;CAAE,GAAG,iBAAiB,CAYvG;AAED;;;;;;;;;;;GAWG;AACH,iBAAS,QAAQ,IAAI,iBAAiB,CAKrC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,iBAAS,KAAK,CAAC,OAAO,CAAC,EAAE;IACvB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,iBAAiB,CAKpB;AAID;;;;;;;;;;;;;GAaG;AACH,iBAAS,SAAS,CAAC,IAAI,EAAE,kBAAkB,GAAG,eAAe,EAAE,CAgC9D;AAED;;;;;GAKG;AACH,iBAAS,UAAU,CAAC,IAAI,EAAE,kBAAkB,GAAG,eAAe,EAAE,CAK/D;AAED;;;;;;GAMG;AACH,iBAAS,oBAAoB,IAAI,IAAI,CAGpC;AAED;;;;;GAKG;AACH,qBAAa,UAAU;IACrB,+DAA+D;IAC/D,MAAM,CAAC,OAAO,iBAAW;IAEzB,gEAAgE;IAChE,MAAM,CAAC,QAAQ,kBAAY;IAE3B,uDAAuD;IACvD,MAAM,CAAC,KAAK,eAAS;IAErB,wDAAwD;IACxD,MAAM,CAAC,SAAS,mBAAa;IAE7B,wDAAwD;IACxD,MAAM,CAAC,UAAU,oBAAc;IAE/B,0CAA0C;IAC1C,MAAM,CAAC,oBAAoB,8BAAwB;CACpD"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decorator-based metadata system for declaring Record model fields and indexes.
|
|
3
|
+
*
|
|
4
|
+
* Provides three property decorators:
|
|
5
|
+
* - `@Indexed()` — mark a field for secondary indexing (lookups via IndexStore).
|
|
6
|
+
* - `@Required()` — shorthand for `@Field({ required: true })`.
|
|
7
|
+
* - `@Field()` — override field metadata (type, required, defaultValue, etc.).
|
|
8
|
+
*
|
|
9
|
+
* And two discovery helpers:
|
|
10
|
+
* - `getFields(ctor)` — return all FieldDefinition[] for a class.
|
|
11
|
+
* - `getIndexes(ctor)` — return all IndexDefinition[] for a class.
|
|
12
|
+
*
|
|
13
|
+
* Metadata is stored in module-scoped Maps keyed by constructor:
|
|
14
|
+
* - `indexedMeta` — primary @Indexed entries.
|
|
15
|
+
* - `fieldMeta` — primary @Field / @Required / @Indexed field patches.
|
|
16
|
+
* - `fieldsCache` — derived FieldDefinition[] (invalidated on decoration).
|
|
17
|
+
* - `indexesCache` — derived IndexDefinition[] (invalidated on decoration).
|
|
18
|
+
*
|
|
19
|
+
* @module Decorators
|
|
20
|
+
*/
|
|
21
|
+
// ─── Metadata storage ────────────────────────────────
|
|
22
|
+
/** Primary storage for @Indexed() entries — one array of IndexDefinition per class. */
|
|
23
|
+
const indexedMeta = new Map();
|
|
24
|
+
/** Primary storage for per-field decorator patches — nested map: ctor → fieldName → partial def. */
|
|
25
|
+
const fieldMeta = new Map();
|
|
26
|
+
/** Derived cache: merged FieldDefinition[] per class (cleared when a decorator fires). */
|
|
27
|
+
const fieldsCache = new Map();
|
|
28
|
+
/** Derived cache: IndexDefinition[] per class (cleared when @Indexed fires). */
|
|
29
|
+
const indexesCache = new Map();
|
|
30
|
+
/**
|
|
31
|
+
* Merge a partial FieldDefinition patch into the metadata store for a given class/field.
|
|
32
|
+
*
|
|
33
|
+
* If the class or field has no metadata yet, creates fresh entries.
|
|
34
|
+
* Invalidates the fieldsCache so the next `getFields()` call rebuilds.
|
|
35
|
+
*
|
|
36
|
+
* @param ctor - The model constructor (class).
|
|
37
|
+
* @param propertyKey - Decorated property name.
|
|
38
|
+
* @param patch - Partial field definition to merge.
|
|
39
|
+
*/
|
|
40
|
+
function upsertFieldMetadata(ctor, propertyKey, patch) {
|
|
41
|
+
if (!fieldMeta.has(ctor))
|
|
42
|
+
fieldMeta.set(ctor, new Map());
|
|
43
|
+
const name = String(propertyKey);
|
|
44
|
+
const existing = fieldMeta.get(ctor).get(name) || {};
|
|
45
|
+
// Merge existing metadata with new patch; `name` is always set
|
|
46
|
+
fieldMeta.get(ctor).set(name, {
|
|
47
|
+
name,
|
|
48
|
+
...existing,
|
|
49
|
+
...patch,
|
|
50
|
+
});
|
|
51
|
+
// Invalidate derived cache
|
|
52
|
+
fieldsCache.delete(ctor);
|
|
53
|
+
}
|
|
54
|
+
// ─── Property Decorators ─────────────────────────────
|
|
55
|
+
/**
|
|
56
|
+
* Mark a field as indexed for faster lookups via IndexStore.
|
|
57
|
+
*
|
|
58
|
+
* When a Record subclass has fields decorated with `@Indexed()`, SheetORM
|
|
59
|
+
* creates a combined index sheet (e.g. `idx_Cars`) and maintains index entries
|
|
60
|
+
* during save/delete operations. The `search` filter operator leverages the
|
|
61
|
+
* index for n-gram full-text search.
|
|
62
|
+
*
|
|
63
|
+
* @param options.unique - Enforce unique values across all entities (default: false).
|
|
64
|
+
* @param options.type - Storage type hint for the index ("string" | "number" | "date").
|
|
65
|
+
* @returns A standard TypeScript property decorator.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* class Car extends Record {
|
|
69
|
+
* @Indexed({ unique: true })
|
|
70
|
+
* vin!: string;
|
|
71
|
+
*
|
|
72
|
+
* @Indexed()
|
|
73
|
+
* make!: string;
|
|
74
|
+
* }
|
|
75
|
+
*/
|
|
76
|
+
function Indexed(options) {
|
|
77
|
+
return (target, propertyKey) => {
|
|
78
|
+
const ctor = target.constructor;
|
|
79
|
+
// Register the index definition
|
|
80
|
+
if (!indexedMeta.has(ctor))
|
|
81
|
+
indexedMeta.set(ctor, []);
|
|
82
|
+
indexedMeta.get(ctor).push({ field: String(propertyKey), ...options });
|
|
83
|
+
// Also register in fieldMeta so the field appears in getFields() even
|
|
84
|
+
// when using ES2022 [[Set]] class field semantics (no own property on prototype)
|
|
85
|
+
upsertFieldMetadata(ctor, propertyKey, {});
|
|
86
|
+
// Invalidate index cache
|
|
87
|
+
indexesCache.delete(ctor);
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Mark a field as required — shorthand for `@Field({ required: true })`.
|
|
92
|
+
*
|
|
93
|
+
* Required fields are validated during save(); an error is thrown if the
|
|
94
|
+
* value is null, undefined, or an empty string.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* class User extends Record {
|
|
98
|
+
* @Required()
|
|
99
|
+
* email!: string;
|
|
100
|
+
* }
|
|
101
|
+
*/
|
|
102
|
+
function Required() {
|
|
103
|
+
return (target, propertyKey) => {
|
|
104
|
+
const ctor = target.constructor;
|
|
105
|
+
upsertFieldMetadata(ctor, propertyKey, { required: true });
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Override field metadata: storage type, required flag, default value, or
|
|
110
|
+
* reference table name.
|
|
111
|
+
*
|
|
112
|
+
* Fields that do not carry any decorator are still auto-discovered from a
|
|
113
|
+
* temporary instance's own properties. Use `@Field()` when you need to
|
|
114
|
+
* explicitly set the storage type or a default value.
|
|
115
|
+
*
|
|
116
|
+
* @param options.type - Storage type ("string" | "number" | "boolean" | "date" | "json" | "reference").
|
|
117
|
+
* @param options.required - Validate non-empty on save (default: false).
|
|
118
|
+
* @param options.defaultValue - Fallback value when the field is undefined.
|
|
119
|
+
* @param options.referenceTable - Related table name (for "reference" type fields).
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* class Product extends Record {
|
|
123
|
+
* @Field({ type: "number", defaultValue: 0 })
|
|
124
|
+
* price!: number;
|
|
125
|
+
*
|
|
126
|
+
* @Field({ type: "json" })
|
|
127
|
+
* metadata!: Record<string, unknown>;
|
|
128
|
+
* }
|
|
129
|
+
*/
|
|
130
|
+
function Field(options) {
|
|
131
|
+
return (target, propertyKey) => {
|
|
132
|
+
const ctor = target.constructor;
|
|
133
|
+
upsertFieldMetadata(ctor, propertyKey, options ?? {});
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
// ─── Field & Index Discovery ─────────────────────────
|
|
137
|
+
/**
|
|
138
|
+
* Discover all user-defined fields for a Record subclass.
|
|
139
|
+
*
|
|
140
|
+
* Merges two sources:
|
|
141
|
+
* 1. **Own properties** from a temporary instance — captures ESNext [[Define]]
|
|
142
|
+
* class fields that become own properties without a decorator.
|
|
143
|
+
* 2. **Decorator metadata** from `@Indexed` / `@Field` / `@Required` — captures
|
|
144
|
+
* fields declared with [[Set]] semantics (TypeScript `useDefineForClassFields: false`).
|
|
145
|
+
*
|
|
146
|
+
* Results are cached per constructor and invalidated whenever a decorator fires.
|
|
147
|
+
*
|
|
148
|
+
* @param ctor - Model constructor to inspect.
|
|
149
|
+
* @returns Array of FieldDefinition objects (one per user-defined property).
|
|
150
|
+
*/
|
|
151
|
+
function getFields(ctor) {
|
|
152
|
+
// Return cached result if available
|
|
153
|
+
if (fieldsCache.has(ctor))
|
|
154
|
+
return fieldsCache.get(ctor);
|
|
155
|
+
// 1. Discover own properties from a temp instance (undecorated fields defined via [[Define]])
|
|
156
|
+
const temp = new ctor();
|
|
157
|
+
const discoveredNames = new Set(Object.getOwnPropertyNames(temp));
|
|
158
|
+
// 2. Add names registered through @Indexed decorator
|
|
159
|
+
const idxMeta = indexedMeta.get(ctor) || [];
|
|
160
|
+
for (const idx of idxMeta)
|
|
161
|
+
discoveredNames.add(idx.field);
|
|
162
|
+
// 3. Add names registered through @Field / @Required decorators
|
|
163
|
+
const fMeta = fieldMeta.get(ctor) || new Map();
|
|
164
|
+
for (const name of fMeta.keys())
|
|
165
|
+
discoveredNames.add(name);
|
|
166
|
+
// 4. Build the final FieldDefinition array, merging decorator overrides
|
|
167
|
+
const fields = [];
|
|
168
|
+
for (const name of discoveredNames) {
|
|
169
|
+
const override = fMeta.get(name);
|
|
170
|
+
fields.push({
|
|
171
|
+
name,
|
|
172
|
+
type: override?.type,
|
|
173
|
+
required: override?.required,
|
|
174
|
+
defaultValue: override?.defaultValue,
|
|
175
|
+
referenceTable: override?.referenceTable,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
// Cache for subsequent calls
|
|
179
|
+
fieldsCache.set(ctor, fields);
|
|
180
|
+
return fields;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get all index definitions for a Record subclass (from `@Indexed` decorators).
|
|
184
|
+
*
|
|
185
|
+
* @param ctor - Model constructor to inspect.
|
|
186
|
+
* @returns Array of IndexDefinition objects.
|
|
187
|
+
*/
|
|
188
|
+
function getIndexes(ctor) {
|
|
189
|
+
if (indexesCache.has(ctor))
|
|
190
|
+
return indexesCache.get(ctor);
|
|
191
|
+
const indexes = indexedMeta.get(ctor) || [];
|
|
192
|
+
indexesCache.set(ctor, indexes);
|
|
193
|
+
return indexes;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Reset derived decorator caches (fieldsCache and indexesCache).
|
|
197
|
+
*
|
|
198
|
+
* Called by `Registry.reset()` during testing to ensure a clean state.
|
|
199
|
+
* Primary metadata (`fieldMeta` and `indexedMeta`) is set at class-definition
|
|
200
|
+
* time by decorators and must NOT be cleared here — only derived caches.
|
|
201
|
+
*/
|
|
202
|
+
function resetDecoratorCaches() {
|
|
203
|
+
fieldsCache.clear();
|
|
204
|
+
indexesCache.clear();
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Public decorator utility class.
|
|
208
|
+
*
|
|
209
|
+
* Wraps the three property decorators and two discovery functions
|
|
210
|
+
* as static methods, following the SheetORM one-export-per-file pattern.
|
|
211
|
+
*/
|
|
212
|
+
export class Decorators {
|
|
213
|
+
}
|
|
214
|
+
/** Property decorator: mark a field for secondary indexing. */
|
|
215
|
+
Decorators.Indexed = Indexed;
|
|
216
|
+
/** Property decorator: mark a field as required (shorthand). */
|
|
217
|
+
Decorators.Required = Required;
|
|
218
|
+
/** Property decorator: set explicit field metadata. */
|
|
219
|
+
Decorators.Field = Field;
|
|
220
|
+
/** Discover all field definitions for a model class. */
|
|
221
|
+
Decorators.getFields = getFields;
|
|
222
|
+
/** Discover all index definitions for a model class. */
|
|
223
|
+
Decorators.getIndexes = getIndexes;
|
|
224
|
+
/** Reset derived caches (for testing). */
|
|
225
|
+
Decorators.resetDecoratorCaches = resetDecoratorCaches;
|
|
226
|
+
//# sourceMappingURL=Decorators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Decorators.js","sourceRoot":"","sources":["../../../src/core/Decorators.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ActiveRecord base class for ORM-managed models.
|
|
3
|
+
*
|
|
4
|
+
* Subclass `Record` to define entities stored in Google Sheets. Fields
|
|
5
|
+
* are auto-discovered from ESNext class field declarations at registration
|
|
6
|
+
* time via the decorator metadata system ({@link Decorators}).
|
|
7
|
+
*
|
|
8
|
+
* Follows the **ActiveRecord** pattern — each instance knows how to
|
|
9
|
+
* `save()` and `delete()` itself, while static methods like `find()`,
|
|
10
|
+
* `where()`, and `query()` provide collection-level operations.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* class Car extends Record {
|
|
15
|
+
* brand = "";
|
|
16
|
+
* year = 0;
|
|
17
|
+
* }
|
|
18
|
+
* const car = Car.create({ brand: "Toyota", year: 2024 }).save();
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @module Record
|
|
22
|
+
*/
|
|
23
|
+
import type { Entity } from "./types/Entity.js";
|
|
24
|
+
import type { FilterOperator } from "./types/FilterOperator.js";
|
|
25
|
+
import type { QueryOptions } from "./types/QueryOptions.js";
|
|
26
|
+
import type { PaginatedResult } from "./types/PaginatedResult.js";
|
|
27
|
+
import type { GroupResult } from "./types/GroupResult.js";
|
|
28
|
+
import { Query } from "../query/Query.js";
|
|
29
|
+
import type { RecordConstructor } from "./RecordConstructor.js";
|
|
30
|
+
/**
|
|
31
|
+
* Base class for all SheetORM models.
|
|
32
|
+
*
|
|
33
|
+
* Provides both instance-level persistence (`save`, `delete`) and
|
|
34
|
+
* static query helpers (`find`, `where`, `query`, `select`, `groupBy`,
|
|
35
|
+
* `saveAll`). System columns (`__id`, `__createdAt`, `__updatedAt`)
|
|
36
|
+
* are declared here so every subclass inherits them.
|
|
37
|
+
*/
|
|
38
|
+
export declare class Record implements Entity {
|
|
39
|
+
/** UUID primary key, assigned automatically on first save. */
|
|
40
|
+
__id: string;
|
|
41
|
+
/** ISO-8601 creation timestamp, set by SheetRepository on insert. */
|
|
42
|
+
__createdAt: string | undefined;
|
|
43
|
+
/** ISO-8601 last-update timestamp, set by SheetRepository on every save. */
|
|
44
|
+
__updatedAt: string | undefined;
|
|
45
|
+
/** Index signature allowing arbitrary field access by name. */
|
|
46
|
+
[key: string]: unknown;
|
|
47
|
+
/**
|
|
48
|
+
* Convention-based table name derived from the class name.
|
|
49
|
+
* e.g. class `Car` → `"tbl_Cars"`.
|
|
50
|
+
*/
|
|
51
|
+
static get tableName(): string;
|
|
52
|
+
/**
|
|
53
|
+
* Convention-based combined index table name.
|
|
54
|
+
* e.g. class `Car` → `"idx_Cars"`.
|
|
55
|
+
*/
|
|
56
|
+
static get indexTableName(): string;
|
|
57
|
+
/**
|
|
58
|
+
* Whether the auto-created sheet should be protected.
|
|
59
|
+
* Override in a subclass to return `true` and enable sheet protection.
|
|
60
|
+
*/
|
|
61
|
+
static isProtected(): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Email addresses of editors allowed to edit the protected sheet.
|
|
64
|
+
* Only used when `isProtected()` returns `true`.
|
|
65
|
+
* Override in a subclass to specify allowed editors.
|
|
66
|
+
*/
|
|
67
|
+
static protectedFor(): string[];
|
|
68
|
+
/**
|
|
69
|
+
* Whether the auto-created sheet should be hidden from the tab bar.
|
|
70
|
+
* Override in a subclass to return `true` and hide the sheet.
|
|
71
|
+
* Hidden sheets are still accessible from the "All sheets" menu.
|
|
72
|
+
*/
|
|
73
|
+
static isHidden(): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Create an in-memory instance pre-populated with the given data.
|
|
76
|
+
* The instance is **not** persisted until `save()` is called.
|
|
77
|
+
*
|
|
78
|
+
* @param data - Plain object whose keys map to field names.
|
|
79
|
+
* @returns A new, unsaved Record subclass instance.
|
|
80
|
+
*/
|
|
81
|
+
static create<T extends Record>(this: RecordConstructor<T>, data: {
|
|
82
|
+
[key: string]: unknown;
|
|
83
|
+
}): T;
|
|
84
|
+
/**
|
|
85
|
+
* Persist this instance to the underlying Google Sheet.
|
|
86
|
+
*
|
|
87
|
+
* On first save (no `__id`) a new row is inserted; on subsequent
|
|
88
|
+
* saves the existing row is updated in-place. Only fields declared
|
|
89
|
+
* via decorators (or auto-discovered) are written; dynamic index-
|
|
90
|
+
* signature properties are ignored.
|
|
91
|
+
*
|
|
92
|
+
* @returns `this` for fluent chaining.
|
|
93
|
+
*/
|
|
94
|
+
save(): this;
|
|
95
|
+
/**
|
|
96
|
+
* Delete this instance's row from the sheet.
|
|
97
|
+
* @returns `true` if the row was found and deleted, `false` if `__id` is missing.
|
|
98
|
+
*/
|
|
99
|
+
delete(): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Fluent setter — updates a single field and returns `this`.
|
|
102
|
+
* @param field - The field name to set.
|
|
103
|
+
* @param value - The new value.
|
|
104
|
+
*/
|
|
105
|
+
set(field: string, value: unknown): this;
|
|
106
|
+
/**
|
|
107
|
+
* Read a single field value by name.
|
|
108
|
+
* @param field - The field name to read.
|
|
109
|
+
*/
|
|
110
|
+
get(field: string): unknown;
|
|
111
|
+
/**
|
|
112
|
+
* Serialise this Record to a plain object.
|
|
113
|
+
*
|
|
114
|
+
* Only includes declared class fields (from decorator metadata) plus
|
|
115
|
+
* system columns. Dynamic properties set via the index signature are
|
|
116
|
+
* intentionally excluded to keep JSON output predictable.
|
|
117
|
+
*/
|
|
118
|
+
toJSON(): {
|
|
119
|
+
[key: string]: unknown;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Start a fluent query chain with an initial filter.
|
|
123
|
+
* Equivalent to `Record.query().where(field, operator, value)`.
|
|
124
|
+
*/
|
|
125
|
+
static where<T extends Record>(this: RecordConstructor<T>, field: string, operator: FilterOperator, value: unknown): Query<T>;
|
|
126
|
+
/**
|
|
127
|
+
* Look up a single record by its UUID primary key.
|
|
128
|
+
* Uses the repository's fast-path cache when available.
|
|
129
|
+
*
|
|
130
|
+
* @returns The hydrated instance, or `null` if not found.
|
|
131
|
+
*/
|
|
132
|
+
static findById<T extends Record>(this: RecordConstructor<T>, id: string): T | null;
|
|
133
|
+
/**
|
|
134
|
+
* Return all records matching the optional query options.
|
|
135
|
+
* Without options, returns every record in the table.
|
|
136
|
+
*/
|
|
137
|
+
static find<T extends Record>(this: RecordConstructor<T>, options?: QueryOptions): T[];
|
|
138
|
+
/**
|
|
139
|
+
* Return the first record matching the query options, or `null`.
|
|
140
|
+
*/
|
|
141
|
+
static findOne<T extends Record>(this: RecordConstructor<T>, options?: QueryOptions): T | null;
|
|
142
|
+
/** Count records matching the optional query options. */
|
|
143
|
+
static count(options?: QueryOptions): number;
|
|
144
|
+
/**
|
|
145
|
+
* Delete all records matching the query options.
|
|
146
|
+
* @returns The number of records deleted.
|
|
147
|
+
*/
|
|
148
|
+
static deleteAll(options?: QueryOptions): number;
|
|
149
|
+
/**
|
|
150
|
+
* Start an empty fluent query chain.
|
|
151
|
+
* Call `.where()`, `.orderBy()`, `.limit()`, etc. to build the query.
|
|
152
|
+
*/
|
|
153
|
+
static query<T extends Record>(this: RecordConstructor<T>): Query<T>;
|
|
154
|
+
/**
|
|
155
|
+
* Return a paginated subset of records.
|
|
156
|
+
*
|
|
157
|
+
* @param offset - Number of records to skip (0-based).
|
|
158
|
+
* @param limit - Maximum number of records to return.
|
|
159
|
+
* @param options - Optional filters/sorting.
|
|
160
|
+
* @returns A {@link PaginatedResult} with `items`, `total`, `offset`, `limit`.
|
|
161
|
+
*/
|
|
162
|
+
static select<T extends Record>(this: RecordConstructor<T>, offset: number, limit: number, options?: QueryOptions): PaginatedResult<T>;
|
|
163
|
+
/**
|
|
164
|
+
* Group records by a field value.
|
|
165
|
+
*
|
|
166
|
+
* @param field - The field to group by.
|
|
167
|
+
* @param options - Optional pre-grouping filters.
|
|
168
|
+
* @returns An array of {@link GroupResult}, each with `key` and `items`.
|
|
169
|
+
*/
|
|
170
|
+
static groupBy<T extends Record>(this: RecordConstructor<T>, field: string, options?: QueryOptions): GroupResult<T>[];
|
|
171
|
+
/**
|
|
172
|
+
* Batch-save multiple records in a single operation.
|
|
173
|
+
*
|
|
174
|
+
* Delegates to `SheetRepository.saveAll()` which uses entity-batch and
|
|
175
|
+
* index-batch optimisations to minimise GAS API calls.
|
|
176
|
+
*
|
|
177
|
+
* @param items - Array of plain data objects.
|
|
178
|
+
* @returns Array of hydrated, persisted Record instances.
|
|
179
|
+
*/
|
|
180
|
+
static saveAll<T extends Record>(this: RecordConstructor<T>, items: Array<{
|
|
181
|
+
[key: string]: unknown;
|
|
182
|
+
}>): T[];
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=Record.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Record.d.ts","sourceRoot":"","sources":["../../../src/core/Record.ts"],"names":[],"mappings":"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"}
|