From 8ad02b89498d79c022356815658e67eac04d50c6 Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Thu, 28 Sep 2017 18:32:37 +0200 Subject: [PATCH 01/18] *BREAKING*: Remove application.online_devices and application.device_length These were slightly convenient, but hacky and inconsistent with any data retrieved manually with $expands. One day we might bring these back, but for now it's much cleaner for everybody if we keep this simple. Change-Type: major --- lib/models/application.coffee | 4 ---- tests/integration/models/application.spec.coffee | 8 -------- 2 files changed, 12 deletions(-) diff --git a/lib/models/application.coffee b/lib/models/application.coffee index 0a29b5bfd..9319ee746 100644 --- a/lib/models/application.coffee +++ b/lib/models/application.coffee @@ -96,11 +96,7 @@ getApplicationModel = (deps, opts) -> user: userId , options - # TODO: It might be worth to do all these handy - # manipulations server side directly. .map (application) -> - application.online_devices = filter(application.device, is_online: true).length - application.devices_length = application.device?.length or 0 normalizeApplication(application) return application diff --git a/tests/integration/models/application.spec.coffee b/tests/integration/models/application.spec.coffee index fd0e49401..6363d8346 100644 --- a/tests/integration/models/application.spec.coffee +++ b/tests/integration/models/application.spec.coffee @@ -106,14 +106,6 @@ describe 'Application Model', -> resin.models.application.getAll().then (applications) => m.chai.expect(applications[0].id).to.equal(@application.id) - it 'should add a devices_length property', -> - resin.models.application.getAll().then (applications) -> - m.chai.expect(applications[0].devices_length).to.equal(0) - - it 'should add an online_devices property', -> - resin.models.application.getAll().then (applications) -> - m.chai.expect(applications[0].online_devices).to.equal(0) - it 'should support arbitrary pinejs options', -> resin.models.application.getAll(expand: 'user') .then (applications) -> From 0e704c905f4c3aff778a1edbce7f5a06ab2d2e30 Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Thu, 28 Sep 2017 19:29:15 +0200 Subject: [PATCH 02/18] *BREAKING*: Remove device.application_name and device.dashboard_url Both of these were generated from expanded data we'd like to remove, and somewhat messily at that. You can easily generate them by hand by expanding application yourself and looking at the name and id there by hand. Change-Type: major --- lib/models/device.coffee | 10 +++--- tests/integration/models/device.spec.coffee | 36 --------------------- 2 files changed, 6 insertions(+), 40 deletions(-) diff --git a/lib/models/device.coffee b/lib/models/device.coffee index d23a71241..2e26c4348 100644 --- a/lib/models/device.coffee +++ b/lib/models/device.coffee @@ -117,9 +117,6 @@ getDeviceModel = (deps, opts) -> return url.resolve(dashboardUrl, "/apps/#{options.appId}/devices/#{options.deviceId}/summary") addExtraInfo = (device) -> - # TODO: Move this to the server - device.application_name = device.application[0].app_name - device.dashboard_url = getDashboardUrl({ appId: device.application[0].id, deviceId: device.id }) normalizeDeviceOsVersion(device) return device @@ -389,7 +386,12 @@ getDeviceModel = (deps, opts) -> # }); ### exports.getApplicationName = (uuidOrId, callback) -> - exports.get(uuidOrId, select: 'application_name').get('application_name').asCallback(callback) + exports.get uuidOrId, + select: 'id' + expand: application: $select: 'app_name' + .then (device) -> + device.application[0].app_name + .asCallback(callback) ###* # @summary Get application container information diff --git a/tests/integration/models/device.spec.coffee b/tests/integration/models/device.spec.coffee index 20a9dcda4..f004770f7 100644 --- a/tests/integration/models/device.spec.coffee +++ b/tests/integration/models/device.spec.coffee @@ -197,14 +197,6 @@ describe 'Device Model', -> m.chai.expect(devices).to.have.length(1) m.chai.expect(devices[0].id).to.equal(@device.id) - it 'should add an application_name property', -> - resin.models.device.getAll().then (devices) => - m.chai.expect(devices[0].application_name).to.equal(@application.app_name) - - it 'should add a dashboard_url property', -> - resin.models.device.getAll().then (devices) => - m.chai.expect(devices[0].dashboard_url).to.equal(resin.models.device.getDashboardUrl({ appId: @application.id, deviceId: @device.id })) - it 'should support arbitrary pinejs options', -> resin.models.device.getAll(select: [ 'id' ]) .then ([ device ]) => @@ -223,14 +215,6 @@ describe 'Device Model', -> m.chai.expect(devices).to.have.length(1) m.chai.expect(devices[0].id).to.equal(@device.id) - it 'should include an application_name property in the result', -> - resin.models.device.getAllByApplication(@application.id).then (devices) => - m.chai.expect(devices[0].application_name).to.equal(@application.app_name) - - it 'should add a dashboard_url property', -> - resin.models.device.getAllByApplication(@application.id).then (devices) => - m.chai.expect(devices[0].dashboard_url).to.equal(resin.models.device.getDashboardUrl({ appId: @application.id, deviceId: @device.id })) - it 'should be rejected if the application name does not exist', -> promise = resin.models.device.getAllByApplication('HelloWorldApp') m.chai.expect(promise).to.be.rejectedWith('Application not found: HelloWorldApp') @@ -278,10 +262,6 @@ describe 'Device Model', -> m.chai.expect(childDevices).to.have.length(1) m.chai.expect(childDevices[0].id).to.equal(@childDevice.id) - it 'should include an application_name property in the result (with the child app name)', -> - resin.models.device.getAllByParentDevice(@device.id).then ([ childDevice ]) => - m.chai.expect(childDevice.application_name).to.equal(@childApplication.app_name) - it 'should be empty if the parent device has no children', -> promise = resin.models.device.getAllByParentDevice(@childDevice.id).then (childDevices) -> m.chai.expect(childDevices).to.have.length(0) @@ -306,14 +286,6 @@ describe 'Device Model', -> resin.models.device.get(@device.id).then (device) => m.chai.expect(device.id).to.equal(@device.id) - it 'should add an application_name property', -> - resin.models.device.get(@device.id).then (device) => - m.chai.expect(device.application_name).to.equal(@application.app_name) - - it 'should add a dashboard_url property', -> - resin.models.device.get(@device.id).then (device) => - m.chai.expect(device.dashboard_url).to.equal(resin.models.device.getDashboardUrl({ appId: @application.id, deviceId: @device.id })) - it 'should be rejected if the device name does not exist', -> promise = resin.models.device.get('asdfghjkl') m.chai.expect(promise).to.be.rejectedWith('Device not found: asdfghjkl') @@ -339,14 +311,6 @@ describe 'Device Model', -> m.chai.expect(devices).to.have.length(1) m.chai.expect(devices[0].id).to.equal(@device.id) - it 'should add an application_name property', -> - resin.models.device.getByName(@device.name).then (devices) => - m.chai.expect(devices[0].application_name).to.equal(@application.app_name) - - it 'should add a dashboard_url property', -> - resin.models.device.getByName(@device.name).then (devices) => - m.chai.expect(devices[0].dashboard_url).to.equal(resin.models.device.getDashboardUrl({ appId: @application.id, deviceId: @device.id })) - it 'should be rejected if the device does not exist', -> promise = resin.models.device.getByName('HelloWorldDevice') m.chai.expect(promise).to.be.rejectedWith('Device not found: HelloWorldDevice') From d809e8286a4fdb42e86b4c71cf4f018330bc5eea Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Thu, 28 Sep 2017 21:06:19 +0200 Subject: [PATCH 03/18] *BREAKING*: Don't expand relationships by default. Pass { expand: '...' } options to opt in instead. Change-Type: major --- lib/models/application.coffee | 10 ++++------ lib/models/build.coffee | 6 ------ lib/models/device.coffee | 7 +------ lib/models/environment-variables.coffee | 5 +---- lib/util/index.coffee | 2 -- tests/util.spec.coffee | 9 --------- 6 files changed, 6 insertions(+), 33 deletions(-) diff --git a/lib/models/application.coffee b/lib/models/application.coffee index 9319ee746..86b17af94 100644 --- a/lib/models/application.coffee +++ b/lib/models/application.coffee @@ -91,7 +91,6 @@ getApplicationModel = (deps, opts) -> options: mergePineOptions orderby: 'app_name asc' - expand: 'device' filter: user: userId , options @@ -195,15 +194,14 @@ getApplicationModel = (deps, opts) -> $eq: [ $tolower: $: 'app_name' appName - ] - expand: + ], user: - $filter: - $eq: [ + $any: + $alias: 'u', + $expr: $eq: [ $tolower: $: 'username' owner ] - $select: 'id' , options .tap (applications) -> if isEmpty(applications) diff --git a/lib/models/build.coffee b/lib/models/build.coffee index 79c568397..363a7dc4d 100644 --- a/lib/models/build.coffee +++ b/lib/models/build.coffee @@ -113,12 +113,6 @@ getBuildModel = (deps, opts) -> 'message' # 'log' # We *don't* include logs by default, since it's usually huge. ] - expand: - user: - $select: [ - 'id' - 'username' - ] orderby: 'created_at desc' , options .asCallback(callback) diff --git a/lib/models/device.coffee b/lib/models/device.coffee index 2e26c4348..bfbbc4081 100644 --- a/lib/models/device.coffee +++ b/lib/models/device.coffee @@ -149,7 +149,6 @@ getDeviceModel = (deps, opts) -> resource: 'device' options: mergePineOptions - expand: 'application' orderby: 'name asc' , options @@ -269,10 +268,7 @@ getDeviceModel = (deps, opts) -> pine.get resource: 'device' id: uuidOrId - options: - mergePineOptions - expand: 'application' - , options + options: options .tap (device) -> if not device? throw new errors.ResinDeviceNotFound(uuidOrId) @@ -281,7 +277,6 @@ getDeviceModel = (deps, opts) -> resource: 'device' options: mergePineOptions - expand: 'application' filter: uuid: $startswith: uuidOrId , options diff --git a/lib/models/environment-variables.coffee b/lib/models/environment-variables.coffee index 2532a5ae7..fb6bcc7f6 100644 --- a/lib/models/environment-variables.coffee +++ b/lib/models/environment-variables.coffee @@ -229,9 +229,7 @@ getEnvironmentVariablesModel = (deps, opts) -> return pine.get resource: 'device_environment_variable' options: - filter: - device: id - expand: 'device' + filter: device: id orderby: 'env_var_name asc' .map(fixDeviceEnvVarNameKey) .asCallback(callback) @@ -273,7 +271,6 @@ getEnvironmentVariablesModel = (deps, opts) -> $any: $alias: 'd', $expr: d: application: id - expand: 'device' orderby: 'env_var_name asc' .map(fixDeviceEnvVarNameKey) .asCallback(callback) diff --git a/lib/util/index.coffee b/lib/util/index.coffee index 519253f45..060c1f130 100644 --- a/lib/util/index.coffee +++ b/lib/util/index.coffee @@ -133,8 +133,6 @@ exports.mergePineOptions = (defaults, extras) -> if value? if not isArray(value) value = [value] - if !includes(value, 'id') - value.unshift('id') result[option] = value diff --git a/tests/util.spec.coffee b/tests/util.spec.coffee index 3accac517..d7db4a836 100644 --- a/tests/util.spec.coffee +++ b/tests/util.spec.coffee @@ -42,15 +42,6 @@ describe 'Pine option merging', -> skip: 4 orderby: 'id asc' - it 'overrides select options, but always includes id', -> - result = mergePineOptions - select: ['id', 'other'] - , - select: ['app_name'] - - m.chai.expect(result).to.deep.equal - select: ['id', 'app_name'] - it 'combines filter options with $and', -> result = mergePineOptions filter: id: 1 From b7e9445a73367075a330b3a0cee2831305201859 Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Fri, 29 Sep 2017 10:59:46 +0200 Subject: [PATCH 04/18] Update yarn.lock --- yarn.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/yarn.lock b/yarn.lock index a3cf63839..0b77cf4c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4082,19 +4082,19 @@ resin-errors@^2.0.0: dependencies: typed-error "^0.1.0" +resin-errors@^2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/resin-errors/-/resin-errors-2.10.0.tgz#1e24d07f0ef7d4f1edb519fad4ae4e659c1e0c66" + dependencies: + tslib "^1.7.1" + typed-error "^2.0.0" + resin-errors@^2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/resin-errors/-/resin-errors-2.7.0.tgz#93ade640792107556d916df8692b5ecd97dda297" dependencies: typed-error "^0.1.0" -resin-errors@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/resin-errors/-/resin-errors-2.9.0.tgz#1f5de94238d2a70c0736dca84b7bf63a144e4e50" - dependencies: - tslib "^1.7.1" - typed-error "^2.0.0" - resin-pine@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/resin-pine/-/resin-pine-5.0.2.tgz#a7337acd1604d44d4ff450fbbeb8bbd9936af103" From 89afe7bb5648e93d86d6c1bf9fe10886a824cd7a Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Fri, 29 Sep 2017 11:46:20 +0200 Subject: [PATCH 05/18] Make device.move throw ResinInvalidDeviceType for incompatible device types (not just Error) Change-Type: patch --- lib/models/device.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/models/device.coffee b/lib/models/device.coffee index bfbbc4081..9ddef9502 100644 --- a/lib/models/device.coffee +++ b/lib/models/device.coffee @@ -767,7 +767,7 @@ getDeviceModel = (deps, opts) -> .then ({ application, device }) -> if device.device_type isnt application.device_type - throw new Error("Incompatible application: #{applicationNameOrId}") + throw new errors.ResinInvalidDeviceType("Incompatible application: #{applicationNameOrId}") return pine.patch resource: 'device' From 4391099864a32cccd85b88869c120c72fc5d2726 Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Thu, 21 Sep 2017 20:04:29 +0300 Subject: [PATCH 06/18] *BREAKING*: Don't allow creating applications with discontinued device types Connects-To: #358 Change-Type: major --- lib/models/application.coffee | 15 +++++++++------ package.json | 2 +- tests/integration/models/application.spec.coffee | 6 +++++- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/models/application.coffee b/lib/models/application.coffee index 0caec36d0..0a29b5bfd 100644 --- a/lib/models/application.coffee +++ b/lib/models/application.coffee @@ -349,13 +349,16 @@ getApplicationModel = (deps, opts) -> else Promise.resolve() - deviceSlugPromise = deviceModel().getDeviceSlug(deviceType) - .tap (deviceSlug) -> - if not deviceSlug? + deviceManifestPromise = deviceModel().getManifestBySlug(deviceType) + .tap (deviceManifest) -> + if not deviceManifest? throw new errors.ResinInvalidDeviceType(deviceType) - return Promise.all([ deviceSlugPromise, parentAppPromise ]) - .then ([ deviceSlug, parentApplication ]) -> + return Promise.all([ deviceManifestPromise, parentAppPromise ]) + .then ([ deviceManifest, parentApplication ]) -> + if deviceManifest.state == 'DISCONTINUED' + throw new errors.ResinDiscontinuedDeviceType(deviceType) + extraOptions = if parentApplication application: parentApplication.id else {} @@ -365,7 +368,7 @@ getApplicationModel = (deps, opts) -> body: assign app_name: name - device_type: deviceSlug + device_type: deviceManifest.slug , extraOptions .asCallback(callback) diff --git a/package.json b/package.json index ee6352d55..4f4dbace2 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "promise-memoize": "^1.2.0", "resin-device-logs": "^3.1.0", "resin-device-status": "^1.0.1", - "resin-errors": "^2.9.0", + "resin-errors": "^2.10.0", "resin-pine": "^5.0.2", "resin-register-device": "^4.0.1", "resin-request": "^8.6.0", diff --git a/tests/integration/models/application.spec.coffee b/tests/integration/models/application.spec.coffee index 7df9b3e0e..fd0e49401 100644 --- a/tests/integration/models/application.spec.coffee +++ b/tests/integration/models/application.spec.coffee @@ -36,7 +36,7 @@ describe 'Application Model', -> it 'should be able to create a child application', -> resin.models.application.create('FooBar', 'raspberry-pi').then (parentApplication) -> - resin.models.application.create('FooBarChild', 'edge', parentApplication.id) + resin.models.application.create('FooBarChild', 'generic-amd64', parentApplication.id) .then -> resin.models.application.getAll() .then ([ parentApplication, childApplication ]) -> @@ -46,6 +46,10 @@ describe 'Application Model', -> promise = resin.models.application.create('FooBar', 'foobarbaz') m.chai.expect(promise).to.be.rejectedWith('Invalid device type: foobarbaz') + it 'should be rejected if the device type is discontinuted', -> + promise = resin.models.application.create('FooBar', 'edge') + m.chai.expect(promise).to.be.rejectedWith('Discontinued device type: edge') + it 'should be rejected if the name has less than three characters', -> promise = resin.models.application.create('Fo', 'raspberry-pi') m.chai.expect(promise).to.be.rejected From c1b14973151604a4b3762bf82e74350ea77ebdb7 Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Mon, 2 Oct 2017 12:45:22 +0200 Subject: [PATCH 07/18] *BREAKING*: Rename getAppWithOwner to getAppByOwner Change-Type: major --- DOCUMENTATION.md | 12 ++++++------ lib/models/application.coffee | 6 +++--- tests/integration/models/application.spec.coffee | 10 +++++----- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index f0a85c853..356004e6e 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -20,7 +20,7 @@ If you feel something is missing, not clear or could be improved, please don't h * [.application](#resin.models.application) : object * [.getAll([options])](#resin.models.application.getAll) ⇒ Promise * [.get(nameOrId, [options])](#resin.models.application.get) ⇒ Promise - * [.getAppWithOwner(appName, owner, [options])](#resin.models.application.getAppWithOwner) ⇒ Promise + * [.getAppByOwner(appName, owner, [options])](#resin.models.application.getAppByOwner) ⇒ Promise * [.has(nameOrId)](#resin.models.application.has) ⇒ Promise * [.hasAny()](#resin.models.application.hasAny) ⇒ Promise * ~~[.getById(id)](#resin.models.application.getById) ⇒ Promise~~ @@ -269,7 +269,7 @@ resin.models.device.get(123).catch(function (error) { * [.application](#resin.models.application) : object * [.getAll([options])](#resin.models.application.getAll) ⇒ Promise * [.get(nameOrId, [options])](#resin.models.application.get) ⇒ Promise - * [.getAppWithOwner(appName, owner, [options])](#resin.models.application.getAppWithOwner) ⇒ Promise + * [.getAppByOwner(appName, owner, [options])](#resin.models.application.getAppByOwner) ⇒ Promise * [.has(nameOrId)](#resin.models.application.has) ⇒ Promise * [.hasAny()](#resin.models.application.hasAny) ⇒ Promise * ~~[.getById(id)](#resin.models.application.getById) ⇒ Promise~~ @@ -379,7 +379,7 @@ resin.models.device.get(123).catch(function (error) { * [.application](#resin.models.application) : object * [.getAll([options])](#resin.models.application.getAll) ⇒ Promise * [.get(nameOrId, [options])](#resin.models.application.get) ⇒ Promise - * [.getAppWithOwner(appName, owner, [options])](#resin.models.application.getAppWithOwner) ⇒ Promise + * [.getAppByOwner(appName, owner, [options])](#resin.models.application.getAppByOwner) ⇒ Promise * [.has(nameOrId)](#resin.models.application.has) ⇒ Promise * [.hasAny()](#resin.models.application.hasAny) ⇒ Promise * ~~[.getById(id)](#resin.models.application.getById) ⇒ Promise~~ @@ -454,9 +454,9 @@ resin.models.application.get('MyApp', function(error, application) { console.log(application); }); ``` - + -##### application.getAppWithOwner(appName, owner, [options]) ⇒ Promise +##### application.getAppByOwner(appName, owner, [options]) ⇒ Promise **Kind**: static method of [application](#resin.models.application) **Summary**: Get a single application using the appname and owner's username **Access**: public @@ -470,7 +470,7 @@ resin.models.application.get('MyApp', function(error, application) { **Example** ```js -resin.models.application.getAppWithOwner('MyApp', 'MyUser').then(function(application) { +resin.models.application.getAppByOwner('MyApp', 'MyUser').then(function(application) { console.log(application); }); ``` diff --git a/lib/models/application.coffee b/lib/models/application.coffee index 86b17af94..f8e564dc4 100644 --- a/lib/models/application.coffee +++ b/lib/models/application.coffee @@ -164,7 +164,7 @@ getApplicationModel = (deps, opts) -> ###* # @summary Get a single application using the appname and owner's username - # @name getAppWithOwner + # @name getAppByOwner # @public # @function # @memberof resin.models.application @@ -176,11 +176,11 @@ getApplicationModel = (deps, opts) -> # @returns {Promise} # # @example - # resin.models.application.getAppWithOwner('MyApp', 'MyUser').then(function(application) { + # resin.models.application.getAppByOwner('MyApp', 'MyUser').then(function(application) { # console.log(application); # }); ### - exports.getAppWithOwner = (appName, owner, options = {}, callback) -> + exports.getAppByOwner = (appName, owner, options = {}, callback) -> callback = findCallback(arguments) appName = appName.toLowerCase() diff --git a/tests/integration/models/application.spec.coffee b/tests/integration/models/application.spec.coffee index 6363d8346..a2e342ff5 100644 --- a/tests/integration/models/application.spec.coffee +++ b/tests/integration/models/application.spec.coffee @@ -15,10 +15,10 @@ describe 'Application Model', -> promise = resin.models.application.getAll() m.chai.expect(promise).to.become([]) - describe 'resin.models.application.getAppWithOwner()', -> + describe 'resin.models.application.getAppByOwner()', -> it 'should eventually reject', -> - promise = resin.models.application.getAppWithOwner('testapp', 'FooBar') + promise = resin.models.application.getAppByOwner('testapp', 'FooBar') m.chai.expect(promise).to.be.rejected describe 'resin.models.application.hasAny()', -> @@ -86,14 +86,14 @@ describe 'Application Model', -> promise = resin.models.application.hasAny() m.chai.expect(promise).to.eventually.be.true - describe 'resin.models.application.getAppWithOwner()', -> + describe 'resin.models.application.getAppByOwner()', -> it 'should find the created application', -> - resin.models.application.getAppWithOwner('FooBar', credentials.username).then (application) => + resin.models.application.getAppByOwner('FooBar', credentials.username).then (application) => m.chai.expect(application.id).to.equal(@application.id) it 'should not find the created application with a different username', -> - promise = resin.models.application.getAppWithOwner('FooBar', 'test_username') + promise = resin.models.application.getAppByOwner('FooBar', 'test_username') m.chai.expect(promise).to.eventually.reject describe 'resin.models.application.getAll()', -> From 84ad402c4f522c92d2c0257816306d8cee05d3a0 Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Mon, 2 Oct 2017 17:53:02 +0200 Subject: [PATCH 08/18] *BREAKING*: Remove (already deprecated) models.application.getApiKey() Change-Type: major --- DOCUMENTATION.md | 18 ------------------ lib/models/application.coffee | 16 ---------------- 2 files changed, 34 deletions(-) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 356004e6e..50bd22ab3 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -32,7 +32,6 @@ If you feel something is missing, not clear or could be improved, please don't h * [.purge(appId)](#resin.models.application.purge) ⇒ Promise * [.shutdown(appId, [options])](#resin.models.application.shutdown) ⇒ Promise * [.reboot(appId, [options])](#resin.models.application.reboot) ⇒ Promise - * ~~[.getApiKey(nameOrId)](#resin.models.application.getApiKey) ⇒ Promise~~ * [.enableDeviceUrls(nameOrId)](#resin.models.application.enableDeviceUrls) ⇒ Promise * [.disableDeviceUrls(nameOrId)](#resin.models.application.disableDeviceUrls) ⇒ Promise * [.grantSupportAccess(nameOrId, expiryTimestamp)](#resin.models.application.grantSupportAccess) ⇒ Promise @@ -281,7 +280,6 @@ resin.models.device.get(123).catch(function (error) { * [.purge(appId)](#resin.models.application.purge) ⇒ Promise * [.shutdown(appId, [options])](#resin.models.application.shutdown) ⇒ Promise * [.reboot(appId, [options])](#resin.models.application.reboot) ⇒ Promise - * ~~[.getApiKey(nameOrId)](#resin.models.application.getApiKey) ⇒ Promise~~ * [.enableDeviceUrls(nameOrId)](#resin.models.application.enableDeviceUrls) ⇒ Promise * [.disableDeviceUrls(nameOrId)](#resin.models.application.disableDeviceUrls) ⇒ Promise * [.grantSupportAccess(nameOrId, expiryTimestamp)](#resin.models.application.grantSupportAccess) ⇒ Promise @@ -391,7 +389,6 @@ resin.models.device.get(123).catch(function (error) { * [.purge(appId)](#resin.models.application.purge) ⇒ Promise * [.shutdown(appId, [options])](#resin.models.application.shutdown) ⇒ Promise * [.reboot(appId, [options])](#resin.models.application.reboot) ⇒ Promise - * ~~[.getApiKey(nameOrId)](#resin.models.application.getApiKey) ⇒ Promise~~ * [.enableDeviceUrls(nameOrId)](#resin.models.application.enableDeviceUrls) ⇒ Promise * [.disableDeviceUrls(nameOrId)](#resin.models.application.disableDeviceUrls) ⇒ Promise * [.grantSupportAccess(nameOrId, expiryTimestamp)](#resin.models.application.grantSupportAccess) ⇒ Promise @@ -768,21 +765,6 @@ resin.models.application.reboot(123, function(error) { if (error) throw error; }); ``` - - -##### ~~application.getApiKey(nameOrId) ⇒ Promise~~ -***Deprecated*** - -**Kind**: static method of [application](#resin.models.application) -**Summary**: Get an API key for a specific application -**Access**: public -**Fulfil**: String - api key -**See**: [generateApiKey](#resin.models.application.generateApiKey) - -| Param | Type | Description | -| --- | --- | --- | -| nameOrId | String \| Number | application name (string) or id (number) | - ##### application.enableDeviceUrls(nameOrId) ⇒ Promise diff --git a/lib/models/application.coffee b/lib/models/application.coffee index f8e564dc4..d14e521a2 100644 --- a/lib/models/application.coffee +++ b/lib/models/application.coffee @@ -611,22 +611,6 @@ getApplicationModel = (deps, opts) -> throw err .asCallback(callback) - ###* - # @summary Get an API key for a specific application - # @name getApiKey - # @public - # @function - # @memberof resin.models.application - # - # @param {String|Number} nameOrId - application name (string) or id (number) - # @fulfil {String} - api key - # @returns {Promise} - # - # @deprecated Use generateApiKey instead - # @see {@link resin.models.application.generateApiKey} - ### - exports.getApiKey = exports.generateApiKey - ###* # @summary Enable device urls for all devices that belong to an application # @name enableDeviceUrls From a340c22bfb078f525ddeb8feffdc20021827cec4 Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Mon, 2 Oct 2017 17:54:28 +0200 Subject: [PATCH 09/18] Change device registration to use a provisioning key Change-Type: major --- lib/models/device.coffee | 23 +++++++++++++---------- lib/util/index.coffee | 5 +++++ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/models/device.coffee b/lib/models/device.coffee index 9ddef9502..614cc0bce 100644 --- a/lib/models/device.coffee +++ b/lib/models/device.coffee @@ -28,7 +28,17 @@ semver = require('semver') errors = require('resin-errors') deviceStatus = require('resin-device-status') -{ onlyIf, isId, findCallback, mergePineOptions, notFoundResponse, treatAsMissingDevice, LOCKED_STATUS_CODE, timeSince } = require('../util') +{ + onlyIf, + isId, + findCallback, + mergePineOptions, + notFoundResponse, + noDeviceForKeyResponse, + treatAsMissingDevice, + LOCKED_STATUS_CODE, + timeSince +} = require('../util') { normalizeDeviceOsVersion } = require('../util/device-os-version') # The min version where /apps API endpoints are implemented is 1.8.0 but we'll @@ -1297,7 +1307,7 @@ getDeviceModel = (deps, opts) -> exports.register = (applicationNameOrId, uuid, callback) -> Promise.props userId: auth.getUserId() - apiKey: applicationModel().getApiKey(applicationNameOrId) + apiKey: applicationModel().generateProvisioningKey(applicationNameOrId) application: applicationModel().get(applicationNameOrId, select: ['id', 'device_type']) .then ({ userId, apiKey, application }) -> @@ -1344,14 +1354,7 @@ getDeviceModel = (deps, opts) -> url: "/api-key/device/#{deviceId}/device-key" baseUrl: apiUrl .get('body') - .catch( - { - code: 'ResinRequestError' - statusCode: 500 - body: 'No device found to associate with the api key' - } - treatAsMissingDevice(uuidOrId) - ) + .catch(noDeviceForKeyResponse, treatAsMissingDevice(uuidOrId)) .asCallback(callback) ###* diff --git a/lib/util/index.coffee b/lib/util/index.coffee index 060c1f130..5cd04b5cf 100644 --- a/lib/util/index.coffee +++ b/lib/util/index.coffee @@ -56,6 +56,11 @@ exports.notFoundResponse = code: 'ResinRequestError' statusCode: 404 +exports.noDeviceForKeyResponse = + code: 'ResinRequestError' + statusCode: 500 + body: 'No device found to associate with the api key' + exports.noApplicationForKeyResponse = code: 'ResinRequestError' statusCode: 500 From 116762c7d3b07bc8c0ec2bf5c01860ec1e75c884 Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Tue, 10 Oct 2017 13:56:34 +0200 Subject: [PATCH 10/18] *BREAKING*: Stop actively supporting node 4. Node 4 may well still work with the SDK for quite a while, but we'll no longer actively test against it, and it's quite possible that it may stop working entirely in any future release. Change-Type: major --- .travis.yml | 2 -- README.md | 3 ++- appveyor.yml | 4 ++-- package.json | 5 ++++- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 86cdb85b2..227f96e2d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,8 +14,6 @@ matrix: - '6' env: - 'CAN_DEPLOY=true' - - node_js: - - '4' before_install: - npm -g install npm@4 script: diff --git a/README.md b/README.md index 11f2d715e..a8e45cc42 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,8 @@ $ npm install --save resin-sdk Platforms --------- -We currently support NodeJS and the browser. +We currently support NodeJS (6+) and the browser. + The following features are node-only: - OS image streaming download (`resin.models.os.download`), - resin settings client (`resin.settings`). diff --git a/appveyor.yml b/appveyor.yml index 49a7af57f..3ca352f53 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,13 +14,13 @@ matrix: # what combinations to test environment: matrix: - - nodejs_version: 6 + - nodejs_version: 8 RESINTEST_EMAIL: 'test2+juan@resin.io' RESINTEST_USERNAME: 'test2_juan' RESINTEST_USERID: 5616 RESINTEST_REGISTER_EMAIL: 'test2+register+juan@resin.io' RESINTEST_REGISTER_USERNAME: 'test2_register_juan' - - nodejs_version: 4 + - nodejs_version: 6 RESINTEST_EMAIL: 'test3+juan@resin.io' RESINTEST_USERNAME: 'test3_juan' RESINTEST_USERID: 8717 diff --git a/package.json b/package.json index 4f4dbace2..578725334 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,9 @@ }, "author": "Juan Cruz Viotti ", "license": "Apache-2.0", + "engines": { + "node": ">=6.0" + }, "devDependencies": { "browserify": "^14.3.0", "catch-uncommitted": "^1.0.0", @@ -79,4 +82,4 @@ "resin-token": "^4.0.0", "semver": "^5.3.0" } -} \ No newline at end of file +} From 10166ee01746cffc73a2b64da29235810318d854 Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Tue, 26 Sep 2017 14:02:15 +0200 Subject: [PATCH 11/18] Ignore all .env files --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 871a42f3e..11aaa5cd1 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,7 @@ node_modules .DS_Store -.env +.env* .vscode # Ignore all build output From 0059047cfd8f3505b6999484e17c01a2fa3f1567 Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Wed, 11 Oct 2017 10:59:24 +0200 Subject: [PATCH 12/18] *BREAKING*: Tie the SDK to a specific API version (removing `apiVersion` option) Change-Type: major --- DOCUMENTATION.md | 1 - README.md | 1 - lib/resin.coffee | 5 +++-- tests/integration/setup.coffee | 1 - 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 50bd22ab3..00f76dbd9 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -3708,7 +3708,6 @@ startup and before any calls to `fromSharedOptions()` are made. resin.setSharedOptions({ apiUrl: 'https://api.resin.io/', imageMakerUrl: 'https://img.resin.io/', - apiVersion: 'v2', isBrowser: true, }); ``` diff --git a/README.md b/README.md index a8e45cc42..26a33c6e0 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,6 @@ var resin = require('resin-sdk')({ Where the factory method accepts the following options: * `apiUrl`, string, *optional*, is the resin.io API url. Defaults to `https://api.resin.io/`, -* `apiVersion`, string, *optional*, is the version of the API to talk to, like `v2`. Defaults to the current stable version: `v2`, * `apiKey`, string, *optional*, is the API key to make the requests with, * `imageMakerUrl`, string, *optional*, is the resin.io image maker url. Defaults to `https://img.resin.io/`, * `dataDirectory`, string, *optional*, *ignored in the browser*, is the directory where the user settings are stored, normally retrieved like `require('resin-settings-client').get('dataDirectory')`. Defaults to `$HOME/.resin`, diff --git a/lib/resin.coffee b/lib/resin.coffee index 8ede5d8ff..8056b7be4 100644 --- a/lib/resin.coffee +++ b/lib/resin.coffee @@ -78,9 +78,11 @@ getSdk = (opts = {}) -> defaults opts, apiUrl: 'https://api.resin.io/' imageMakerUrl: 'https://img.resin.io/' - apiVersion: 'v2' isBrowser: window? + # You cannot externally set the API version (as SDK implementation depends on it) + opts.apiVersion = 'v2' + if opts.isBrowser settings = get: notImplemented @@ -255,7 +257,6 @@ getSdk = (opts = {}) -> # resin.setSharedOptions({ # apiUrl: 'https://api.resin.io/', # imageMakerUrl: 'https://img.resin.io/', -# apiVersion: 'v2', # isBrowser: true, # }); ### diff --git a/tests/integration/setup.coffee b/tests/integration/setup.coffee index f2bc1287b..60c97a206 100644 --- a/tests/integration/setup.coffee +++ b/tests/integration/setup.coffee @@ -23,7 +23,6 @@ else dataDirectory: settings.get('dataDirectory') _.assign opts, - apiVersion: 'v2' apiKey: null isBrowser: IS_BROWSER, retries: 3 From 7974dc2b9d3415cf9b66a3451a1621c65c7376f9 Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Thu, 28 Sep 2017 17:51:04 +0200 Subject: [PATCH 13/18] *BREAKING*: Upgrade to API v3. Main change is that all relationships & result properties now include verbs (e.g. device.application is now device.belongs_to__application). Change-Type: major --- DOCUMENTATION.md | 2 +- lib/models/application.coffee | 14 ++++---- lib/models/build.coffee | 2 +- lib/models/device.coffee | 34 +++++++++---------- lib/models/environment-variables.coffee | 2 +- lib/resin.coffee | 4 +-- .../models/application.spec.coffee | 6 ++-- tests/integration/models/device.spec.coffee | 14 ++++---- 8 files changed, 39 insertions(+), 39 deletions(-) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 00f76dbd9..60eb8a5e9 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -234,7 +234,7 @@ in the SDK. resin.pine.get({ resource: 'build/$count', options: { - filter: { application: applicationId } + filter: { belongs_to__application: applicationId } } }); ``` diff --git a/lib/models/application.coffee b/lib/models/application.coffee index d14e521a2..619ba42c1 100644 --- a/lib/models/application.coffee +++ b/lib/models/application.coffee @@ -55,8 +55,8 @@ getApplicationModel = (deps, opts) -> exports._getId = getId normalizeApplication = (application) -> - if isArray(application.device) - forEach application.device, (device) -> + if isArray(application.owns__device) + forEach application.owns__device, (device) -> normalizeDeviceOsVersion(device) return application @@ -354,7 +354,7 @@ getApplicationModel = (deps, opts) -> throw new errors.ResinDiscontinuedDeviceType(deviceType) extraOptions = if parentApplication - application: parentApplication.id + depends_on__application: parentApplication.id else {} return pine.post @@ -640,7 +640,7 @@ getApplicationModel = (deps, opts) -> is_web_accessible: true options: filter: - application: id + belongs_to__application: id .asCallback(callback) ###* @@ -672,7 +672,7 @@ getApplicationModel = (deps, opts) -> is_web_accessible: false options: filter: - application: id + belongs_to__application: id .asCallback(callback) ###* @@ -705,7 +705,7 @@ getApplicationModel = (deps, opts) -> return pine.patch resource: 'application' id: applicationId - body: support_expiry_date: expiryTimestamp + body: is_accessible_by_support_until__date: expiryTimestamp .catch(notFoundResponse, treatAsMissingApplication(nameOrId)) .asCallback(callback) @@ -735,7 +735,7 @@ getApplicationModel = (deps, opts) -> return pine.patch resource: 'application' id: applicationId - body: support_expiry_date: null + body: is_accessible_by_support_until__date: null .catch(notFoundResponse, treatAsMissingApplication(nameOrId)) .asCallback(callback) diff --git a/lib/models/build.coffee b/lib/models/build.coffee index 363a7dc4d..ace9ae8cf 100644 --- a/lib/models/build.coffee +++ b/lib/models/build.coffee @@ -98,7 +98,7 @@ getBuildModel = (deps, opts) -> options: mergePineOptions filter: - application: id + belongs_to__application: id select: [ 'id' 'created_at' diff --git a/lib/models/device.coffee b/lib/models/device.coffee index 614cc0bce..fe3db621d 100644 --- a/lib/models/device.coffee +++ b/lib/models/device.coffee @@ -198,7 +198,7 @@ getDeviceModel = (deps, opts) -> applicationModel().get(nameOrId, select: 'id').then ({ id }) -> exports.getAll(mergePineOptions( - filter: application: id + filter: belongs_to__application: id options ), callback) @@ -235,7 +235,7 @@ getDeviceModel = (deps, opts) -> exports.get(parentUuidOrId, select: 'id').then ({ id }) -> exports.getAll(mergePineOptions( - filter: device: id + filter: is_managed_by__device: id options ), callback) @@ -393,9 +393,9 @@ getDeviceModel = (deps, opts) -> exports.getApplicationName = (uuidOrId, callback) -> exports.get uuidOrId, select: 'id' - expand: application: $select: 'app_name' + expand: belongs_to__application: $select: 'app_name' .then (device) -> - device.application[0].app_name + device.belongs_to__application[0].app_name .asCallback(callback) ###* @@ -428,7 +428,7 @@ getDeviceModel = (deps, opts) -> exports.getApplicationInfo = (uuidOrId, callback) -> exports.get(uuidOrId).then (device) -> ensureSupervisorCompatibility(device.supervisor_version, MIN_SUPERVISOR_APPS_API).then -> - appId = device.application[0].id + appId = device.belongs_to__application[0].id return request.send method: 'POST' url: "/supervisor/v1/apps/#{appId}" @@ -782,7 +782,7 @@ getDeviceModel = (deps, opts) -> return pine.patch resource: 'device' body: - application: application.id + belongs_to__application: application.id options: filter: uuid: device.uuid @@ -819,7 +819,7 @@ getDeviceModel = (deps, opts) -> exports.startApplication = (uuidOrId, callback) -> exports.get(uuidOrId).then (device) -> ensureSupervisorCompatibility(device.supervisor_version, MIN_SUPERVISOR_APPS_API).then -> - appId = device.application[0].id + appId = device.belongs_to__application[0].id return request.send method: 'POST' url: "/supervisor/v1/apps/#{appId}/start" @@ -862,7 +862,7 @@ getDeviceModel = (deps, opts) -> exports.stopApplication = (uuidOrId, callback) -> exports.get(uuidOrId).then (device) -> ensureSupervisorCompatibility(device.supervisor_version, MIN_SUPERVISOR_APPS_API).then -> - appId = device.application[0].id + appId = device.belongs_to__application[0].id return request.send method: 'POST' url: "/supervisor/v1/apps/#{appId}/stop" @@ -989,7 +989,7 @@ getDeviceModel = (deps, opts) -> baseUrl: apiUrl body: deviceId: device.id - appId: device.application[0].id + appId: device.belongs_to__application[0].id data: force: Boolean(options.force) .catch (err) -> @@ -1031,9 +1031,9 @@ getDeviceModel = (deps, opts) -> baseUrl: apiUrl body: deviceId: device.id - appId: device.application[0].id + appId: device.belongs_to__application[0].id data: - appId: device.application[0].id + appId: device.belongs_to__application[0].id .catch (err) -> if err.statusCode == LOCKED_STATUS_CODE throw new errors.ResinSupervisorLockedError() @@ -1078,7 +1078,7 @@ getDeviceModel = (deps, opts) -> baseUrl: apiUrl body: deviceId: device.id - appId: device.application[0].id + appId: device.belongs_to__application[0].id data: force: Boolean(options.force) .asCallback(callback) @@ -1530,7 +1530,7 @@ getDeviceModel = (deps, opts) -> baseUrl: apiUrl data: deviceId: device.id - appId: device.application[0].id + appId: device.belongs_to__application[0].id .get('body') .asCallback(callback) @@ -1567,7 +1567,7 @@ getDeviceModel = (deps, opts) -> baseUrl: apiUrl data: deviceId: device.id - appId: device.application[0].id + appId: device.belongs_to__application[0].id .get('body') .asCallback(callback) @@ -1604,7 +1604,7 @@ getDeviceModel = (deps, opts) -> body: method: 'GET' deviceId: device.id - appId: device.application[0].id + appId: device.belongs_to__application[0].id .asCallback(callback) ###* @@ -1664,7 +1664,7 @@ getDeviceModel = (deps, opts) -> return pine.patch resource: 'device' id: id - body: support_expiry_date: expiryTimestamp + body: is_accessible_by_support_until__date: expiryTimestamp .asCallback(callback) ###* @@ -1693,7 +1693,7 @@ getDeviceModel = (deps, opts) -> return pine.patch resource: 'device' id: id - body: support_expiry_date: null + body: is_accessible_by_support_until__date: null .asCallback(callback) ###* diff --git a/lib/models/environment-variables.coffee b/lib/models/environment-variables.coffee index fb6bcc7f6..c7b13cc3c 100644 --- a/lib/models/environment-variables.coffee +++ b/lib/models/environment-variables.coffee @@ -270,7 +270,7 @@ getEnvironmentVariablesModel = (deps, opts) -> device: $any: $alias: 'd', - $expr: d: application: id + $expr: d: belongs_to__application: id orderby: 'env_var_name asc' .map(fixDeviceEnvVarNameKey) .asCallback(callback) diff --git a/lib/resin.coffee b/lib/resin.coffee index 8056b7be4..065596fde 100644 --- a/lib/resin.coffee +++ b/lib/resin.coffee @@ -81,7 +81,7 @@ getSdk = (opts = {}) -> isBrowser: window? # You cannot externally set the API version (as SDK implementation depends on it) - opts.apiVersion = 'v2' + opts.apiVersion = 'v3' if opts.isBrowser settings = @@ -207,7 +207,7 @@ getSdk = (opts = {}) -> # resin.pine.get({ # resource: 'build/$count', # options: { - # filter: { application: applicationId } + # filter: { belongs_to__application: applicationId } # } # }); ### diff --git a/tests/integration/models/application.spec.coffee b/tests/integration/models/application.spec.coffee index a2e342ff5..72d2f7ae7 100644 --- a/tests/integration/models/application.spec.coffee +++ b/tests/integration/models/application.spec.coffee @@ -40,7 +40,7 @@ describe 'Application Model', -> .then -> resin.models.application.getAll() .then ([ parentApplication, childApplication ]) -> - m.chai.expect(childApplication.application.__id).to.equal(parentApplication.id) + m.chai.expect(childApplication.depends_on__application.__id).to.equal(parentApplication.id) it 'should be rejected if the device type is invalid', -> promise = resin.models.application.create('FooBar', 'foobarbaz') @@ -276,7 +276,7 @@ describe 'Application Model', -> .then => resin.models.application.get(@application.id) .then (app) -> - Date.parse(app.support_expiry_date) + Date.parse(app.is_accessible_by_support_until__date) m.chai.expect(promise).to.eventually.equal(expiryTime) @@ -289,7 +289,7 @@ describe 'Application Model', -> .then => resin.models.application.get(@application.id) .then (app) -> - app.support_expiry_date + app.is_accessible_by_support_until__date m.chai.expect(promise).to.eventually.equal(null) diff --git a/tests/integration/models/device.spec.coffee b/tests/integration/models/device.spec.coffee index f004770f7..f80bc43e2 100644 --- a/tests/integration/models/device.spec.coffee +++ b/tests/integration/models/device.spec.coffee @@ -244,11 +244,11 @@ describe 'Device Model', -> resin.pine.post resource: 'device' body: - user: userId - application: @childApplication.id + belongs_to__user: userId + belongs_to__application: @childApplication.id device_type: @childApplication.device_type uuid: resin.models.device.generateUniqueKey() - device: @device.id + is_managed_by__device: @device.id .then (device) => @childDevice = device @@ -738,8 +738,8 @@ describe 'Device Model', -> promise = resin.models.device.grantSupportAccess(@device.id, expiryTimestamp) .then => resin.models.device.get(@device.id) - .then ({ support_expiry_date }) -> - Date.parse(support_expiry_date) + .then ({ is_accessible_by_support_until__date }) -> + Date.parse(is_accessible_by_support_until__date) m.chai.expect(promise).to.eventually.equal(expiryTimestamp) @@ -750,8 +750,8 @@ describe 'Device Model', -> resin.models.device.revokeSupportAccess(@device.id) .then => resin.models.device.get(@device.id) - .then ({ support_expiry_date }) -> - m.chai.expect(support_expiry_date).to.be.null + .then ({ is_accessible_by_support_until__date }) -> + m.chai.expect(is_accessible_by_support_until__date).to.be.null describe 'given a single application with a device id whose shorter uuid is only numbers', -> From c0e9e7c98919adfffd827da1c528b4c3acb5da08 Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Thu, 12 Oct 2017 16:27:19 +0200 Subject: [PATCH 14/18] Fix device interacting methods broken by non-automatic relationships --- lib/models/device.coffee | 45 ++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/lib/models/device.coffee b/lib/models/device.coffee index fe3db621d..ecce38a8b 100644 --- a/lib/models/device.coffee +++ b/lib/models/device.coffee @@ -426,7 +426,10 @@ getDeviceModel = (deps, opts) -> # }); ### exports.getApplicationInfo = (uuidOrId, callback) -> - exports.get(uuidOrId).then (device) -> + exports.get uuidOrId, + select: ['id', 'supervisor_version'] + expand: belongs_to__application: $select: 'id' + .then (device) -> ensureSupervisorCompatibility(device.supervisor_version, MIN_SUPERVISOR_APPS_API).then -> appId = device.belongs_to__application[0].id return request.send @@ -817,7 +820,10 @@ getDeviceModel = (deps, opts) -> # }); ### exports.startApplication = (uuidOrId, callback) -> - exports.get(uuidOrId).then (device) -> + exports.get uuidOrId, + select: ['id', 'supervisor_version'] + expand: belongs_to__application: $select: 'id' + .then (device) -> ensureSupervisorCompatibility(device.supervisor_version, MIN_SUPERVISOR_APPS_API).then -> appId = device.belongs_to__application[0].id return request.send @@ -860,7 +866,10 @@ getDeviceModel = (deps, opts) -> # }); ### exports.stopApplication = (uuidOrId, callback) -> - exports.get(uuidOrId).then (device) -> + exports.get uuidOrId, + select: ['id', 'supervisor_version'] + expand: belongs_to__application: $select: 'id' + .then (device) -> ensureSupervisorCompatibility(device.supervisor_version, MIN_SUPERVISOR_APPS_API).then -> appId = device.belongs_to__application[0].id return request.send @@ -982,7 +991,10 @@ getDeviceModel = (deps, opts) -> exports.shutdown = (uuidOrId, options = {}, callback) -> callback = findCallback(arguments) - exports.get(uuidOrId).then (device) -> + exports.get uuidOrId, + select: 'id' + expand: belongs_to__application: $select: 'id' + .then (device) -> return request.send method: 'POST' url: '/supervisor/v1/shutdown' @@ -1024,7 +1036,10 @@ getDeviceModel = (deps, opts) -> # }); ### exports.purge = (uuidOrId, callback) -> - exports.get(uuidOrId).then (device) -> + exports.get uuidOrId, + select: 'id' + expand: belongs_to__application: $select: 'id' + .then (device) -> return request.send method: 'POST' url: '/supervisor/v1/purge' @@ -1071,7 +1086,10 @@ getDeviceModel = (deps, opts) -> # }); ### exports.update = (uuidOrId, options, callback) -> - exports.get(uuidOrId).then (device) -> + exports.get uuidOrId, + select: 'id' + expand: belongs_to__application: $select: 'id' + .then (device) -> return request.send method: 'POST' url: '/supervisor/v1/update' @@ -1523,7 +1541,10 @@ getDeviceModel = (deps, opts) -> # }); ### exports.enableTcpPing = (uuidOrId, callback) -> - exports.get(uuidOrId).then (device) -> + exports.get uuidOrId, + select: 'id' + expand: belongs_to__application: $select: 'id' + .then (device) -> return request.send method: 'POST' url: '/supervisor/v1/tcp-ping' @@ -1560,7 +1581,10 @@ getDeviceModel = (deps, opts) -> # }); ### exports.disableTcpPing = (uuidOrId, callback) -> - exports.get(uuidOrId).then (device) -> + exports.get uuidOrId, + select: 'id' + expand: belongs_to__application: $select: 'id' + .then (device) -> return request.send method: 'DELETE' url: '/supervisor/v1/tcp-ping' @@ -1596,7 +1620,10 @@ getDeviceModel = (deps, opts) -> # }); ### exports.ping = (uuidOrId, callback) -> - exports.get(uuidOrId).then (device) -> + exports.get uuidOrId, + select: 'id' + expand: belongs_to__application: $select: 'id' + .then (device) -> return request.send method: 'POST' url: '/supervisor/ping' From 8e74381aa8918aab848ff5f469c4b485391329cc Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Thu, 12 Oct 2017 16:28:09 +0200 Subject: [PATCH 15/18] Make device.update options optional Change-Type: patch --- lib/models/device.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/models/device.coffee b/lib/models/device.coffee index ecce38a8b..c6f0c4139 100644 --- a/lib/models/device.coffee +++ b/lib/models/device.coffee @@ -1085,7 +1085,9 @@ getDeviceModel = (deps, opts) -> # if (error) throw error; # }); ### - exports.update = (uuidOrId, options, callback) -> + exports.update = (uuidOrId, options = {}, callback) -> + callback = findCallback(arguments) + exports.get uuidOrId, select: 'id' expand: belongs_to__application: $select: 'id' From b949de69a4823d348a8042d7232427077faef55c Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Thu, 12 Oct 2017 16:28:40 +0200 Subject: [PATCH 16/18] Fix breaking bugs in device.enable/disableTcpPing Change-Type: patch --- lib/models/device.coffee | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/models/device.coffee b/lib/models/device.coffee index c6f0c4139..92ad14d83 100644 --- a/lib/models/device.coffee +++ b/lib/models/device.coffee @@ -1551,7 +1551,7 @@ getDeviceModel = (deps, opts) -> method: 'POST' url: '/supervisor/v1/tcp-ping' baseUrl: apiUrl - data: + body: deviceId: device.id appId: device.belongs_to__application[0].id .get('body') @@ -1588,10 +1588,11 @@ getDeviceModel = (deps, opts) -> expand: belongs_to__application: $select: 'id' .then (device) -> return request.send - method: 'DELETE' + method: 'POST' url: '/supervisor/v1/tcp-ping' baseUrl: apiUrl - data: + body: + method: 'DELETE' deviceId: device.id appId: device.belongs_to__application[0].id .get('body') From ea7e818f963c46554405248190362a073d75d3f6 Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Thu, 12 Oct 2017 16:29:03 +0200 Subject: [PATCH 17/18] *BREAKING*: Remove device.ensureSupervisorCompatibility - use semver directly instead Change-Type: major --- lib/models/device.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/models/device.coffee b/lib/models/device.coffee index 92ad14d83..b0bc7f275 100644 --- a/lib/models/device.coffee +++ b/lib/models/device.coffee @@ -101,7 +101,7 @@ getDeviceModel = (deps, opts) -> # console.log('Is compatible'); # }); ### - exports.ensureSupervisorCompatibility = ensureSupervisorCompatibility = Promise.method (version, minVersion) -> + ensureSupervisorCompatibility = Promise.method (version, minVersion) -> if semver.lt(version, minVersion) throw new Error("Incompatible supervisor version: #{version} - must be >= #{minVersion}") From b446b46d7f59fa5bfa73f2baa72757fb51bcd9da Mon Sep 17 00:00:00 2001 From: "resin-io-versionbot[bot]" Date: Thu, 12 Oct 2017 15:02:20 +0000 Subject: [PATCH 18/18] v7.0.0 --- CHANGELOG.md | 17 +++++++++++++++++ package.json | 4 ++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85839dead..7685e8be2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY! This project adheres to [Semantic Versioning](http://semver.org/). +## v7.0.0 - 2017-10-12 + +* *BREAKING*: Remove device.ensureSupervisorCompatibility - use semver directly instead #420 [Tim Perry] +* Fix breaking bugs in device.enable/disableTcpPing #420 [Tim Perry] +* Make device.update options optional #420 [Tim Perry] +* *BREAKING*: Upgrade to API v3. Main change is that all relationships & result properties now include verbs (e.g. device.application is now device.belongs_to__application). #420 [Tim Perry] +* *BREAKING*: Tie the SDK to a specific API version (removing `apiVersion` option) #420 [Tim Perry] +* *BREAKING*: Stop actively supporting node 4. #420 [Tim Perry] +* Change device registration to use a provisioning key #420 [Tim Perry] +* *BREAKING*: Remove (already deprecated) models.application.getApiKey() #420 [Tim Perry] +* *BREAKING*: Rename getAppWithOwner to getAppByOwner #420 [Tim Perry] +* *BREAKING*: Don't allow creating applications with discontinued device types #420 [Tim Perry] +* Make device.move throw ResinInvalidDeviceType for incompatible device types (not just Error) #420 [Tim Perry] +* *BREAKING*: Don't expand relationships by default. Pass { expand: '...' } options to opt in instead. #420 [Tim Perry] +* *BREAKING*: Remove device.application_name and device.dashboard_url #420 [Tim Perry] +* *BREAKING*: Remove application.online_devices and application.device_length #420 [Tim Perry] + ## v6.15.0 - 2017-10-12 * Add application.generateProvisioningKey() #419 [Tim Perry] diff --git a/package.json b/package.json index 578725334..4b2805cf9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "resin-sdk", - "version": "6.15.0", + "version": "7.0.0", "description": "The Resin.io JavaScript SDK", "main": "build/resin.js", "homepage": "https://github.com/resin-io/resin-sdk", @@ -82,4 +82,4 @@ "resin-token": "^4.0.0", "semver": "^5.3.0" } -} +} \ No newline at end of file