ember-browser-services 4.0.4 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # ember-browser-services
2
2
 
3
+ ## 5.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - [#397](https://github.com/CrowdStrike/ember-browser-services/pull/397) [`606e0f8fe4e6ef3ff527cb432c65af2fb9d631d4`](https://github.com/CrowdStrike/ember-browser-services/commit/606e0f8fe4e6ef3ff527cb432c65af2fb9d631d4) Thanks [@simonihmig](https://github.com/simonihmig)! - Drop support for Ember < 4.8
8
+
9
+ - [#399](https://github.com/CrowdStrike/ember-browser-services/pull/399) [`562c673596fdcad78a4f7f5b89877b2ff3a18073`](https://github.com/CrowdStrike/ember-browser-services/commit/562c673596fdcad78a4f7f5b89877b2ff3a18073) Thanks [@simonihmig](https://github.com/simonihmig)! - Update ember-window-mock, drop unneeded glue code
10
+
11
+ There is a potentially breaking change, as you cannot mock `window.location.origin` directly anymore. But this should not restrict you, as you can set `window.location.href`, and `origin` will be correctly reflected. Having `origin` not be aligned with `href` can never happen in reality, since `origin` is a read-only property, so having these diverge in tests is not really useful.
12
+
3
13
  ## 4.0.4
4
14
 
5
15
  ### Patch Changes
package/README.md CHANGED
@@ -25,7 +25,7 @@ looking at the documentation.
25
25
 
26
26
  ## Compatibility
27
27
 
28
- * Ember.js v3.12 or above
28
+ * Ember.js v4.8 or above
29
29
  * ember-auto-import v2 or above
30
30
  * typescript v4.5 or above
31
31
  * embroider max-compat and strict modes
@@ -1 +1 @@
1
- {"version":3,"file":"-proxy-service.js","sources":["../../../src/services/browser/-proxy-service.ts"],"sourcesContent":["import Service from '@ember/service';\n\nimport type { Class } from '../../types';\n\n/**\n * Allows Services to behave as Proxy objects for real objects, such as\n * window, document, navigator, Worker, etc.\n *\n * useful for consistently accessing unmockable objects and then replacing them\n * with fakes in testing.\n *\n * would it be worth recursively wrapping in a proxy for any reason?\n *\n * NOTE: This only works for one layer deep of properties\n *\n * @param {Object | Class} browserObject - the api to wrap a service around.\n */\nexport function proxyService<BrowserAPI>(\n ObjectToProxy: BrowserAPI | Class<BrowserAPI>\n): Service & BrowserAPI {\n type ProxyKey = BrowserAPI | Service;\n type CreateMethod = (typeof Service)['create'];\n\n // extending the types for the static method create is too hard / impossible\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let UnTypedService = Service as any;\n\n function instanceHandlerFor(browserObject: BrowserAPI) {\n return {\n get<K extends keyof ProxyKey>(\n targetInstance: Service,\n prop: K,\n receiver: unknown\n ) {\n if (prop in targetInstance) {\n return Reflect.get(targetInstance, prop, receiver);\n }\n\n let value = browserObject[prop];\n\n if (typeof value === 'function') {\n // prevents the error \"Illegal Invocation\"\n // which can sometimes happen due to losing the \"this\" depending on\n // the invocation context at the call site\n return value.bind(browserObject);\n }\n\n return value;\n },\n set<K extends keyof ProxyKey>(\n targetInstance: Service,\n prop: K,\n value: BrowserAPI[K],\n receiver: unknown\n ) {\n if (prop in targetInstance) {\n Reflect.set(targetInstance, prop, value, receiver);\n }\n\n browserObject[prop] = value;\n\n return true;\n },\n };\n }\n\n function isConstructable(\n proxyTo: BrowserAPI | Class<BrowserAPI>\n ): proxyTo is Class<BrowserAPI> {\n return typeof proxyTo === 'function';\n }\n\n // We have to untype the Service, because...\n // this is nuts:\n // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/da0e5b5/types/ember__object/core.d.ts#L82-L94\n //\n // it's also all private, and the ember-TS team apparently didn't think people would want to do this :D\n class ProxyCreator extends UnTypedService {\n // https://github.com/emberjs/ember.js/blob/master/packages/%40ember/service/index.js#L66-L74\n // https://github.com/emberjs/ember.js/blob/f85cefe9855b2521b02800d4bb2b68da7db2a214/packages/%40ember/service/index.js#L68-L72\n static isServiceFactory = true;\n\n static create(\n injections: Parameters<CreateMethod>\n ): ReturnType<CreateMethod> {\n let serviceInstance = class ProxiedService extends Service {\n // @private\n declare __browser_object__: BrowserAPI;\n /*\n * We cannot create the base Service, we must use a new one.\n * If we don't, we are unable to run tests in a legacy qunit environment\n * due to \"writableChains\" issues.\n *\n * https://github.com/emberjs/ember.js/pull/15347/files#diff-7e13eecefe753df1d82ce67b32bc4366R361\n *\n * */\n }.create(injections);\n\n let browserObject = isConstructable(ObjectToProxy)\n ? new ObjectToProxy()\n : ObjectToProxy;\n\n serviceInstance.__browser_object__ = browserObject;\n\n return new Proxy(serviceInstance, instanceHandlerFor(browserObject));\n }\n\n constructor(...args: unknown[]) {\n super(...args);\n throw new Error('ProxyCreator is not new-able');\n }\n }\n\n return ProxyCreator as unknown as Service & BrowserAPI;\n}\n"],"names":["proxyService","ObjectToProxy","UnTypedService","Service","instanceHandlerFor","browserObject","get","targetInstance","prop","receiver","Reflect","value","bind","set","isConstructable","proxyTo","ProxyCreator","isServiceFactory","create","injections","serviceInstance","ProxiedService","__browser_object__","Proxy","constructor","args","Error"],"mappings":";;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASA,YAAY,CAC1BC,aAA6C,EACvB;AAItB;AACA;EACA,IAAIC,cAAc,GAAGC,OAAc,CAAA;EAEnC,SAASC,kBAAkB,CAACC,aAAyB,EAAE;IACrD,OAAO;AACLC,MAAAA,GAAG,CACDC,cAAuB,EACvBC,IAAO,EACPC,QAAiB,EACjB;QACA,IAAID,IAAI,IAAID,cAAc,EAAE;UAC1B,OAAOG,OAAO,CAACJ,GAAG,CAACC,cAAc,EAAEC,IAAI,EAAEC,QAAQ,CAAC,CAAA;AACpD,SAAA;AAEA,QAAA,IAAIE,KAAK,GAAGN,aAAa,CAACG,IAAI,CAAC,CAAA;AAE/B,QAAA,IAAI,OAAOG,KAAK,KAAK,UAAU,EAAE;AAC/B;AACA;AACA;AACA,UAAA,OAAOA,KAAK,CAACC,IAAI,CAACP,aAAa,CAAC,CAAA;AAClC,SAAA;AAEA,QAAA,OAAOM,KAAK,CAAA;OACb;MACDE,GAAG,CACDN,cAAuB,EACvBC,IAAO,EACPG,KAAoB,EACpBF,QAAiB,EACjB;QACA,IAAID,IAAI,IAAID,cAAc,EAAE;UAC1BG,OAAO,CAACG,GAAG,CAACN,cAAc,EAAEC,IAAI,EAAEG,KAAK,EAAEF,QAAQ,CAAC,CAAA;AACpD,SAAA;AAEAJ,QAAAA,aAAa,CAACG,IAAI,CAAC,GAAGG,KAAK,CAAA;AAE3B,QAAA,OAAO,IAAI,CAAA;AACb,OAAA;KACD,CAAA;AACH,GAAA;EAEA,SAASG,eAAe,CACtBC,OAAuC,EACT;IAC9B,OAAO,OAAOA,OAAO,KAAK,UAAU,CAAA;AACtC,GAAA;;AAEA;AACA;AACA;AACA;AACA;EACA,MAAMC,YAAY,SAASd,cAAc,CAAC;AACxC;AACA;IACA,OAAOe,gBAAgB,GAAG,IAAI,CAAA;IAE9B,OAAOC,MAAM,CACXC,UAAoC,EACV;AAC1B,MAAA,IAAIC,eAAe,GAAG,MAAMC,cAAc,SAASlB,OAAO,CAAC,EAW1D,CAACe,MAAM,CAACC,UAAU,CAAC,CAAA;MAEpB,IAAId,aAAa,GAAGS,eAAe,CAACb,aAAa,CAAC,GAC9C,IAAIA,aAAa,EAAE,GACnBA,aAAa,CAAA;MAEjBmB,eAAe,CAACE,kBAAkB,GAAGjB,aAAa,CAAA;MAElD,OAAO,IAAIkB,KAAK,CAACH,eAAe,EAAEhB,kBAAkB,CAACC,aAAa,CAAC,CAAC,CAAA;AACtE,KAAA;IAEAmB,WAAW,CAAC,GAAGC,IAAe,EAAE;MAC9B,KAAK,CAAC,GAAGA,IAAI,CAAC,CAAA;AACd,MAAA,MAAM,IAAIC,KAAK,CAAC,8BAA8B,CAAC,CAAA;AACjD,KAAA;AACF,GAAA;AAEA,EAAA,OAAOV,YAAY,CAAA;AACrB;;;;"}
1
+ {"version":3,"file":"-proxy-service.js","sources":["../../../src/services/browser/-proxy-service.ts"],"sourcesContent":["import Service from '@ember/service';\n\nimport type { Class } from '../../types';\n\n/**\n * Allows Services to behave as Proxy objects for real objects, such as\n * window, document, navigator, Worker, etc.\n *\n * useful for consistently accessing unmockable objects and then replacing them\n * with fakes in testing.\n *\n * would it be worth recursively wrapping in a proxy for any reason?\n *\n * NOTE: This only works for one layer deep of properties\n *\n * @param {Object | Class} browserObject - the api to wrap a service around.\n */\nexport function proxyService<BrowserAPI>(\n ObjectToProxy: BrowserAPI | Class<BrowserAPI>\n): Service & BrowserAPI {\n type ProxyKey = BrowserAPI | Service;\n type CreateMethod = (typeof Service)['create'];\n\n // extending the types for the static method create is too hard / impossible\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let UnTypedService = Service as any;\n\n function instanceHandlerFor(browserObject: BrowserAPI) {\n return {\n get<K extends keyof ProxyKey>(\n targetInstance: Service,\n prop: K,\n receiver: unknown\n ) {\n if (prop in targetInstance) {\n return Reflect.get(targetInstance, prop, receiver);\n }\n\n let value = browserObject[prop];\n\n if (typeof value === 'function') {\n // prevents the error \"Illegal Invocation\"\n // which can sometimes happen due to losing the \"this\" depending on\n // the invocation context at the call site\n return value.bind(browserObject);\n }\n\n return value;\n },\n set<K extends keyof ProxyKey>(\n targetInstance: Service,\n prop: K,\n value: BrowserAPI[K],\n receiver: unknown\n ) {\n if (prop in targetInstance) {\n Reflect.set(targetInstance, prop, value, receiver);\n }\n\n browserObject[prop] = value;\n\n return true;\n },\n };\n }\n\n function isConstructable(\n proxyTo: BrowserAPI | Class<BrowserAPI>\n ): proxyTo is Class<BrowserAPI> {\n return typeof proxyTo === 'function';\n }\n\n // We have to untype the Service, because...\n // this is nuts:\n // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/da0e5b5/types/ember__object/core.d.ts#L82-L94\n //\n // it's also all private, and the ember-TS team apparently didn't think people would want to do this :D\n class ProxyCreator extends UnTypedService {\n // https://github.com/emberjs/ember.js/blob/master/packages/%40ember/service/index.js#L66-L74\n // https://github.com/emberjs/ember.js/blob/f85cefe9855b2521b02800d4bb2b68da7db2a214/packages/%40ember/service/index.js#L68-L72\n static isServiceFactory = true;\n\n static create(\n injections: Parameters<CreateMethod>\n ): ReturnType<CreateMethod> {\n let serviceInstance = class ProxiedService extends Service {\n // @private\n declare __browser_object__: BrowserAPI;\n /*\n * We cannot create the base Service, we must use a new one.\n * If we don't, we are unable to run tests in a legacy qunit environment\n * due to \"writableChains\" issues.\n *\n * https://github.com/emberjs/ember.js/pull/15347/files#diff-7e13eecefe753df1d82ce67b32bc4366R361\n *\n * */\n }.create(injections);\n\n let browserObject = isConstructable(ObjectToProxy)\n ? new ObjectToProxy()\n : ObjectToProxy;\n\n serviceInstance.__browser_object__ = browserObject;\n\n return new Proxy(serviceInstance, instanceHandlerFor(browserObject));\n }\n\n constructor(...args: unknown[]) {\n super(...args);\n throw new Error('ProxyCreator is not new-able');\n }\n }\n\n return ProxyCreator as unknown as Service & BrowserAPI;\n}\n"],"names":["proxyService","ObjectToProxy","UnTypedService","Service","instanceHandlerFor","browserObject","get","targetInstance","prop","receiver","Reflect","value","bind","set","isConstructable","proxyTo","ProxyCreator","isServiceFactory","create","injections","serviceInstance","ProxiedService","__browser_object__","Proxy","constructor","args","Error"],"mappings":";;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASA,YAAYA,CAC1BC,aAA6C,EACvB;AAItB;AACA;EACA,IAAIC,cAAc,GAAGC,OAAc,CAAA;EAEnC,SAASC,kBAAkBA,CAACC,aAAyB,EAAE;IACrD,OAAO;AACLC,MAAAA,GAAGA,CACDC,cAAuB,EACvBC,IAAO,EACPC,QAAiB,EACjB;QACA,IAAID,IAAI,IAAID,cAAc,EAAE;UAC1B,OAAOG,OAAO,CAACJ,GAAG,CAACC,cAAc,EAAEC,IAAI,EAAEC,QAAQ,CAAC,CAAA;AACpD,SAAA;AAEA,QAAA,IAAIE,KAAK,GAAGN,aAAa,CAACG,IAAI,CAAC,CAAA;AAE/B,QAAA,IAAI,OAAOG,KAAK,KAAK,UAAU,EAAE;AAC/B;AACA;AACA;AACA,UAAA,OAAOA,KAAK,CAACC,IAAI,CAACP,aAAa,CAAC,CAAA;AAClC,SAAA;AAEA,QAAA,OAAOM,KAAK,CAAA;OACb;MACDE,GAAGA,CACDN,cAAuB,EACvBC,IAAO,EACPG,KAAoB,EACpBF,QAAiB,EACjB;QACA,IAAID,IAAI,IAAID,cAAc,EAAE;UAC1BG,OAAO,CAACG,GAAG,CAACN,cAAc,EAAEC,IAAI,EAAEG,KAAK,EAAEF,QAAQ,CAAC,CAAA;AACpD,SAAA;AAEAJ,QAAAA,aAAa,CAACG,IAAI,CAAC,GAAGG,KAAK,CAAA;AAE3B,QAAA,OAAO,IAAI,CAAA;AACb,OAAA;KACD,CAAA;AACH,GAAA;EAEA,SAASG,eAAeA,CACtBC,OAAuC,EACT;IAC9B,OAAO,OAAOA,OAAO,KAAK,UAAU,CAAA;AACtC,GAAA;;AAEA;AACA;AACA;AACA;AACA;EACA,MAAMC,YAAY,SAASd,cAAc,CAAC;AACxC;AACA;IACA,OAAOe,gBAAgB,GAAG,IAAI,CAAA;IAE9B,OAAOC,MAAMA,CACXC,UAAoC,EACV;AAC1B,MAAA,IAAIC,eAAe,GAAG,MAAMC,cAAc,SAASlB,OAAO,CAAC,EAW1D,CAACe,MAAM,CAACC,UAAU,CAAC,CAAA;AAEpB,MAAA,IAAId,aAAa,GAAGS,eAAe,CAACb,aAAa,CAAC,GAC9C,IAAIA,aAAa,EAAE,GACnBA,aAAa,CAAA;MAEjBmB,eAAe,CAACE,kBAAkB,GAAGjB,aAAa,CAAA;MAElD,OAAO,IAAIkB,KAAK,CAACH,eAAe,EAAEhB,kBAAkB,CAACC,aAAa,CAAC,CAAC,CAAA;AACtE,KAAA;IAEAmB,WAAWA,CAAC,GAAGC,IAAe,EAAE;MAC9B,KAAK,CAAC,GAAGA,IAAI,CAAC,CAAA;AACd,MAAA,MAAM,IAAIC,KAAK,CAAC,8BAA8B,CAAC,CAAA;AACjD,KAAA;AACF,GAAA;AAEA,EAAA,OAAOV,YAAY,CAAA;AACrB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"web-storage.js","sources":["../../../src/test-support/-private/web-storage.ts"],"sourcesContent":["import Service from '@ember/service';\n\ntype FakeWebStorage = Record<string, string>;\n\n/**\n * Mimics the Web Storage API, as used by localStorage and sessionStorage.\n *\n */\nclass FakeWebStorageService extends Service {\n fakeWebStorage: FakeWebStorage = {};\n\n setItem(key: string, value: string): void {\n // Everything in Web Storage is a string\n this.fakeWebStorage[key] = `${value}`;\n }\n\n getItem(key: string): string | null {\n return this.fakeWebStorage[key] || null;\n }\n\n removeItem(key: string): void {\n delete this.fakeWebStorage[key];\n }\n\n clear(): void {\n this.fakeWebStorage = {};\n }\n}\n\nexport class FakeLocalStorageService extends FakeWebStorageService {}\nexport class FakeSessionStorageService extends FakeWebStorageService {}\n"],"names":["FakeWebStorageService","Service","fakeWebStorage","setItem","key","value","getItem","removeItem","clear","FakeLocalStorageService","FakeSessionStorageService"],"mappings":";;AAIA;AACA;AACA;AACA;AACA,MAAMA,qBAAqB,SAASC,OAAO,CAAC;EAC1CC,cAAc,GAAmB,EAAE,CAAA;AAEnCC,EAAAA,OAAO,CAACC,GAAW,EAAEC,KAAa,EAAQ;AACxC;IACA,IAAI,CAACH,cAAc,CAACE,GAAG,CAAC,GAAI,CAAA,EAAEC,KAAM,CAAC,CAAA,CAAA;AACvC,GAAA;EAEAC,OAAO,CAACF,GAAW,EAAiB;AAClC,IAAA,OAAO,IAAI,CAACF,cAAc,CAACE,GAAG,CAAC,IAAI,IAAI,CAAA;AACzC,GAAA;EAEAG,UAAU,CAACH,GAAW,EAAQ;AAC5B,IAAA,OAAO,IAAI,CAACF,cAAc,CAACE,GAAG,CAAC,CAAA;AACjC,GAAA;AAEAI,EAAAA,KAAK,GAAS;AACZ,IAAA,IAAI,CAACN,cAAc,GAAG,EAAE,CAAA;AAC1B,GAAA;AACF,CAAA;AAEO,MAAMO,uBAAuB,SAAST,qBAAqB,CAAC,EAAA;AAC5D,MAAMU,yBAAyB,SAASV,qBAAqB,CAAC;;;;"}
1
+ {"version":3,"file":"web-storage.js","sources":["../../../src/test-support/-private/web-storage.ts"],"sourcesContent":["import Service from '@ember/service';\n\ntype FakeWebStorage = Record<string, string>;\n\n/**\n * Mimics the Web Storage API, as used by localStorage and sessionStorage.\n *\n */\nclass FakeWebStorageService extends Service {\n fakeWebStorage: FakeWebStorage = {};\n\n setItem(key: string, value: string): void {\n // Everything in Web Storage is a string\n this.fakeWebStorage[key] = `${value}`;\n }\n\n getItem(key: string): string | null {\n return this.fakeWebStorage[key] || null;\n }\n\n removeItem(key: string): void {\n delete this.fakeWebStorage[key];\n }\n\n clear(): void {\n this.fakeWebStorage = {};\n }\n}\n\nexport class FakeLocalStorageService extends FakeWebStorageService {}\nexport class FakeSessionStorageService extends FakeWebStorageService {}\n"],"names":["FakeWebStorageService","Service","fakeWebStorage","setItem","key","value","getItem","removeItem","clear","FakeLocalStorageService","FakeSessionStorageService"],"mappings":";;AAIA;AACA;AACA;AACA;AACA,MAAMA,qBAAqB,SAASC,OAAO,CAAC;EAC1CC,cAAc,GAAmB,EAAE,CAAA;AAEnCC,EAAAA,OAAOA,CAACC,GAAW,EAAEC,KAAa,EAAQ;AACxC;IACA,IAAI,CAACH,cAAc,CAACE,GAAG,CAAC,GAAG,CAAA,EAAGC,KAAK,CAAE,CAAA,CAAA;AACvC,GAAA;EAEAC,OAAOA,CAACF,GAAW,EAAiB;AAClC,IAAA,OAAO,IAAI,CAACF,cAAc,CAACE,GAAG,CAAC,IAAI,IAAI,CAAA;AACzC,GAAA;EAEAG,UAAUA,CAACH,GAAW,EAAQ;AAC5B,IAAA,OAAO,IAAI,CAACF,cAAc,CAACE,GAAG,CAAC,CAAA;AACjC,GAAA;AAEAI,EAAAA,KAAKA,GAAS;AACZ,IAAA,IAAI,CAACN,cAAc,GAAG,EAAE,CAAA;AAC1B,GAAA;AACF,CAAA;AAEO,MAAMO,uBAAuB,SAAST,qBAAqB,CAAC,EAAA;AAC5D,MAAMU,yBAAyB,SAASV,qBAAqB,CAAC;;;;"}
@@ -3,7 +3,6 @@ import window from 'ember-window-mock';
3
3
  import { setupWindowMock } from 'ember-window-mock/test-support';
4
4
  import { proxyService } from '../services/browser/-proxy-service.js';
5
5
  import { FakeLocalStorageService, FakeSessionStorageService } from './-private/web-storage.js';
6
- import { patchWindow } from './window-mock-augments.js';
7
6
 
8
7
  function setupBrowserFakes(hooks, options) {
9
8
  setupWindowMock(hooks);
@@ -18,10 +17,7 @@ function setupBrowserFakes(hooks, options) {
18
17
  // the type for the owner keeps being wrong............
19
18
  let owner = this.owner;
20
19
  if (options.window) {
21
- // default, can still be overwritten
22
- // see: https://github.com/kaliber5/ember-window-mock/issues/175
23
- let patched = patchWindow(window);
24
- let service = maybeMake(options.window, patched);
20
+ let service = maybeMake(options.window, window);
25
21
  owner.register('service:browser/window', service);
26
22
  }
27
23
  if (options.document) {
@@ -60,11 +56,6 @@ function maybeMake(maybeImplementation, target) {
60
56
 
61
57
  // we are already using ember-window-mock, so the proxy internal to that package will
62
58
  // "just handle" setting stuff on the window
63
- //
64
- // NOTE:
65
- // - Location implementation is incomplete:
66
- // https://github.com/kaliber5/ember-window-mock/blob/2b8fbf581fc65e7f5455cd291497a3fdc2efdaf5/addon-test-support/-private/mock/location.js#L23
67
- // - does not allow setting "origin"
68
59
  function applyStub(root, partial) {
69
60
  if (!partial) return root;
70
61
  for (let key of Object.keys(partial)) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/test-support/index.ts"],"sourcesContent":["import Service from '@ember/service';\n\nimport window from 'ember-window-mock';\n\nimport { setupWindowMock } from 'ember-window-mock/test-support';\n\nimport { proxyService } from '../services/browser/-proxy-service';\nimport {\n FakeLocalStorageService,\n FakeSessionStorageService,\n} from './-private/web-storage';\nimport { patchWindow } from './window-mock-augments';\n\nimport type { RecursivePartial } from '../types';\n\ntype Fakes = {\n window?: boolean | typeof Service | RecursivePartial<Window>;\n localStorage?: boolean;\n sessionStorage?: boolean;\n document?: boolean | typeof Service | RecursivePartial<Document>;\n navigator?: boolean | RecursivePartial<Navigator>;\n};\n\nexport function setupBrowserFakes(hooks: NestedHooks, options: Fakes): void {\n setupWindowMock(hooks);\n\n // Switched to 'any' from 'TestContext' due to awkward migration period from\n // DT to built-in-types.\n // I don't know if it's possible to support both fake test-helper types and real ones\n // (simultaneously)\n //\n // Additionally, these types have no bearing on end-user behavior, so this is low risk.\n hooks.beforeEach(function (this: any) {\n // the type for the owner keeps being wrong............\n let owner = this.owner as unknown as {\n register: (name: string, thing: unknown) => void;\n unregister: (name: string) => void;\n };\n\n if (options.window) {\n // default, can still be overwritten\n // see: https://github.com/kaliber5/ember-window-mock/issues/175\n let patched = patchWindow(window);\n let service = maybeMake(options.window, patched);\n\n owner.register('service:browser/window', service);\n }\n\n if (options.document) {\n let service = maybeMake(options.document, window.document);\n\n owner.register('service:browser/document', service);\n }\n\n if (options.localStorage) {\n owner.register('service:browser/local-storage', FakeLocalStorageService);\n }\n\n if (options.sessionStorage) {\n owner.register(\n 'service:browser/session-storage',\n FakeSessionStorageService\n );\n }\n\n if (options.navigator) {\n let service = maybeMake(options.navigator, window.navigator);\n\n owner.register('service:browser/navigator', service);\n }\n });\n}\n\n// this usage of any is correct, because it literally could be *any*thing\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype UnknownObject = Record<string, any>;\n\nexport function maybeMake<\n DefaultType extends UnknownObject,\n TestClass extends UnknownObject\n>(\n maybeImplementation:\n | true\n | typeof Service\n | TestClass\n | RecursivePartial<DefaultType>,\n target: DefaultType\n): DefaultType {\n if (maybeImplementation === true) {\n return proxyService(target);\n }\n\n if (maybeImplementation.prototype instanceof Service) {\n return target;\n }\n\n if (typeof maybeImplementation === 'object') {\n applyStub(target, maybeImplementation);\n\n return proxyService(target);\n }\n\n return proxyService(target);\n}\n\n// we are already using ember-window-mock, so the proxy internal to that package will\n// \"just handle\" setting stuff on the window\n//\n// NOTE:\n// - Location implementation is incomplete:\n// https://github.com/kaliber5/ember-window-mock/blob/2b8fbf581fc65e7f5455cd291497a3fdc2efdaf5/addon-test-support/-private/mock/location.js#L23\n// - does not allow setting \"origin\"\nfunction applyStub(root: any, partial?: any) {\n if (!partial) return root;\n\n for (let key of Object.keys(partial)) {\n let value = partial[key];\n\n if (Array.isArray(value)) {\n root[key] = value;\n } else if (typeof value === 'object') {\n applyStub(root[key], value);\n } else {\n root[key] = value;\n }\n }\n}\n"],"names":["setupBrowserFakes","hooks","options","setupWindowMock","beforeEach","owner","window","patched","patchWindow","service","maybeMake","register","document","localStorage","FakeLocalStorageService","sessionStorage","FakeSessionStorageService","navigator","maybeImplementation","target","proxyService","prototype","Service","applyStub","root","partial","key","Object","keys","value","Array","isArray"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/test-support/index.ts"],"sourcesContent":["import Service from '@ember/service';\n\nimport window from 'ember-window-mock';\n\nimport { setupWindowMock } from 'ember-window-mock/test-support';\n\nimport { proxyService } from '../services/browser/-proxy-service';\nimport {\n FakeLocalStorageService,\n FakeSessionStorageService,\n} from './-private/web-storage';\n\nimport type { RecursivePartial } from '../types';\n\ntype Fakes = {\n window?: boolean | typeof Service | RecursivePartial<Window>;\n localStorage?: boolean;\n sessionStorage?: boolean;\n document?: boolean | typeof Service | RecursivePartial<Document>;\n navigator?: boolean | RecursivePartial<Navigator>;\n};\n\nexport function setupBrowserFakes(hooks: NestedHooks, options: Fakes): void {\n setupWindowMock(hooks);\n\n // Switched to 'any' from 'TestContext' due to awkward migration period from\n // DT to built-in-types.\n // I don't know if it's possible to support both fake test-helper types and real ones\n // (simultaneously)\n //\n // Additionally, these types have no bearing on end-user behavior, so this is low risk.\n hooks.beforeEach(function (this: any) {\n // the type for the owner keeps being wrong............\n let owner = this.owner as unknown as {\n register: (name: string, thing: unknown) => void;\n unregister: (name: string) => void;\n };\n\n if (options.window) {\n let service = maybeMake(options.window, window);\n\n owner.register('service:browser/window', service);\n }\n\n if (options.document) {\n let service = maybeMake(options.document, window.document);\n\n owner.register('service:browser/document', service);\n }\n\n if (options.localStorage) {\n owner.register('service:browser/local-storage', FakeLocalStorageService);\n }\n\n if (options.sessionStorage) {\n owner.register(\n 'service:browser/session-storage',\n FakeSessionStorageService\n );\n }\n\n if (options.navigator) {\n let service = maybeMake(options.navigator, window.navigator);\n\n owner.register('service:browser/navigator', service);\n }\n });\n}\n\n// this usage of any is correct, because it literally could be *any*thing\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype UnknownObject = Record<string, any>;\n\nexport function maybeMake<\n DefaultType extends UnknownObject,\n TestClass extends UnknownObject\n>(\n maybeImplementation:\n | true\n | typeof Service\n | TestClass\n | RecursivePartial<DefaultType>,\n target: DefaultType\n): DefaultType {\n if (maybeImplementation === true) {\n return proxyService(target);\n }\n\n if (maybeImplementation.prototype instanceof Service) {\n return target;\n }\n\n if (typeof maybeImplementation === 'object') {\n applyStub(target, maybeImplementation);\n\n return proxyService(target);\n }\n\n return proxyService(target);\n}\n\n// we are already using ember-window-mock, so the proxy internal to that package will\n// \"just handle\" setting stuff on the window\nfunction applyStub(root: any, partial?: any) {\n if (!partial) return root;\n\n for (let key of Object.keys(partial)) {\n let value = partial[key];\n\n if (Array.isArray(value)) {\n root[key] = value;\n } else if (typeof value === 'object') {\n applyStub(root[key], value);\n } else {\n root[key] = value;\n }\n }\n}\n"],"names":["setupBrowserFakes","hooks","options","setupWindowMock","beforeEach","owner","window","service","maybeMake","register","document","localStorage","FakeLocalStorageService","sessionStorage","FakeSessionStorageService","navigator","maybeImplementation","target","proxyService","prototype","Service","applyStub","root","partial","key","Object","keys","value","Array","isArray"],"mappings":";;;;;;AAsBO,SAASA,iBAAiBA,CAACC,KAAkB,EAAEC,OAAc,EAAQ;EAC1EC,eAAe,CAACF,KAAK,CAAC,CAAA;;AAEtB;AACA;AACA;AACA;AACA;AACA;EACAA,KAAK,CAACG,UAAU,CAAC,YAAqB;AACpC;AACA,IAAA,IAAIC,KAAK,GAAG,IAAI,CAACA,KAGhB,CAAA;IAED,IAAIH,OAAO,CAACI,MAAM,EAAE;MAClB,IAAIC,OAAO,GAAGC,SAAS,CAACN,OAAO,CAACI,MAAM,EAAEA,MAAM,CAAC,CAAA;AAE/CD,MAAAA,KAAK,CAACI,QAAQ,CAAC,wBAAwB,EAAEF,OAAO,CAAC,CAAA;AACnD,KAAA;IAEA,IAAIL,OAAO,CAACQ,QAAQ,EAAE;MACpB,IAAIH,OAAO,GAAGC,SAAS,CAACN,OAAO,CAACQ,QAAQ,EAAEJ,MAAM,CAACI,QAAQ,CAAC,CAAA;AAE1DL,MAAAA,KAAK,CAACI,QAAQ,CAAC,0BAA0B,EAAEF,OAAO,CAAC,CAAA;AACrD,KAAA;IAEA,IAAIL,OAAO,CAACS,YAAY,EAAE;AACxBN,MAAAA,KAAK,CAACI,QAAQ,CAAC,+BAA+B,EAAEG,uBAAuB,CAAC,CAAA;AAC1E,KAAA;IAEA,IAAIV,OAAO,CAACW,cAAc,EAAE;AAC1BR,MAAAA,KAAK,CAACI,QAAQ,CACZ,iCAAiC,EACjCK,yBACF,CAAC,CAAA;AACH,KAAA;IAEA,IAAIZ,OAAO,CAACa,SAAS,EAAE;MACrB,IAAIR,OAAO,GAAGC,SAAS,CAACN,OAAO,CAACa,SAAS,EAAET,MAAM,CAACS,SAAS,CAAC,CAAA;AAE5DV,MAAAA,KAAK,CAACI,QAAQ,CAAC,2BAA2B,EAAEF,OAAO,CAAC,CAAA;AACtD,KAAA;AACF,GAAC,CAAC,CAAA;AACJ,CAAA;;AAEA;AACA;;AAGO,SAASC,SAASA,CAIvBQ,mBAIiC,EACjCC,MAAmB,EACN;EACb,IAAID,mBAAmB,KAAK,IAAI,EAAE;IAChC,OAAOE,YAAY,CAACD,MAAM,CAAC,CAAA;AAC7B,GAAA;AAEA,EAAA,IAAID,mBAAmB,CAACG,SAAS,YAAYC,OAAO,EAAE;AACpD,IAAA,OAAOH,MAAM,CAAA;AACf,GAAA;AAEA,EAAA,IAAI,OAAOD,mBAAmB,KAAK,QAAQ,EAAE;AAC3CK,IAAAA,SAAS,CAACJ,MAAM,EAAED,mBAAmB,CAAC,CAAA;IAEtC,OAAOE,YAAY,CAACD,MAAM,CAAC,CAAA;AAC7B,GAAA;EAEA,OAAOC,YAAY,CAACD,MAAM,CAAC,CAAA;AAC7B,CAAA;;AAEA;AACA;AACA,SAASI,SAASA,CAACC,IAAS,EAAEC,OAAa,EAAE;AAC3C,EAAA,IAAI,CAACA,OAAO,EAAE,OAAOD,IAAI,CAAA;EAEzB,KAAK,IAAIE,GAAG,IAAIC,MAAM,CAACC,IAAI,CAACH,OAAO,CAAC,EAAE;AACpC,IAAA,IAAII,KAAK,GAAGJ,OAAO,CAACC,GAAG,CAAC,CAAA;AAExB,IAAA,IAAII,KAAK,CAACC,OAAO,CAACF,KAAK,CAAC,EAAE;AACxBL,MAAAA,IAAI,CAACE,GAAG,CAAC,GAAGG,KAAK,CAAA;AACnB,KAAC,MAAM,IAAI,OAAOA,KAAK,KAAK,QAAQ,EAAE;AACpCN,MAAAA,SAAS,CAACC,IAAI,CAACE,GAAG,CAAC,EAAEG,KAAK,CAAC,CAAA;AAC7B,KAAC,MAAM;AACLL,MAAAA,IAAI,CAACE,GAAG,CAAC,GAAGG,KAAK,CAAA;AACnB,KAAA;AACF,GAAA;AACF;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ember-browser-services",
3
- "version": "4.0.4",
3
+ "version": "5.0.0",
4
4
  "description": "Browser APIs as services for easier testing",
5
5
  "repository": "https://github.com/CrowdStrike/ember-browser-services",
6
6
  "license": "MIT",
@@ -35,36 +35,36 @@
35
35
  ],
36
36
  "dependencies": {
37
37
  "@embroider/addon-shim": "^1.3.0",
38
- "ember-window-mock": "^0.8.1"
38
+ "ember-window-mock": "^1.0.1"
39
39
  },
40
40
  "devDependencies": {
41
- "@babel/core": "7.20.12",
41
+ "@babel/core": "7.25.2",
42
42
  "@babel/eslint-parser": "^7.19.1",
43
43
  "@babel/plugin-proposal-class-properties": "7.18.6",
44
- "@babel/plugin-proposal-decorators": "7.20.13",
45
- "@babel/plugin-syntax-decorators": "7.19.0",
46
- "@babel/plugin-transform-typescript": "7.20.13",
47
- "@babel/preset-typescript": "7.18.6",
48
- "@embroider/addon-dev": "3.0.0",
49
- "@nullvoxpopuli/eslint-configs": "3.1.1",
44
+ "@babel/plugin-proposal-decorators": "7.24.7",
45
+ "@babel/plugin-syntax-decorators": "7.24.7",
46
+ "@babel/plugin-transform-typescript": "7.25.2",
47
+ "@babel/preset-typescript": "7.24.7",
48
+ "@embroider/addon-dev": "3.2.0",
49
+ "@nullvoxpopuli/eslint-configs": "3.2.2",
50
50
  "@types/ember__application": "^4.0.0",
51
51
  "@types/ember__engine": "^4.0.0",
52
52
  "@types/ember__object": "^4.0.0",
53
53
  "@types/ember__service": "^4.0.0",
54
54
  "@types/qunit": "^2.11.3",
55
- "@typescript-eslint/eslint-plugin": "5.50.0",
55
+ "@typescript-eslint/eslint-plugin": "5.55.0",
56
56
  "@typescript-eslint/parser": "^5.50.0",
57
- "concurrently": "7.6.0",
58
- "ember-source": "3.8.0",
57
+ "concurrently": "8.2.2",
58
+ "ember-source": "3.28.12",
59
59
  "eslint": "^8.33.0",
60
60
  "eslint-plugin-decorator-position": "5.0.2",
61
- "eslint-plugin-ember": "11.4.5",
61
+ "eslint-plugin-ember": "11.4.8",
62
62
  "eslint-plugin-import": "2.27.5",
63
63
  "eslint-plugin-json": "3.1.0",
64
64
  "eslint-plugin-node": "11.1.0",
65
- "eslint-plugin-simple-import-sort": "7.0.0",
65
+ "eslint-plugin-simple-import-sort": "10.0.0",
66
66
  "prettier": "^2.8.3",
67
- "rollup": "3.12.1",
67
+ "rollup": "3.29.4",
68
68
  "rollup-plugin-copy": "^3.4.0",
69
69
  "rollup-plugin-ts": "3.2.0",
70
70
  "typescript": "4.9.5"
@@ -87,9 +87,6 @@
87
87
  "./services/browser/window.js": "./dist/_app_/services/browser/window.js"
88
88
  }
89
89
  },
90
- "volta": {
91
- "extends": "../package.json"
92
- },
93
90
  "types": "dist",
94
91
  "scripts": {
95
92
  "start": "pnpm watch:js",
@@ -1,2 +0,0 @@
1
- declare function patchWindow(target: any): any;
2
- export { patchWindow };
@@ -1,45 +0,0 @@
1
- import window from 'ember-window-mock';
2
- import locationFactory from 'ember-window-mock/test-support/-private/mock/location';
3
-
4
- const AUGMENTS = ['origin'];
5
- function createLocation(target) {
6
- let initialHref = target?.location?.href ?? window.location.href;
7
- let mockLocation = locationFactory(initialHref);
8
- let values = {};
9
- mockLocation.isPatchedLocation = true;
10
- return new Proxy(mockLocation, {
11
- get(target, key, receiver) {
12
- if (AUGMENTS.includes(key)) {
13
- return values[key] ?? Reflect.get(target, key, receiver);
14
- }
15
- return Reflect.get(target, key, receiver);
16
- },
17
- set(target, key, value, receiver) {
18
- if (AUGMENTS.includes(key)) {
19
- return values[key] = value;
20
- }
21
- return Reflect.set(target, key, value, receiver);
22
- }
23
- });
24
- }
25
- function patchWindow(target) {
26
- let location = createLocation(target);
27
- let self = new Proxy(target, {
28
- get(target, key, receiver) {
29
- if (key === 'location') return location;
30
- if (key === 'parent') return self;
31
- if (key === 'top') return self;
32
- return Reflect.get(target, key, receiver);
33
- },
34
- set(target, key, value, receiver) {
35
- if (key === 'location') {
36
- throw new Error(`location cannot be set on window`);
37
- }
38
- return Reflect.set(target, key, value, receiver);
39
- }
40
- });
41
- return self;
42
- }
43
-
44
- export { patchWindow };
45
- //# sourceMappingURL=window-mock-augments.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"window-mock-augments.js","sources":["../../src/test-support/window-mock-augments.ts"],"sourcesContent":["import window from 'ember-window-mock';\n\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-expect-error\nimport locationFactory from 'ember-window-mock/test-support/-private/mock/location';\n\nconst AUGMENTS: Array<string | symbol> = ['origin'];\n\nfunction createLocation(target?: Window) {\n let initialHref = target?.location?.href ?? window.location.href;\n let mockLocation = locationFactory(initialHref);\n let values: any = {};\n\n mockLocation.isPatchedLocation = true;\n\n return new Proxy(mockLocation, {\n get(target, key, receiver) {\n if (AUGMENTS.includes(key)) {\n return values[key] ?? Reflect.get(target, key, receiver);\n }\n\n return Reflect.get(target, key, receiver);\n },\n\n set(target, key, value, receiver) {\n if (AUGMENTS.includes(key)) {\n return (values[key] = value);\n }\n\n return Reflect.set(target, key, value, receiver);\n },\n });\n}\n\nexport function patchWindow(target: any) {\n let location = createLocation(target);\n\n let self: any = new Proxy(target, {\n get(target, key, receiver) {\n if (key === 'location') return location;\n if (key === 'parent') return self;\n if (key === 'top') return self;\n\n return Reflect.get(target, key, receiver);\n },\n set(target, key, value, receiver) {\n if (key === 'location') {\n throw new Error(`location cannot be set on window`);\n }\n\n return Reflect.set(target, key, value, receiver);\n },\n });\n\n return self;\n}\n"],"names":["AUGMENTS","createLocation","target","initialHref","location","href","window","mockLocation","locationFactory","values","isPatchedLocation","Proxy","get","key","receiver","includes","Reflect","set","value","patchWindow","self","Error"],"mappings":";;;AAMA,MAAMA,QAAgC,GAAG,CAAC,QAAQ,CAAC,CAAA;AAEnD,SAASC,cAAc,CAACC,MAAe,EAAE;AACvC,EAAA,IAAIC,WAAW,GAAGD,MAAM,EAAEE,QAAQ,EAAEC,IAAI,IAAIC,MAAM,CAACF,QAAQ,CAACC,IAAI,CAAA;AAChE,EAAA,IAAIE,YAAY,GAAGC,eAAe,CAACL,WAAW,CAAC,CAAA;EAC/C,IAAIM,MAAW,GAAG,EAAE,CAAA;EAEpBF,YAAY,CAACG,iBAAiB,GAAG,IAAI,CAAA;AAErC,EAAA,OAAO,IAAIC,KAAK,CAACJ,YAAY,EAAE;AAC7BK,IAAAA,GAAG,CAACV,MAAM,EAAEW,GAAG,EAAEC,QAAQ,EAAE;AACzB,MAAA,IAAId,QAAQ,CAACe,QAAQ,CAACF,GAAG,CAAC,EAAE;AAC1B,QAAA,OAAOJ,MAAM,CAACI,GAAG,CAAC,IAAIG,OAAO,CAACJ,GAAG,CAACV,MAAM,EAAEW,GAAG,EAAEC,QAAQ,CAAC,CAAA;AAC1D,OAAA;MAEA,OAAOE,OAAO,CAACJ,GAAG,CAACV,MAAM,EAAEW,GAAG,EAAEC,QAAQ,CAAC,CAAA;KAC1C;IAEDG,GAAG,CAACf,MAAM,EAAEW,GAAG,EAAEK,KAAK,EAAEJ,QAAQ,EAAE;AAChC,MAAA,IAAId,QAAQ,CAACe,QAAQ,CAACF,GAAG,CAAC,EAAE;AAC1B,QAAA,OAAQJ,MAAM,CAACI,GAAG,CAAC,GAAGK,KAAK,CAAA;AAC7B,OAAA;MAEA,OAAOF,OAAO,CAACC,GAAG,CAACf,MAAM,EAAEW,GAAG,EAAEK,KAAK,EAAEJ,QAAQ,CAAC,CAAA;AAClD,KAAA;AACF,GAAC,CAAC,CAAA;AACJ,CAAA;AAEO,SAASK,WAAW,CAACjB,MAAW,EAAE;AACvC,EAAA,IAAIE,QAAQ,GAAGH,cAAc,CAACC,MAAM,CAAC,CAAA;AAErC,EAAA,IAAIkB,IAAS,GAAG,IAAIT,KAAK,CAACT,MAAM,EAAE;AAChCU,IAAAA,GAAG,CAACV,MAAM,EAAEW,GAAG,EAAEC,QAAQ,EAAE;AACzB,MAAA,IAAID,GAAG,KAAK,UAAU,EAAE,OAAOT,QAAQ,CAAA;AACvC,MAAA,IAAIS,GAAG,KAAK,QAAQ,EAAE,OAAOO,IAAI,CAAA;AACjC,MAAA,IAAIP,GAAG,KAAK,KAAK,EAAE,OAAOO,IAAI,CAAA;MAE9B,OAAOJ,OAAO,CAACJ,GAAG,CAACV,MAAM,EAAEW,GAAG,EAAEC,QAAQ,CAAC,CAAA;KAC1C;IACDG,GAAG,CAACf,MAAM,EAAEW,GAAG,EAAEK,KAAK,EAAEJ,QAAQ,EAAE;MAChC,IAAID,GAAG,KAAK,UAAU,EAAE;AACtB,QAAA,MAAM,IAAIQ,KAAK,CAAE,CAAA,gCAAA,CAAiC,CAAC,CAAA;AACrD,OAAA;MAEA,OAAOL,OAAO,CAACC,GAAG,CAACf,MAAM,EAAEW,GAAG,EAAEK,KAAK,EAAEJ,QAAQ,CAAC,CAAA;AAClD,KAAA;AACF,GAAC,CAAC,CAAA;AAEF,EAAA,OAAOM,IAAI,CAAA;AACb;;;;"}