vault-rails 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
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