@jwerre/vellum 1.1.0 → 1.1.1

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/README.md CHANGED
@@ -178,12 +178,10 @@ Vellum works seamlessly with Svelte 5 components.
178
178
 
179
179
  There is a working example of Vellum in the `routes` directory. To run it, clone the repository, install dependencies, and run the development server:
180
180
 
181
- ```
182
- git clone https://github.com/jwerre/vellum.git
183
- cd vellum
184
- npm install
185
- npm run dev
186
- ```
181
+ git clone https://github.com/jwerre/vellum.git
182
+ cd vellum
183
+ npm install
184
+ npm run dev
187
185
 
188
186
  ## API Documentation
189
187
 
@@ -198,58 +196,62 @@ npm run dev
198
196
  - [Model](#model)
199
197
  - [Parameters](#parameters-1)
200
198
  - [Examples](#examples-1)
201
- - [validationError](#validationerror)
202
199
  - [idAttribute](#idattribute)
200
+ - [Examples](#examples-2)
201
+ - [validationError](#validationerror)
202
+ - [defaults](#defaults)
203
+ - [Examples](#examples-3)
203
204
  - [get](#get)
204
205
  - [Parameters](#parameters-2)
205
- - [Examples](#examples-2)
206
+ - [Examples](#examples-4)
206
207
  - [has](#has)
207
208
  - [Parameters](#parameters-3)
208
- - [Examples](#examples-3)
209
+ - [Examples](#examples-5)
209
210
  - [unset](#unset)
210
211
  - [Parameters](#parameters-4)
211
- - [Examples](#examples-4)
212
+ - [Examples](#examples-6)
212
213
  - [clear](#clear)
213
- - [Examples](#examples-5)
214
+ - [Examples](#examples-7)
214
215
  - [escape](#escape)
215
216
  - [Parameters](#parameters-5)
216
- - [Examples](#examples-6)
217
+ - [Examples](#examples-8)
217
218
  - [isNew](#isnew)
218
219
  - [isValid](#isvalid)
219
220
  - [Parameters](#parameters-6)
220
- - [Examples](#examples-7)
221
+ - [Examples](#examples-9)
221
222
  - [validate](#validate)
222
223
  - [Parameters](#parameters-7)
223
- - [Examples](#examples-8)
224
+ - [Examples](#examples-10)
224
225
  - [sync](#sync)
225
226
  - [Parameters](#parameters-8)
226
- - [Examples](#examples-9)
227
+ - [Examples](#examples-11)
227
228
  - [fetch](#fetch)
228
- - [Examples](#examples-10)
229
+ - [Examples](#examples-12)
229
230
  - [save](#save)
230
231
  - [Parameters](#parameters-9)
231
- - [Examples](#examples-11)
232
+ - [Examples](#examples-13)
232
233
  - [destroy](#destroy)
233
- - [Examples](#examples-12)
234
+ - [Examples](#examples-14)
234
235
  - [toJSON](#tojson)
235
- - [Examples](#examples-13)
236
+ - [Examples](#examples-15)
237
+ - [validationError](#validationerror-1)
236
238
  - [Collection](#collection)
237
239
  - [Parameters](#parameters-10)
238
- - [Examples](#examples-14)
240
+ - [Examples](#examples-16)
239
241
  - [items](#items)
240
242
  - [length](#length)
241
243
  - [add](#add)
242
244
  - [Parameters](#parameters-11)
243
- - [Examples](#examples-15)
245
+ - [Examples](#examples-17)
244
246
  - [reset](#reset)
245
247
  - [Parameters](#parameters-12)
246
- - [Examples](#examples-16)
248
+ - [Examples](#examples-18)
247
249
  - [find](#find)
248
250
  - [Parameters](#parameters-13)
249
- - [Examples](#examples-17)
251
+ - [Examples](#examples-19)
250
252
  - [fetch](#fetch-1)
251
253
  - [Parameters](#parameters-14)
252
- - [Examples](#examples-18)
254
+ - [Examples](#examples-20)
253
255
 
254
256
  ### vellumConfig
255
257
 
@@ -269,6 +271,7 @@ with existing headers rather than replaced entirely.
269
271
  - `config` **Partial\<VellumConfig>** Partial configuration object with properties to update
270
272
  - `config.origin` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** New origin URL to set
271
273
  - `config.headers` **Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>?** Headers to merge with existing headers
274
+ - `config.idAttribute` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The default unique identifier attribute for models (optional, default `"id"`)
272
275
 
273
276
  #### Examples
274
277
 
@@ -312,7 +315,6 @@ Key features:
312
315
  #### Parameters
313
316
 
314
317
  - `data` (optional, default `{}`)
315
- - `options` (optional, default `{}`)
316
318
 
317
319
  #### Examples
318
320
 
@@ -326,9 +328,12 @@ interface UserAttributes {
326
328
  }
327
329
 
328
330
  class User extends Model<UserAttributes> {
329
- endpoint(): string {
331
+ endpoint() {
330
332
  return '/users';
331
333
  }
334
+ defaults() {
335
+ return { name: '', createdAt: new Date() };
336
+ }
332
337
  }
333
338
 
334
339
  // Create and use a model instance
@@ -336,40 +341,73 @@ const user = new User({ name: 'John Doe', email: 'john@example.com' });
336
341
  await user.save(); // Creates new user on server
337
342
  user.set('name', 'Jane Doe');
338
343
  await user.save(); // Updates existing user
344
+ await user.destroy(); // Deletes user
339
345
  ```
340
346
 
341
- ```javascript
342
- // Using custom ID attribute (e.g., MongoDB _id)
343
- interface MongoUserAttributes {
344
- _id?: string;
345
- username: string;
346
- profile: {
347
- firstName: string;
348
- lastName: string;
349
- };
350
- }
347
+ #### idAttribute
351
348
 
352
- class MongoUser extends Model<MongoUserAttributes> {
353
- constructor(data?: Partial<MongoUserAttributes>) {
354
- super(data, { idAttribute: '_id' });
355
- }
349
+ The name of the attribute that serves as the unique identifier for this model instance.
356
350
 
357
- endpoint(): string {
358
- return '/api/users';
359
- }
351
+ This private field stores the attribute name that will be used to identify the model's
352
+ primary key when performing operations like determining if the model is new, constructing
353
+ URLs for API requests, and managing model identity. The default value is 'id', but it
354
+ can be customized through the ModelOptions parameter in the constructor.
355
+
356
+ Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)
357
+
358
+ ##### Examples
359
+
360
+ ```javascript
361
+ // Default behavior uses 'id' as the identifier
362
+ const user = new User({ id: 1, name: 'John' });
363
+
364
+ // Custom ID attribute can be specified in constructor options
365
+ class User extends Model<UserSchema> {
366
+ idAttribute = '_id
367
+ endpoint(): string {
368
+ return '/users';
369
+ }
360
370
  }
371
+ const user = new User({ _id: '507f1f77bcf86cd799439011', name: 'John' });
361
372
  ```
362
373
 
363
374
  #### validationError
364
375
 
365
- Validation error property that gets set when validation fails.
366
- This property contains the error returned by the validate method.
376
+ Gets the latest validation error.
367
377
 
368
- #### idAttribute
378
+ #### defaults
369
379
 
370
- Gets the current ID attribute name used by this model instance.
380
+ Provides default attribute values for new model instances.
371
381
 
372
- Returns **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the attribute used as the ID field
382
+ This method is called during model construction to establish initial attribute
383
+ values before applying any user-provided data. Subclasses can override this
384
+ method to define default values for their specific attributes, ensuring that
385
+ models always have sensible initial state.
386
+
387
+ The defaults are applied first, then any data passed to the constructor will
388
+ override these default values. This allows for flexible model initialization
389
+ where some attributes have fallback values while others can be explicitly set.
390
+
391
+ ##### Examples
392
+
393
+ ```javascript
394
+ // Override in a User model subclass
395
+ protected defaults(): Partial<UserAttributes> {
396
+ return {
397
+ role: 'user',
398
+ isActive: true,
399
+ createdAt: new Date()
400
+ };
401
+ }
402
+ ```
403
+
404
+ ```javascript
405
+ // Creating a model with defaults
406
+ const user = new User({ name: 'John' });
407
+ // Resulting attributes: { role: 'user', isActive: true, createdAt: Date, name: 'John' }
408
+ ```
409
+
410
+ Returns **Partial\<T>** A partial object containing default attribute values
373
411
 
374
412
  #### get
375
413
 
@@ -766,6 +804,11 @@ const jsonString = JSON.stringify(user.toJSON());
766
804
 
767
805
  Returns **T** A plain object containing all of the model's attributes
768
806
 
807
+ ### validationError
808
+
809
+ Validation error property that gets set when validation fails.
810
+ This property contains the error returned by the validate method.
811
+
769
812
  ### Collection
770
813
 
771
814
  Abstract base class for managing collections of Model instances.
@@ -76,7 +76,7 @@ export class Model {
76
76
  * }
77
77
  * const user = new User({ _id: '507f1f77bcf86cd799439011', name: 'John' });
78
78
  */
79
- idAttribute = 'id';
79
+ idAttribute = vellumConfig.idAttribute;
80
80
  /**
81
81
  * Creates a new instance of Model.
82
82
  */
@@ -1,6 +1,7 @@
1
1
  export interface VellumConfig {
2
2
  origin: string;
3
3
  headers: Record<string, string>;
4
+ idAttribute: string;
4
5
  }
5
6
  /**
6
7
  * Global reactive state for Vellum configuration. Uses Svelte's $state rune to
@@ -8,6 +9,7 @@ export interface VellumConfig {
8
9
  *
9
10
  * @default origin - Empty string (must be configured before use)
10
11
  * @default headers - Contains 'Content-Type': 'application/json'
12
+ * @default idAttribute - The default unique identifier attribute for models
11
13
  */
12
14
  export declare const vellumConfig: VellumConfig;
13
15
  /**
@@ -20,6 +22,7 @@ export declare const vellumConfig: VellumConfig;
20
22
  * @param {Partial<VellumConfig>} config - Partial configuration object with properties to update
21
23
  * @param {string} [config.origin] - New origin URL to set
22
24
  * @param {Record<string, string>} [config.headers] - Headers to merge with existing headers
25
+ * @param {string} [config.idAttribute="id"] - The default unique identifier attribute for models
23
26
  *
24
27
  * @example
25
28
  * // Set the API origin
@@ -4,12 +4,14 @@
4
4
  *
5
5
  * @default origin - Empty string (must be configured before use)
6
6
  * @default headers - Contains 'Content-Type': 'application/json'
7
+ * @default idAttribute - The default unique identifier attribute for models
7
8
  */
8
9
  export const vellumConfig = $state({
9
10
  origin: '',
10
11
  headers: {
11
12
  'Content-Type': 'application/json'
12
- }
13
+ },
14
+ idAttribute: 'id'
13
15
  });
14
16
  /**
15
17
  * Helper function to update global Vellum configuration
@@ -21,6 +23,7 @@ export const vellumConfig = $state({
21
23
  * @param {Partial<VellumConfig>} config - Partial configuration object with properties to update
22
24
  * @param {string} [config.origin] - New origin URL to set
23
25
  * @param {Record<string, string>} [config.headers] - Headers to merge with existing headers
26
+ * @param {string} [config.idAttribute="id"] - The default unique identifier attribute for models
24
27
  *
25
28
  * @example
26
29
  * // Set the API origin
@@ -41,8 +44,12 @@ export const vellumConfig = $state({
41
44
  * });
42
45
  */
43
46
  export const configureVellum = (config) => {
44
- if (config.origin)
47
+ if (config.origin?.length) {
45
48
  vellumConfig.origin = config.origin;
49
+ }
50
+ if (config.idAttribute?.length) {
51
+ vellumConfig.idAttribute = config.idAttribute;
52
+ }
46
53
  if (config.headers) {
47
54
  vellumConfig.headers = { ...vellumConfig.headers, ...config.headers };
48
55
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jwerre/vellum",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Structural state management library for Svelte 5",
5
5
  "repository": {
6
6
  "type": "git",
@@ -32,7 +32,7 @@
32
32
  "types:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
33
33
  "check": "npm audit --audit-level=moderate --omit=dev && npm run format && npm run lint && npm run spell && npm run types && npm test && npm run build && npm run release:dry",
34
34
  "dev": "vite dev",
35
- "docs": "npm run build && documentation readme dist/index.js --section=\"API Documentation\"",
35
+ "docs": "npm run build && documentation readme dist/index.js --section=\"API Documentation\" && prettier --write README.md",
36
36
  "format": "prettier --check .",
37
37
  "format:write": "prettier --write .",
38
38
  "lint": "prettier --check . && eslint .",