vault-rails 0.0.10 → 0.0.11

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.
data/Rakefile CHANGED
@@ -1,2 +1,2 @@
1
- require "bundler/gem_tasks"
1
+ require "bundler"
2
2
  Bundler::GemHelper.install_tasks
@@ -1,6 +1,5 @@
1
1
  module Vault
2
- module Rails
3
- class Engine < ::Rails::Engine
4
- end
2
+ module Rails
3
+ require 'vault/rails/engine' if defined?(Rails)
5
4
  end
6
- end
5
+ end
@@ -0,0 +1,8 @@
1
+ require 'rails'
2
+
3
+ module Vault
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ end
7
+ end
8
+ end
@@ -1,5 +1,5 @@
1
1
  module Vault
2
2
  module Rails
3
- VERSION = "0.0.10"
3
+ VERSION = "0.0.11"
4
4
  end
5
5
  end
@@ -0,0 +1,629 @@
1
+ class Vault
2
+ constructor: (@name, @urls, options = {}) ->
3
+ # Setup some internal variables.
4
+ @objects = []
5
+ @dirty_object_count = 0
6
+ @save_error_count = 0
7
+ @messages =
8
+ notices: []
9
+ warnings: []
10
+ errors: []
11
+
12
+ # This property is used to temporarily lock the vault during mutation methods.
13
+ @locked = false
14
+
15
+ # Declare default options.
16
+ @options =
17
+ autoload: true
18
+ after_load: ->
19
+ id_attribute: "id"
20
+ offline: false
21
+ sub_collections: []
22
+
23
+ # Declare an array used to track ids that are in use,
24
+ # so as to prevent duplicates when generating new ones.
25
+ @ids_in_use = []
26
+
27
+ # Merge default options with user-defined ones.
28
+ for option, value of options
29
+ @options[option] = value
30
+
31
+ # Setup the vault for offline use.
32
+ if @options.offline
33
+ # Bind a cache routine to save data should the window be closed or url changed.
34
+ $(window).unload =>
35
+ @store()
36
+
37
+ # Load the collection if configured to do so.
38
+ if @options.autoload
39
+ # Check the offline data store first, if configured to do so.
40
+ if @options.offline
41
+ if @load()
42
+ if @dirty_object_count > 0
43
+ # Offline data loaded and modifications found; keep existing data.
44
+ @messages.notices.push "Found and using dirty offline data."
45
+
46
+ # Detach the callback to after_load so that the call to the
47
+ # vault constructor can complete/return, allowing any post-load code
48
+ # to use the newly instantiated vault object as required.
49
+ window.setTimeout @options.after_load, 100
50
+ else
51
+ # No modifications in offline data; reload fresh data.
52
+ @messages.notices.push "No modifications found in offline data. Reloading..."
53
+
54
+ if @urls.list?
55
+ @reload(@options.after_load)
56
+ else
57
+ # Can't reload without a list url; use the offline data we've loaded.
58
+ @messages.notices.push "List url not configured; using offline data instead."
59
+
60
+ # Detach the callback to after_load so that the call to the
61
+ # vault constructor can complete/return, allowing any post-load code
62
+ # to use the newly instantiated vault object as required.
63
+ window.setTimeout @options.after_load, 100
64
+ else
65
+ if navigator.onLine
66
+ # Load failed, but we're connected; reload fresh data.
67
+ @messages.warnings.push "Offline data load failed. Reloading..."
68
+
69
+ if @urls.list?
70
+ @reload(@options.after_load)
71
+ else
72
+ # Can't reload without a list url; use an empty dataset.
73
+ @messages.warnings.push "List url not configured; using empty dataset instead."
74
+
75
+ # Detach the callback to after_load so that the call to the
76
+ # vault constructor can complete/return, allowing any post-load code
77
+ # to use the newly instantiated vault object as required.
78
+ window.setTimeout @options.after_load, 100
79
+ else
80
+ # Load failed and we're offline; use an empty dataset.
81
+ @messages.warnings.push "Browser is offline and cannot reload; using empty dataset instead."
82
+
83
+ # Detach the callback to after_load so that the call to the
84
+ # vault constructor can complete/return, allowing any post-load code
85
+ # to use the newly instantiated vault object as required.
86
+ window.setTimeout @options.after_load, 100
87
+ else
88
+ # Not using offline data; reload fresh data.
89
+ @messages.notices.push "Not configured for offline data. Reloading..."
90
+
91
+ if @urls.list?
92
+ @reload(@options.after_load)
93
+ else
94
+ # Can't reload without a list url; use an empty dataset.
95
+ @messages.notices.push "List url not configured; using empty dataset instead."
96
+
97
+ # Detach the callback to after_load so that the call to the
98
+ # vault constructor can complete/return, allowing any post-load code
99
+ # to use the newly instantiated vault object as required.
100
+ window.setTimeout @options.after_load, 100
101
+
102
+ # Create convenience attributes for sub-collections.
103
+ for sub_collection in @options.sub_collections
104
+ do (sub_collection) =>
105
+ @[sub_collection] = {
106
+ 'find': (id) =>
107
+ for object in @objects
108
+ for sub_object in object[sub_collection]
109
+ if sub_object[@options.id_attribute].toString() is id.toString()
110
+ return sub_object
111
+
112
+ # Object with specified id couldn't be found.
113
+ return false
114
+ }
115
+
116
+ # Iterate over non-deleted items in the collection.
117
+ each: (logic) ->
118
+ for object in @objects
119
+ unless object.status == "deleted"
120
+ logic object
121
+
122
+ # Add a new item to the collection.
123
+ add: (object) ->
124
+ # Don't bother if the vault is locked.
125
+ if @locked
126
+ @messages.errors.push 'Cannot add, vault is locked.'
127
+ return false
128
+
129
+ # If the object has no id, generate a temporary one and add it to the object.
130
+ unless object[@options.id_attribute]? and object[@options.id_attribute] isnt ''
131
+ object[@options.id_attribute] = @generate_id()
132
+
133
+ # Extend the object with vault-specific variables and functions.
134
+ @extend object,"new"
135
+
136
+ # Add the object to the collection.
137
+ @objects.push object
138
+
139
+ # Increase the count of dirty objects.
140
+ @dirty_object_count++
141
+
142
+ # Store the collection.
143
+ @store
144
+
145
+ # Return the extended object.
146
+ return object
147
+
148
+ # Find an object in the collection using its id.
149
+ find: (id) ->
150
+ for object in @objects
151
+ if object[@options.id_attribute].toString() is id.toString()
152
+ return object
153
+
154
+ # Object with specified id couldn't be found.
155
+ return false
156
+
157
+ # Update an existing item in the collection.
158
+ update: (attributes, id) ->
159
+ # Don't bother if the vault is locked.
160
+ if @locked
161
+ @messages.errors.push 'Cannot update, vault is locked.'
162
+ return false
163
+
164
+ # Get the id of the object from the attributes if it's not explicitly defined.
165
+ id = attributes[@options.id_attribute] unless id?
166
+
167
+ # Get the object; return if it's undefined.
168
+ object = @find(id)
169
+ unless object?
170
+ @messages.errors.push 'Cannot update, object not found.'
171
+ return false
172
+
173
+ # Flag it as dirty.
174
+ if object.status is "clean"
175
+ object.status = "dirty"
176
+ @dirty_object_count++
177
+
178
+ # Merge in the updated attributes, if they're specified and defined on the object.
179
+ if attributes?
180
+ for attribute, value of attributes
181
+ if object[attribute]?
182
+ object[attribute] = value
183
+
184
+ # Store the collection.
185
+ @store
186
+
187
+ # Update was successful.
188
+ return true
189
+
190
+ # Flag an object in the collection for deletion,
191
+ # or if the object is new, remove it.
192
+ delete: (id) ->
193
+ # Don't bother if the vault is locked.
194
+ if @locked
195
+ @messages.errors.push 'Cannot delete, vault is locked.'
196
+ return false
197
+
198
+ for object, index in @objects
199
+ if object[@options.id_attribute] == id
200
+ switch object.status
201
+ when "new"
202
+ # New objects are special; we essentially want to
203
+ # reverse the steps taken during the add operation.
204
+ @objects.splice(index, 1)
205
+ @dirty_object_count--
206
+ when "clean"
207
+ object.status = "deleted"
208
+ @dirty_object_count++
209
+ when "dirty"
210
+ object.status = "deleted"
211
+
212
+ # Store the collection.
213
+ @store
214
+
215
+ # Delete was successful.
216
+ return true
217
+
218
+ # Object not found.
219
+ return false
220
+
221
+ # Forcibly remove an object from the collection.
222
+ destroy: (id) ->
223
+ # Don't bother if the vault is locked.
224
+ if @locked
225
+ @messages.errors.push 'Cannot delete, vault is locked.'
226
+ return false
227
+
228
+ for object, index in @objects
229
+ if object[@options.id_attribute] == id
230
+ # Remove the object from the collection.
231
+ @objects.splice(index, 1)
232
+
233
+ # Reduce the dirty count if this object
234
+ # was dirty, since we're no longer managing it.
235
+ switch object.status
236
+ when "new", "dirty"
237
+ @dirty_object_count--
238
+
239
+ # Store the collection.
240
+ @store
241
+
242
+ # Destroy was successful.
243
+ return true
244
+
245
+ # Object not found.
246
+ return false
247
+
248
+ # Write an object back to the server.
249
+ save: (id, after_save = ->) ->
250
+ # Don't bother if the vault is locked, we're offline or there's nothing to sync.
251
+ if @locked
252
+ @messages.errors.push 'Cannot save, vault is locked.'
253
+ return after_save()
254
+ else if not navigator.onLine
255
+ @messages.errors.push 'Cannot save, navigator is offline.'
256
+ return after_save()
257
+ else if @dirty_object_count is 0
258
+ @messages.errors.push 'Nothing to save.'
259
+ return after_save()
260
+
261
+ # Lock the vault until the save is complete.
262
+ @locked = true
263
+
264
+ # Find the object using the specified id.
265
+ object = @find(id)
266
+
267
+ # Package up the object to be sent to the server.
268
+ packaged_object = {}
269
+ packaged_object[@name] = JSON.stringify @strip object
270
+
271
+ switch object.status
272
+ when "deleted"
273
+ $.ajax
274
+ type: 'DELETE'
275
+ url: @urls.delete
276
+ data: packaged_object
277
+ fixture: (settings) ->
278
+ return true
279
+ success: (data) =>
280
+ # Forcibly remove the deleted object from the collection.
281
+ for vault_object, index in @objects
282
+ if vault_object.id == object.id
283
+ @objects.splice(index, 1)
284
+ @dirty_object_count--
285
+ error: =>
286
+ @messages.errors.push 'Failed to delete.'
287
+ complete: =>
288
+ # Store the collection, unlock the vault, and execute the callback method.
289
+ @store
290
+ @locked = false
291
+ after_save()
292
+ dataType: 'json'
293
+ when "new"
294
+ $.ajax
295
+ type: 'POST'
296
+ url: @urls.create
297
+ data: packaged_object
298
+ fixture: (settings) =>
299
+ return {
300
+ id: 123
301
+ make: "Dodge",
302
+ model: "Viper SRT-10",
303
+ year: 2008}
304
+ success: (data) =>
305
+ # Unlock the vault prematurely so that we can update it.
306
+ @locked = false
307
+
308
+ # Update the object with the attributes sent from the server.
309
+ object.update data, object.id
310
+
311
+ object.status = "clean"
312
+ @dirty_object_count--
313
+ error: =>
314
+ @messages.errors.push 'Failed to create.'
315
+ complete: =>
316
+ # Store the collection, unlock the vault, and execute the callback method.
317
+ @store
318
+ @locked = false
319
+ after_save()
320
+ dataType: 'json'
321
+ when "dirty"
322
+ $.ajax
323
+ type: 'POST'
324
+ url: @urls.update
325
+ data: packaged_object
326
+ fixture: (settings) ->
327
+ return true
328
+ success: (data) =>
329
+ object.status = "clean"
330
+ @dirty_object_count--
331
+ error: =>
332
+ @messages.errors.push 'Failed to update.'
333
+ complete: =>
334
+ # Store the collection, unlock the vault, and execute the callback method.
335
+ @store
336
+ @locked = false
337
+ after_save()
338
+ dataType: 'json'
339
+
340
+ # Used to wipe out the in-memory object list with a fresh one from the server.
341
+ reload: (after_load = ->) ->
342
+ # Don't bother if the vault is locked or we're offline.
343
+ if @locked
344
+ @messages.errors.push 'Cannot reload, vault is locked.'
345
+ return after_load()
346
+ else if not navigator.onLine
347
+ @messages.errors.push 'Cannot reload, navigator is offline.'
348
+ return after_load()
349
+ else if not @urls.list?
350
+ @messages.errors.push 'Cannot reload, list url is not configured.'
351
+ return after_load()
352
+
353
+ # Lock the vault until the reload is complete.
354
+ @locked = true
355
+
356
+ $.ajax
357
+ url: @urls.list
358
+ dataType: 'json'
359
+ success: (data) =>
360
+ # Replace the list of in-memory objects with the new data.
361
+ @objects = data
362
+
363
+ # Extend the objects with vault-specific variables and functions.
364
+ for object in @objects
365
+ @extend object
366
+
367
+ # Reset the count of dirty objects.
368
+ @dirty_object_count = 0
369
+
370
+ # Store the collection.
371
+ @store
372
+
373
+ # Call the callback function as the reload is complete.
374
+ after_load()
375
+ error: =>
376
+ @messages.errors.push 'Failed to list.'
377
+
378
+ # Call the callback function as the reload is complete (albeit unsuccessful).
379
+ after_load()
380
+ complete: =>
381
+ # Unlock the vault as the reload is complete.
382
+ @locked = false
383
+
384
+ # Convenience method for saving and reloading in one shot.
385
+ synchronize: (after_sync = ->) ->
386
+ # Don't bother if we're offline.
387
+ unless navigator.onLine
388
+ @messages.errors.push 'Cannot synchronize, navigator is offline.'
389
+ return after_sync()
390
+
391
+ @save =>
392
+ # Only reload the collection if there were no save errors.
393
+ if @messages.errors.length is 0
394
+ @reload(after_sync)
395
+ else
396
+ after_sync()
397
+
398
+ # Load the collection from offline storage.
399
+ load: ->
400
+ # Don't bother if offline support is disabled.
401
+ unless @options.offline
402
+ return false
403
+
404
+ # Try to load the collection.
405
+ if localStorage.getItem(@name)
406
+ @objects = $.parseJSON(localStorage.getItem @name)
407
+
408
+ # Extend the loaded objects with vault-specific variables and functions.
409
+ for object in @objects
410
+ @extend object
411
+
412
+ # Calculate the number of dirty objects.
413
+ for object in @objects
414
+ unless object.status is "clean"
415
+ @dirty_object_count++
416
+
417
+ return true
418
+ else
419
+ return false
420
+
421
+ # Store the collection for offline use.
422
+ store: ->
423
+ # Don't bother if offline support is disabled.
424
+ unless @options.offline
425
+ return false
426
+
427
+ # Store the collection.
428
+ localStorage.setItem(@name, JSON.stringify(@objects))
429
+ return true
430
+
431
+ # Extend an object with vault-specific variables and functions.
432
+ extend: (object, status) ->
433
+ # Validate the status argument.
434
+ if status?
435
+ throw "Invalid status specified: cannot extend object." unless status in ['clean', 'dirty', 'new']
436
+
437
+ # Add simple variables and methods.
438
+ object.update = (attributes) =>
439
+ @update(attributes, object.id)
440
+ object.delete = =>
441
+ @delete(object.id)
442
+ object.destroy = =>
443
+ @destroy(object.id)
444
+ object.save = (after_save) =>
445
+ @save(object.id, after_save)
446
+
447
+ if status?
448
+ # Status has been explicitly defined; force it on the object.
449
+ object.status = status
450
+ else
451
+ # Default the object's status to clean if it doesn't exist.
452
+ object.status = "clean" unless object.status?
453
+
454
+ # Iterate through all of the sub-collections, and if present
455
+ # extend them with some basic functionality.
456
+ for sub_collection in @options.sub_collections
457
+ do (sub_collection) =>
458
+ if object[sub_collection]?
459
+ # Find functionality.
460
+ object[sub_collection].find = (id) =>
461
+ for sub_collection_object in object[sub_collection]
462
+ if sub_collection_object[@options.id_attribute].toString() is id.toString()
463
+ return sub_collection_object
464
+
465
+ # Object with specified id couldn't be found.
466
+ return false
467
+
468
+ # Add functionality.
469
+ object[sub_collection].add = (sub_object) =>
470
+ # Don't bother if the vault is locked.
471
+ if @locked
472
+ @messages.errors.push 'Cannot add sub-object, vault is locked.'
473
+ return false
474
+
475
+ # Set a status on the object.
476
+ sub_object.status = "new"
477
+
478
+ # If the sub-object has no id, generate a temporary one and add it to the sub-object.
479
+ unless sub_object[@options.id_attribute]? and sub_object[@options.id_attribute] isnt ''
480
+ sub_object[@options.id_attribute] = @generate_id()
481
+
482
+ # Add a delete method to the sub-object.
483
+ sub_object.delete = =>
484
+ object[sub_collection].delete(sub_object[@options.id_attribute])
485
+
486
+ # Add an update method to the sub-object.
487
+ sub_object.update = (attributes) =>
488
+ object[sub_collection].update(attributes, sub_object[@options.id_attribute])
489
+
490
+ # Add the object to the collection.
491
+ object[sub_collection].push sub_object
492
+
493
+ # If the root object was clean, flag it and increase the count of dirty objects.
494
+ if object.status is "clean"
495
+ object.status = "dirty"
496
+ @dirty_object_count++
497
+
498
+ # Store the collection.
499
+ @store
500
+
501
+ return sub_object
502
+
503
+ # Delete functionality.
504
+ object[sub_collection].delete = (id) =>
505
+ # Don't bother if the vault is locked.
506
+ if @locked
507
+ @messages.errors.push 'Cannot delete sub-object, vault is locked.'
508
+ return false
509
+
510
+ # Remove the sub-object from its collection.
511
+ for sub_object, index in object[sub_collection]
512
+ if sub_object[@options.id_attribute] is id
513
+ object[sub_collection].splice(index, 1)
514
+
515
+ # If the root object was clean, flag it and increase the count of dirty objects.
516
+ if object.status is "clean"
517
+ object.status = "dirty"
518
+ @dirty_object_count++
519
+
520
+ # Store the collection.
521
+ @store
522
+
523
+ # Add a delete instance method for pre-existing objects.
524
+ for sub_object, index in object[sub_collection]
525
+ sub_object.delete = =>
526
+ object[sub_collection].delete(sub_object[@options.id_attribute])
527
+
528
+ # Update functionality.
529
+ object[sub_collection].update = (attributes, id) =>
530
+ # Don't bother if the vault is locked.
531
+ if @locked
532
+ @messages.errors.push 'Cannot update sub-object, vault is locked.'
533
+ return false
534
+
535
+ # Get the id of the sub-object from the attributes if it's not explicitly defined.
536
+ id = attributes[@options.id_attribute] unless id?
537
+
538
+ # Get the sub-object; return if it's undefined.
539
+ sub_object = object[sub_collection].find(id)
540
+ unless sub_object?
541
+ @messages.errors.push 'Cannot update, sub-object not found.'
542
+ return false
543
+
544
+ # If the root object was clean, flag it and increase the count of dirty objects.
545
+ if object.status is "clean"
546
+ object.status = "dirty"
547
+ @dirty_object_count++
548
+
549
+ # Merge in the updated attributes, if they're specified and defined on the sub-object.
550
+ if attributes?
551
+ for attribute, value of attributes
552
+ if sub_object[attribute]?
553
+ sub_object[attribute] = value
554
+
555
+ # Store the collection.
556
+ @store
557
+
558
+ # Add an update instance method for pre-existing objects.
559
+ for sub_object in object[sub_collection]
560
+ do (sub_object) =>
561
+ sub_object.update = (attributes) =>
562
+ object[sub_collection].update(attributes, sub_object[@options.id_attribute])
563
+
564
+ return object
565
+
566
+ # Return a copy of an object with vault-specific variables and functions removed.
567
+ strip: (object) ->
568
+ # Clone the object so that we don't strip the original.
569
+ object_clone = @clone object
570
+
571
+ # Remove the temporary id given to new objects.
572
+ if object_clone.status is "new"
573
+ delete object_clone[@options.id_attribute]
574
+
575
+ # Remove vault object methods.
576
+ delete object_clone.status
577
+ delete object_clone.update
578
+ delete object_clone.delete
579
+ delete object_clone.destroy
580
+ delete object_clone.save
581
+
582
+ # Iterate through all of the sub-collections, and if present
583
+ # strip them of their extended functionality.
584
+ for sub_collection in @options.sub_collections
585
+ if object_clone[sub_collection]?
586
+ # Remove the sub-collection's methods.
587
+ delete object_clone[sub_collection].find
588
+ delete object_clone[sub_collection].add
589
+ delete object_clone[sub_collection].delete
590
+ delete object_clone[sub_collection].update
591
+
592
+ # Iterate through and remove the extended instances' methods.
593
+ for sub_object in object_clone[sub_collection]
594
+ if sub_object.status is "new"
595
+ delete sub_object[@options.id_attribute]
596
+ delete sub_object.status
597
+ delete sub_object.delete
598
+ delete sub_object.update
599
+ return object_clone
600
+
601
+ # Clone (deep copy) an object.
602
+ clone: (object) ->
603
+ unless object? and typeof object is 'object'
604
+ return object
605
+
606
+ new_instance = new object.constructor()
607
+
608
+ for key of object
609
+ new_instance[key] = @clone object[key]
610
+
611
+ return new_instance
612
+
613
+ # Generate a new unique (within the set of generated ids) id.
614
+ generate_id: ->
615
+ until id_is_available
616
+ # Generate a new id and assume it's available.
617
+ id = new Date().getTime()
618
+ id_is_available = true
619
+
620
+ # Flag the new id as unavailable if it's taken.
621
+ id_is_available = false for taken in @ids_in_use when id is taken
622
+
623
+ # Store the new id so that it's not used again.
624
+ @ids_in_use.push id
625
+
626
+ return id
627
+
628
+ # Attach the Vault class to the window so that it can be used by other scripts.
629
+ window.Vault = this
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vault-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-04 00:00:00.000000000Z
12
+ date: 2012-01-05 00:00:00.000000000Z
13
13
  dependencies: []
