diff --git a/types/chrome/index.d.ts b/types/chrome/index.d.ts index 2fba292f3cf114..32e74753bd9a9e 100644 --- a/types/chrome/index.d.ts +++ b/types/chrome/index.d.ts @@ -381,22 +381,53 @@ declare namespace chrome { * Permissions: "alarms" */ export namespace alarms { - interface AlarmCreateInfo { - /** Length of time in minutes after which the {@link onAlarm} event should fire. */ - delayInMinutes?: number | undefined; - /** If set, the onAlarm event should fire every `periodInMinutes` minutes after the initial event specified by `when` or `delayInMinutes`. If not set, the alarm will only fire once. */ - periodInMinutes?: number | undefined; - /** Time at which the alarm should fire, in milliseconds past the epoch (e.g. `Date.now() + n`). */ - when?: number | undefined; - } + type AlarmCreateInfo = + & { + /** + * Whether the alarm should persist across sessions (browser restarts). In Chrome, this defaults to true to match historical behavior, but you should set this explicitly to maximize compatibility across browsers. + * @since Chrome 150 + */ + persistAcrossSessions?: boolean | undefined; + } + & ( + | { + /** Length of time in minutes after which the {@link onAlarm} event should fire. */ + delayInMinutes: number; + /** If set, the onAlarm event should fire every `periodInMinutes` minutes after the initial event specified by `when` or `delayInMinutes`. If not set, the alarm will only fire once. */ + periodInMinutes?: number | undefined; + /** Time at which the alarm should fire, in milliseconds past the epoch (e.g. `Date.now() + n`). */ + when?: never | undefined; + } + | { + /** Length of time in minutes after which the {@link onAlarm} event should fire. */ + delayInMinutes?: number | undefined; + /** If set, the onAlarm event should fire every `periodInMinutes` minutes after the initial event specified by `when` or `delayInMinutes`. If not set, the alarm will only fire once. */ + periodInMinutes: number; + /** Time at which the alarm should fire, in milliseconds past the epoch (e.g. `Date.now() + n`). */ + when?: number | undefined; + } + | { + /** Length of time in minutes after which the {@link onAlarm} event should fire. */ + delayInMinutes?: never | undefined; + /** If set, the onAlarm event should fire every `periodInMinutes` minutes after the initial event specified by `when` or `delayInMinutes`. If not set, the alarm will only fire once. */ + periodInMinutes?: number | undefined; + /** Time at which the alarm should fire, in milliseconds past the epoch (e.g. `Date.now() + n`). */ + when: number; + } + ); interface Alarm { + /** Name of this alarm. */ + name: string; /** If not null, the alarm is a repeating alarm and will fire again in `periodInMinutes` minutes. */ periodInMinutes?: number; + /** + * Whether the alarm should persist across sessions (browser restarts). + * @since Chrome 150 + */ + persistAcrossSessions: boolean; /** Time at which this alarm was scheduled to fire, in milliseconds past the epoch (e.g. `Date.now() + n`). For performance reasons, the alarm may have been delayed an arbitrary amount beyond this. */ scheduledTime: number; - /** Name of this alarm. */ - name: string; } /** @@ -7604,7 +7635,7 @@ declare namespace chrome { * Creates a new offscreen document for the extension. * @param parameters The parameters describing the offscreen document to create. * - * Can return its result via Promise in Manifest V3. + * Can return its result via Promise. */ function createDocument(parameters: CreateParameters): Promise; function createDocument(parameters: CreateParameters, callback: () => void): void; @@ -7612,7 +7643,7 @@ declare namespace chrome { /** * Closes the currently-open offscreen document for the extension. * - * Can return its result via Promise in Manifest V3. + * Can return its result via Promise. */ function closeDocument(): Promise; function closeDocument(callback: () => void): void; @@ -7620,7 +7651,8 @@ declare namespace chrome { /** * Determines whether the extension has an active document. * - * Can return its result via Promise in Manifest V3. + * Can return its result via Promise. + * @since Chrome 150 */ function hasDocument(): Promise; function hasDocument(callback: (result: boolean) => void): void; diff --git a/types/chrome/test/index.ts b/types/chrome/test/index.ts index 547268f12ef49f..caba3a26526a27 100644 --- a/types/chrome/test/index.ts +++ b/types/chrome/test/index.ts @@ -2587,12 +2587,17 @@ async function testAlarms() { delayInMinutes: 1, periodInMinutes: 1, when: 1, + persistAcrossSessions: true, }; chrome.alarms.create(alarmCreateInfo); // $ExpectType Promise chrome.alarms.create("name", alarmCreateInfo); // $ExpectType Promise chrome.alarms.create(alarmCreateInfo, () => {}); // $ExpectType void chrome.alarms.create("name", alarmCreateInfo, () => {}); // $ExpectType void + // @ts-expect-error Must set at least one of when, delayInMinutes, or periodInMinutes. + chrome.alarms.create("name", { persistAcrossSessions: true }, () => {}); + // @ts-expect-error Cannot set both when and delayInMinutes. + chrome.alarms.create("name", { when: 1, delayInMinutes: 1 }, () => {}); // @ts-expect-error chrome.alarms.create("name", alarmCreateInfo, () => {}).then(() => {}); @@ -2601,6 +2606,7 @@ async function testAlarms() { alarm.name; // $ExpectType string alarm.periodInMinutes; // $ExpectType number | undefined alarm.scheduledTime; // $ExpectType number + alarm.persistAcrossSessions; // $ExpectType boolean }); // @ts-expect-error chrome.alarms.getAll(() => {}).then(() => {}); @@ -2631,6 +2637,7 @@ async function testAlarms() { alarm.name; // $ExpectType string alarm.periodInMinutes; // $ExpectType number | undefined alarm.scheduledTime; // $ExpectType number + alarm.persistAcrossSessions; // $ExpectType boolean }); chrome.alarms.get("name", (alarm) => { // $ExpectType void alarm; // $ExpectType Alarm | undefined @@ -2638,6 +2645,7 @@ async function testAlarms() { alarm.name; // $ExpectType string alarm.periodInMinutes; // $ExpectType number | undefined alarm.scheduledTime; // $ExpectType number + alarm.persistAcrossSessions; // $ExpectType boolean }); // @ts-expect-error chrome.alarms.get("name", () => {}).then(() => {}); @@ -2646,6 +2654,7 @@ async function testAlarms() { alarm.name; // $ExpectType string alarm.periodInMinutes; // $ExpectType number | undefined alarm.scheduledTime; // $ExpectType number + alarm.persistAcrossSessions; // $ExpectType boolean }); } diff --git a/types/custom-functions-runtime/package.json b/types/custom-functions-runtime/package.json index e060e37d10b001..1bdc67bb97d934 100644 --- a/types/custom-functions-runtime/package.json +++ b/types/custom-functions-runtime/package.json @@ -15,10 +15,6 @@ "name": "OfficeDev", "githubUsername": "OfficeDev" }, - { - "name": "David Chesnut", - "githubUsername": "davidchesnut" - }, { "name": "Alex Jerabek", "githubUsername": "AlexJerabek" diff --git a/types/cyclonedx/package.json b/types/cyclonedx/package.json index 1174e06cf2ea5f..b51097932637d0 100644 --- a/types/cyclonedx/package.json +++ b/types/cyclonedx/package.json @@ -2,7 +2,7 @@ "private": true, "name": "@types/cyclonedx", "version": "1.4.9999", - "nonNpm": true, + "nonNpm": "conflict", "nonNpmDescription": "cyclonedx", "projects": [ "https://github.com/CycloneDX/specification" diff --git a/types/hotwired__turbo/hotwired__turbo-tests.ts b/types/hotwired__turbo/hotwired__turbo-tests.ts index f41a07a13381c1..245cd39ce34c2c 100644 --- a/types/hotwired__turbo/hotwired__turbo-tests.ts +++ b/types/hotwired__turbo/hotwired__turbo-tests.ts @@ -42,6 +42,11 @@ turboFrame.loading = "slow"; turboFrame.reload().catch(console.error); +// $ExpectType string | null +turboFrame.src; +turboFrame.src = "/messages"; +turboFrame.src = null; + const turboStream = document.querySelector("turbo-stream")!; // $ExpectType StreamElement diff --git a/types/hotwired__turbo/index.d.ts b/types/hotwired__turbo/index.d.ts index 2169414fc32b8b..56a0d23125945b 100644 --- a/types/hotwired__turbo/index.d.ts +++ b/types/hotwired__turbo/index.d.ts @@ -1,5 +1,5 @@ export class FrameElement extends HTMLElement { - src: string; + src: string | null; disabled: boolean; loading: "eager" | "lazy"; loaded: Promise; diff --git a/types/multer/index.d.ts b/types/multer/index.d.ts index e6ee81a9df85ea..890e59e2f8636f 100644 --- a/types/multer/index.d.ts +++ b/types/multer/index.d.ts @@ -200,6 +200,8 @@ declare namespace multer { fieldSize?: number | undefined; /** Maximum number of non-file form fields. (Default: Infinity) */ fields?: number | undefined; + /** Maximum number of nesting levels for field names, e.g. `a[b][c]` has 2 levels. (Default: Infinity) */ + fieldNestingDepth?: number | undefined; /** Maximum size of each file in bytes. (Default: Infinity) */ fileSize?: number | undefined; /** Maximum number of file fields. (Default: Infinity) */ diff --git a/types/multer/multer-tests.ts b/types/multer/multer-tests.ts index 5397c67dd6c40c..08caf5d8750bb9 100644 --- a/types/multer/multer-tests.ts +++ b/types/multer/multer-tests.ts @@ -28,6 +28,23 @@ const upload_with_defParamCharset = multer({ upload_with_defParamCharset; // $ExpectType Multer assert.strictEqual(upload_with_defParamCharset.constructor.name, "Multer"); +const upload_with_limits = multer({ + dest: "uploads/", + limits: { + fieldNameSize: 100, + fieldSize: 1048576, + fields: 10, + fieldNestingDepth: 2, + fileSize: Infinity, + files: Infinity, + parts: Infinity, + headerPairs: 2000, + }, +}); + +upload_with_limits; // $ExpectType Multer +assert.strictEqual(upload_with_limits.constructor.name, "Multer"); + const app = express(); app.post( diff --git a/types/multer/package.json b/types/multer/package.json index 09fffe8b4ef162..b520dea7c321c2 100644 --- a/types/multer/package.json +++ b/types/multer/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@types/multer", - "version": "2.1.9999", + "version": "2.2.9999", "projects": [ "https://github.com/expressjs/multer" ], diff --git a/types/namespace-emitter/.npmignore b/types/namespace-emitter/.npmignore new file mode 100644 index 00000000000000..93e307400a5456 --- /dev/null +++ b/types/namespace-emitter/.npmignore @@ -0,0 +1,5 @@ +* +!**/*.d.ts +!**/*.d.cts +!**/*.d.mts +!**/*.d.*.ts diff --git a/types/namespace-emitter/index.d.ts b/types/namespace-emitter/index.d.ts new file mode 100644 index 00000000000000..ae78ac66df0b7e --- /dev/null +++ b/types/namespace-emitter/index.d.ts @@ -0,0 +1,72 @@ +declare namespace createNamespaceEmitter { + type Listener = ( + this: Listener & { event: string }, + arg1?: any, + arg2?: any, + arg3?: any, + arg4?: any, + arg5?: any, + arg6?: any, + ) => void; + + interface Emitter { + /** + * Emit an event. Optionally namespace the event. Handlers are fired in the order in which they were added with exact matches taking precedence. Separate the namespace and event with a `:` + * + * @param event the name of the event, with optional namespace + * @param data up to 6 arguments that are passed to the event listener + * @example + * emitter.emit('example') + * emitter.emit('demo:test') + * emitter.emit('data', { example: true }, 'a string', 1) + */ + emit(event: string, arg1?: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any, arg6?: any): void; + + /** + * Create en event listener. + * + * @example + * emitter.on('example', function () {}) + * emitter.on('demo', function () {}) + */ + on(event: string, listener: Listener): void; + + /** + * Create en event listener that fires once. + * + * @example + * emitter.once('example', function () {}) + * emitter.once('demo', function () {}) + */ + once(event: string, listener: Listener): void; + + /** + * Stop listening to an event. Stop all listeners on an event by only passing the event name. Stop a single listener by passing that event handler as a callback. + * You must be explicit about what will be unsubscribed: `emitter.off('demo')` will unsubscribe an `emitter.on('demo')` listener, + * `emitter.off('demo:example')` will unsubscribe an `emitter.on('demo:example')` listener + * + * @example + * emitter.off('example') + * emitter.off('demo', function () {}) + */ + off(event: string, listener?: Listener): void; + } +} + +/** + * Create an event emitter with namespaces + * + * @example + * var emitter = require('./index')() + * + * emitter.on('*', function () { + * console.log('all events emitted', this.event) + * }) + * + * emitter.on('example', function () { + * console.log('example event emitted') + * }) + */ +declare function createNamespaceEmitter(): createNamespaceEmitter.Emitter; + +export = createNamespaceEmitter; diff --git a/types/namespace-emitter/namespace-emitter-tests.ts b/types/namespace-emitter/namespace-emitter-tests.ts new file mode 100644 index 00000000000000..f4941f68d52b90 --- /dev/null +++ b/types/namespace-emitter/namespace-emitter-tests.ts @@ -0,0 +1,66 @@ +import createNamespaceEmitter = require("namespace-emitter"); + +declare namespace console { + function log(...args: unknown[]): void; +} + +const emitter = createNamespaceEmitter(); + +// readme + +emitter.on("*", function() { + console.log("all events emitted", this.event); +}); + +emitter.on("example", function() { + console.log("example event emitted"); +}); + +emitter.emit("example"); + +emitter.on("demo", function() { + console.log("multiple events with `demo` namespace emitted", this.event); +}); + +emitter.emit("demo:cool"); +emitter.emit("demo:awesome"); +emitter.emit("demo:great"); + +// everything else + +emitter.emit("a", {}); +emitter.emit("b", {}, 1); +emitter.emit("c", {}, 1, ""); +emitter.emit("d", {}, 1, "", null); +emitter.emit("e", {}, 1, "", null, true); +emitter.emit("f", {}, 1, "", null, true, undefined); +// @ts-expect-error https://github.com/sethvincent/namespace-emitter/blob/master/index.js#L29 +emitter.emit("g", {}, 1, "", null, true, undefined, {}); + +emitter.on("a", (arg1) => {}); +emitter.on("b", (arg1, arg2) => {}); +emitter.on("c", (arg1, arg2, arg3) => {}); +emitter.on("d", (arg1, arg2, arg3, arg4) => {}); +emitter.on("e", (arg1, arg2, arg3, arg4, arg5) => {}); +emitter.on("f", (arg1, arg2, arg3, arg4, arg5, arg6) => {}); +// @ts-expect-error https://github.com/sethvincent/namespace-emitter/blob/master/index.js#L29 +emitter.on("g", (arg1, arg2, arg3, arg4, arg5, arg6, arg7) => {}); + +emitter.once("a", (arg1) => {}); +emitter.once("b", (arg1, arg2) => {}); +emitter.once("c", (arg1, arg2, arg3) => {}); +emitter.once("d", (arg1, arg2, arg3, arg4) => {}); +emitter.once("e", (arg1, arg2, arg3, arg4, arg5) => {}); +emitter.once("f", (arg1, arg2, arg3, arg4, arg5, arg6) => {}); +// @ts-expect-error https://github.com/sethvincent/namespace-emitter/blob/master/index.js#L29 +emitter.once("g", (arg1, arg2, arg3, arg4, arg5, arg6, arg7) => {}); + +emitter.off("a", (arg1) => {}); +emitter.off("b", (arg1, arg2) => {}); +emitter.off("c", (arg1, arg2, arg3) => {}); +emitter.off("d", (arg1, arg2, arg3, arg4) => {}); +emitter.off("e", (arg1, arg2, arg3, arg4, arg5) => {}); +emitter.off("f", (arg1, arg2, arg3, arg4, arg5, arg6) => {}); +// @ts-expect-error https://github.com/sethvincent/namespace-emitter/blob/master/index.js#L29 +emitter.off("g", (arg1, arg2, arg3, arg4, arg5, arg6, arg7) => {}); +emitter.off("h"); diff --git a/types/namespace-emitter/package.json b/types/namespace-emitter/package.json new file mode 100644 index 00000000000000..8ff3eb8c9b48d0 --- /dev/null +++ b/types/namespace-emitter/package.json @@ -0,0 +1,17 @@ +{ + "private": true, + "name": "@types/namespace-emitter", + "version": "2.0.9999", + "projects": [ + "https://github.com/sethvincent/namespace-emitter#readme" + ], + "devDependencies": { + "@types/namespace-emitter": "workspace:." + }, + "owners": [ + { + "name": "Remco Haszing", + "githubUsername": "remcohaszing" + } + ] +} diff --git a/types/namespace-emitter/tsconfig.json b/types/namespace-emitter/tsconfig.json new file mode 100644 index 00000000000000..118c238212fa26 --- /dev/null +++ b/types/namespace-emitter/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "module": "node16", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictFunctionTypes": true, + "strictNullChecks": true, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "namespace-emitter-tests.ts" + ] +} diff --git a/types/office-js-preview/package.json b/types/office-js-preview/package.json index 86e1e2d5c1c9f8..4b0184852fdc90 100644 --- a/types/office-js-preview/package.json +++ b/types/office-js-preview/package.json @@ -15,10 +15,6 @@ "name": "OfficeDev", "githubUsername": "OfficeDev" }, - { - "name": "David Chesnut", - "githubUsername": "davidchesnut" - }, { "name": "Alex Jerabek", "githubUsername": "AlexJerabek" diff --git a/types/office-js/package.json b/types/office-js/package.json index 0d2a783af27b93..c94348b6e629d9 100644 --- a/types/office-js/package.json +++ b/types/office-js/package.json @@ -13,10 +13,6 @@ "name": "OfficeDev", "githubUsername": "OfficeDev" }, - { - "name": "David Chesnut", - "githubUsername": "davidchesnut" - }, { "name": "Alex Jerabek", "githubUsername": "AlexJerabek" diff --git a/types/office-runtime/package.json b/types/office-runtime/package.json index c3a6d504f8278a..884a6f08269dc3 100644 --- a/types/office-runtime/package.json +++ b/types/office-runtime/package.json @@ -15,10 +15,6 @@ "name": "OfficeDev", "githubUsername": "OfficeDev" }, - { - "name": "David Chesnut", - "githubUsername": "davidchesnut" - }, { "name": "Alex Jerabek", "githubUsername": "AlexJerabek" diff --git a/types/woosmap.map/index.d.ts b/types/woosmap.map/index.d.ts index 5c39acefac35b3..bbb663a0993bb7 100644 --- a/types/woosmap.map/index.d.ts +++ b/types/woosmap.map/index.d.ts @@ -1563,7 +1563,10 @@ declare namespace woosmap.map { */ heading?: number; /** - * Whether to display the map type control. Defaults to false. + * Whether to display the map type control. When unset, the control auto-attaches + * once the loaded maptype advertises the `satellite` capability. Pass `true`/`false` + * explicitly to opt in or out. Note: `get('mapTypeControl')` reflects the user + * option, not attachment state — it stays `false` while auto-attach is pending. */ mapTypeControl?: boolean; /** @@ -1594,10 +1597,9 @@ declare namespace woosmap.map { */ tilt?: number; /** - * Opt into the upcoming visual refresh styles. When true, the resolved style - * is upgraded to its refreshed counterpart (e.g. `streets` -> `streets_next`). - * If unset, falls back to `woosmap.map.config.getVisualRefresh()` (default false). - * Experimental — will be removed once the refreshed styles become the default. + * Opt into the upcoming visual refresh of the default basemap styles. + * Defaults to false. Will be removed once the refreshed styles become + * the default. */ visualRefresh?: boolean; /** @@ -3392,6 +3394,9 @@ declare namespace woosmap.map.localities { | woosmap.map.localities.DeprecatedLocalitiesTypes | "country" | "admin_level" + | "admin_level_1" + | "admin_level_2" + | "admin_level_3" | "postal_code" | "address" | "route" diff --git a/types/woosmap.map/woosmap.map-tests.ts b/types/woosmap.map/woosmap.map-tests.ts index 71bc68c13babbc..2c15d375f1ee83 100644 --- a/types/woosmap.map/woosmap.map-tests.ts +++ b/types/woosmap.map/woosmap.map-tests.ts @@ -578,6 +578,20 @@ promiseLocalitiesGeocode.then((result) => { // $ExpectType LocalitiesGeocodeResponse result; }); + +// admin_level_x types +const adminLevelXTypes: woosmap.map.localities.LocalitiesTypes[] = ["admin_level_1", "admin_level_2", "admin_level_3"]; +const localitiesGeocodeAdminLevelRequest = expectType({ + address: "Haute-Garonne", + components: { country: ["FR"] }, + types: adminLevelXTypes, +}) as woosmap.map.localities.LocalitiesGeocodeRequest; +const promiseLocalitiesGeocodeAdminLevel = localitiesService.geocode(localitiesGeocodeAdminLevelRequest); +promiseLocalitiesGeocodeAdminLevel.then((result) => { + // $ExpectType LocalitiesGeocodeResponse + result; +}); + const localitiesNearbyRequest = expectType({ input: "royal al", types: ["point_of_interest", "tourism", "hospitality"],