14
14
  description: Store and manage collections of objects without a connection.
15
15
  email:
@@ -18,14 +18,12 @@ executables: []
18
18
  extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
- - .gitignore
22
- - Gemfile
23
- - LICENSE
24
- - Rakefile
25
21
  - lib/vault-rails.rb
26
- - lib/vault-rails/version.rb
27
- - vault-rails.gemspec
22
+ - lib/vault/rails/version.rb
23
+ - lib/vault/rails/engine.rb
24
+ - vendor/assets/javascripts/vault/vault.js.coffee
28
25
  - vendor/assets/javascripts/vault.js.coffee
26
+ - Rakefile
29
27
  homepage: https://github.com/cityofgreatersudbury/vault-rails
30
28
  licenses: []
31
29
  post_install_message:
@@ -46,7 +44,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
46
44
  version: '0'
47
45
  requirements: []
48
46
  rubyforge_project: vault-rails
49
- rubygems_version: 1.8.11
47
+ rubygems_version: 1.8.10
50
48
  signing_key:
51
49
  specification_version: 3
52
50
  summary: CoffeeScript collection class for offline use.
data/.gitignore DELETED
@@ -1,4 +0,0 @@
1
- *.gem
2
- .bundle
3
- Gemfile.lock
4
- pkg/*
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in vault-rails.gemspec
4
- gemspec
data/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- The MIT License
2
-
3
- Copyright (c) 2011 Dennis Reimann
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
@@ -1,19 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "vault-rails/version"
4
-
5
- Gem::Specification.new do |s|
6
- s.name = "vault-rails"
7
- s.version = Vault::Rails::VERSION
8
- s.authors = ["Jordan MacDonald"]
9
- s.email = ["jordan.macdonald@greatersudbury.ca"]
10
- s.homepage = 'https://github.com/cityofgreatersudbury/vault-rails'
11
- s.summary = 'CoffeeScript collection class for offline use.'
12
- s.description = 'Store and manage collections of objects without a connection.'
13
-
14
- s.rubyforge_project = "vault-rails"
15
-
16
- s.files = `git ls-files`.split("\n")
17
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
- s.require_paths = ["lib"]
19
- end