Merge branch 'master' into mentos1386-node-tty-class-fix

This commit is contained in:
Tine Jozelj
2018-02-07 17:31:26 +01:00
23215 changed files with 1561007 additions and 667985 deletions
+1 -1
View File
@@ -1,9 +1,9 @@
root = true
[*]
indent_size = 4
trim_trailing_whitespace = true
insert_final_newline = true
[{*.json,*.yml}]
indent_style = space
indent_size = 2
+3932
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -1,5 +1,9 @@
If you know how to fix the issue, make a pull request instead.
- [ ] I tried using the `@types/xxxx` package and had problems.
- [ ] I tried using the latest stable version of tsc. https://www.npmjs.com/package/typescript
- [ ] I have a question that is inappropriate for [StackOverflow](https://stackoverflow.com/). (Please ask any appropriate questions there).
- [ ] [Mention](https://github.com/blog/821-mention-somebody-they-re-notified) the authors (see `Definitions by:` in `index.d.ts`) so they can respond.
- Authors: @....
If you do not mention the authors the issue will be ignored.
+2 -2
View File
@@ -12,12 +12,12 @@ If adding a new definition:
- [ ] The package does not provide its own types, and you can not add them.
- [ ] If this is for an NPM package, match the name. If not, do not conflict with the name of an NPM package.
- [ ] Create it with `dts-gen --dt`, not by basing it on an existing project.
- [ ] `tslint.json` should be present, and `tsconfig.json` should have `noImplicitAny`, `noImplicitThis`, and `strictNullChecks` set to `true`.
- [ ] `tslint.json` should be present, and `tsconfig.json` should have `noImplicitAny`, `noImplicitThis`, `strictNullChecks`, and `strictFunctionTypes` set to `true`.
If changing an existing definition:
- [ ] Provide a URL to documentation or source code which provides context for the suggested changes: <<url here>>
- [ ] Increase the version number in the header if appropriate.
- [ ] If you are making substantial changes, consider adding a `tslint.json` containing `{ "extends": "dslint/dt.json" }`.
- [ ] If you are making substantial changes, consider adding a `tslint.json` containing `{ "extends": "dtslint/dt.json" }`.
If removing a declaration:
- [ ] If a package was never on DefinitelyTyped, you don't need to do anything. (If you wrote a package and provided types, you don't need to register it with us.)
+10 -2
View File
@@ -12,7 +12,6 @@
*.map
*.swp
.DS_Store
npm-debug.log
_Resharper.DefinitelyTyped
bin
@@ -25,19 +24,28 @@ Properties
# test folder
_infrastructure/tests/build
# IntelliJ based IDEs
.idea
*.iml
*.js.map
!*.js/
!scripts/new-package.js
!scripts/not-needed.js
!scripts/lint.js
# npm
node_modules
package-lock.json
npm-debug.log
# Sublime
.sublimets
.settings/launch.json
# Visual Studio Code
.settings/launch.json
.vs
.vscode
# yarn
yarn.lock
+1 -1
View File
@@ -1,6 +1,6 @@
language: node_js
node_js:
- node
- 8
sudo: false
+70 -6
View File
@@ -1,4 +1,4 @@
# DefinitelyTyped [![Build Status](https://travis-ci.org/DefinitelyTyped/DefinitelyTyped.png?branch=master)](https://travis-ci.org/DefinitelyTyped/DefinitelyTyped)
# DefinitelyTyped [![Build Status](https://travis-ci.org/DefinitelyTyped/DefinitelyTyped.svg?branch=master)](https://travis-ci.org/DefinitelyTyped/DefinitelyTyped)
[![Join the chat at https://gitter.im/borisyankov/DefinitelyTyped](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/borisyankov/DefinitelyTyped?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@@ -38,7 +38,7 @@ or just look for any ".d.ts" files in the package and manually include them with
These can be used by TypeScript 1.0.
* [Typings](https://github.com/typings/typings)
* ~~[NuGet](http://nuget.org/Tpackages?q=DefinitelyTyped)~~ (use preferred alternatives, nuget DT type publishing has been turned off)
* ~~[NuGet](http://nuget.org/packages?q=DefinitelyTyped)~~ (use preferred alternatives, nuget DT type publishing has been turned off)
* Manually download from the `master` branch of this repository
You may need to add manual [references](http://www.typescriptlang.org/docs/handbook/triple-slash-directives.html).
@@ -88,8 +88,16 @@ First, [fork](https://guides.github.com/activities/forking/) this repository, in
* `cd types/my-package-to-edit`
* Make changes. Remember to edit tests.
* You may also want to add yourself to "Definitions by" section of the package header.
- This will cause you to be notified (via your GitHub username) whenever someone makes a pull request or issue about the package.
- Do this by adding your name to the end of the line, as in `// Definitions by: Alice <https://github.com/alice>, Bob <https://github.com/bob>`.
* `npm install -g typescript@2.0` and run `tsc`.
- Or if there are more people, it can be multiline
```typescript
// Definitions by: Alice <https://github.com/alice>
// Bob <https://github.com/bob>
// Steve <https://github.com/steve>
// John <https://github.com/john>
```
* If there is a `tslint.json`, run `npm run lint package-name`. Otherwise, run `tsc` in the package directory.
When you make a PR to edit an existing package, `dt-bot` should @-mention previous authors.
If it doesn't, you can do so yourself in the comment associated with the PR.
@@ -126,6 +134,7 @@ For a good example package, see [base64-js](https://github.com/DefinitelyTyped/D
* First, follow advice from the [handbook](http://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html).
* Formatting: Either use all tabs, or always use 4 spaces.
* `function sum(nums: number[]): number`: Use `ReadonlyArray` if a function does not write to its parameters.
* `interface Foo { new(): Foo; }`:
This defines a type of objects that are new-able. You probably want `declare class Foo { constructor(); }`.
* `const Class: { new(): IClass; }`:
@@ -136,6 +145,10 @@ For a good example package, see [base64-js](https://github.com/DefinitelyTyped/D
Example where a type parameter is acceptable: `function id<T>(value: T): T;`.
Example where it is not acceptable: `function parseJson<T>(json: string): T;`.
Exception: `new Map<string, number>()` is OK.
* Using the types `Function` and `Object` is almost never a good idea. In 99% of cases it's possible to specify a more specific type. Examples are `(x: number) => number` for [functions](http://www.typescriptlang.org/docs/handbook/functions.html#function-types) and `{ x: number, y: number }` for objects. If there is no certainty at all about the type, [`any`](http://www.typescriptlang.org/docs/handbook/basic-types.html#any) is the right choice, not `Object`. If the only known fact about the type is that it's some object, use the type [`object`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#object-type), not `Object` or `{ [key: string]: any }`.
* `var foo: string | any`:
When `any` is used in a union type, the resulting type is still `any`. So while the `string` portion of this type annotation may _look_ useful, it in fact offers no additional typechecking over simply using `any`.
Depending on the intention, acceptable alternatives could be `any`, `string`, or `string | object`.
#### Removing a package
@@ -170,6 +183,18 @@ If a `tslint.json` turns rules off, this is because that hasn't been fixed yet.
(To indicate that a lint rule truly does not apply, use `// tslint:disable rule-name` or better, `//tslint:disable-next-line rule-name`.)
To assert that an expression is of a given type, use `$ExpectType`. To assert that an expression causes a compile error, use `$ExpectError`.
```js
// $ExpectType void
f(1);
// $ExpectError
f("one");
```
For more details, see [dtslint](https://github.com/Microsoft/dtslint#write-tests) readme.
Test by running `npm run lint package-name` where `package-name` is the name of your package.
This script uses [dtslint](https://github.com/Microsoft/dtslint).
@@ -179,7 +204,14 @@ This script uses [dtslint](https://github.com/Microsoft/dtslint).
#### What exactly is the relationship between this repository and the `@types` packages on NPM?
The `master` branch is automatically published to the `@types` scope on NPM thanks to [types-publisher](https://github.com/Microsoft/types-publisher).
This usually happens within an hour of changes being merged.
#### I've submitted a pull request. How long until it is merged?
It depends, but most pull requests will be merged within a week. PRs that have been approved by an author listed in the definition's header are usually merged more quickly; PRs for new definitions will take more time as they require more review from maintainers. Each PR is reviewed by a TypeScript or DefinitelyTyped team member before being merged, so please be patient as human factors may cause delays. Check the [PR Burndown Board](https://github.com/DefinitelyTyped/DefinitelyTyped/projects/3?card_filter_query=is%3Aopen) to see progress as maintainers work through the open PRs.
#### My PR is merged; when will the `@types` NPM package be updated?
NPM packages should update within a few hours. If it's been more than 24 hours, ping @RyanCavanaugh and @andy-ms on the PR to investigate.
#### I'm writing a definition that depends on another definition. Should I use `<reference types="" />` or an import?
@@ -224,7 +256,7 @@ When it graduates draft mode, we may remove it from DefinitelyTyped and deprecat
#### I want to update a package to a new major version
Before making your change, please create a new subfolder with the current version e.g. `v2`, and copy existing files to it. You will need to:
If you intend to continue updating the older version of the package, you may create a new subfolder with the current version e.g. `v2`, and copy existing files to it. If so, you will need to:
1. Update the relative paths in `tsconfig.json` as well as `tslint.json`.
2. Add path mapping rules to ensure that tests are running against the intended version.
@@ -247,21 +279,53 @@ For example [history v2 `tsconfig.json`](https://github.com/DefinitelyTyped/Defi
}
```
Please note that unless upgrading something backwards-compatible like `node`, all packages depending of the updated package need a path mapping to it, as well as packages depending on *those*.
If there are other packages on DefinitelyTyped that are incompatible with the new version, you will need to add path mappings to the old version. You will also need to do this for packages depending on packages depending on the old version.
For example, `react-router` depends on `history@2`, so [react-router `tsconfig.json`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-router/tsconfig.json) has a path mapping to `"history": [ "history/v2" ]`;
transitively `react-router-bootstrap` (which depends on `react-router`) also adds a path mapping in its [tsconfig.json](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-router-bootstrap/tsconfig.json).
Also, `/// <reference types=".." />` will not work with path mapping, so dependencies must use `import`.
#### How do I write definitions for packages that can be used globally and as a module?
The TypeScript handbook contains excellent [general information about writing definitions](https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html), and also [this example definition file](https://www.typescriptlang.org/docs/handbook/declaration-files/templates/global-modifying-module-d-ts.html) which shows how to create a definition using ES6-style module syntax, while also specifying objects made available to the global scope. This technique is demonstrated practically in the [definition for big.js](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/big.js/index.d.ts), which is a library that can be loaded globally via script tag on a web page, or imported via require or ES6-style imports.
To test how your definition can be used both when referenced globally or as an imported module, create a `test` folder, and place two test files in there. Name one `YourLibraryName-global.test.ts` and the other `YourLibraryName-module.test.ts`. The *global* test file should exercise the definition according to how it would be used in a script loaded on a web page where the library is available on the global scope - in this scenario you should not specify an import statement. The *module* test file should exercise the definition according to how it would be used when imported (including the `import` statement(s)). If you specify a `files` property in your `tsconfig.json` file, be sure to include both test files. A [practical example of this](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/big.js/test) is also available on the big.js definition.
Please note that it is not required to fully exercise the definition in each test file - it is sufficient to test only the globally-accessible elements on the global test file and fully exercise the definition in the module test file, or vice versa.
#### What about scoped packages?
Types for a scoped package `@foo/bar` should go in `types/foo__bar`. Note the double underscore.
When `dts-gen` is used to scaffold a scoped package, the `paths` property has to be manually adapted in the generated
`tsconfig.json` to correctly reference the scoped package:
```json
{
"paths":{
"@foo/bar": ["foo__bar"]
}
}
```
#### The file history in GitHub looks incomplete.
GitHub doesn't [support](http://stackoverflow.com/questions/5646174/how-to-make-github-follow-directory-history-after-renames) file history for renamed files. Use [`git log --follow`](https://www.git-scm.com/docs/git-log) instead.
#### Should I add an empty namespace to a package that doesn't export a module to use ES6 style imports?
Some packages, like [chai-http](https://github.com/chaijs/chai-http), export a function.
Importing this module with an ES6 style import in the form `import * as foo from "foo";` leads to the error:
> error TS2497: Module 'foo' resolves to a non-module entity and cannot be imported using this construct
This error can be suppressed by merging the function declaration with an empty namespace of the same name, but this practice is discouraged.
This is a commonly cited [Stack Overflow answer](https://stackoverflow.com/questions/39415661/what-does-resolves-to-a-non-module-entity-and-cannot-be-imported-using-this) regarding this matter.
It is more appropriate to import the module using the `import foo = require("foo");` syntax, or to use a default import like `import foo from "foo";` if using the `--allowSyntheticDefaultImports` flag if your module runtime supports an interop scheme for non-ECMAScript modules as such.
## License
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -17,11 +17,11 @@
"scripts": {
"compile-scripts": "tsc -p scripts",
"not-needed": "node scripts/not-needed.js",
"test": "node node_modules/types-publisher/bin/tester/test.js --run-from-definitely-typed --nProcesses 1",
"test": "node node_modules/types-publisher/bin/tester/test.js --run-from-definitely-typed",
"lint": "dtslint types"
},
"devDependencies": {
"dtslint": "Microsoft/dtslint#production",
"dtslint": "github:Microsoft/dtslint#production",
"types-publisher": "Microsoft/types-publisher#production"
}
}
+10 -1
View File
@@ -39,7 +39,16 @@ function fix(config: any): any {
const out: any = {};
for (const key in config) {
let value = config[key];
out[key] = value;
out[key] = key === "rules" ? fixRules(value) : value;
}
return out;
}
function fixRules(rules: any): any {
const out: any = {};
for (const key in rules) {
out[key] = rules[key];
}
return out;
}
+1 -5
View File
@@ -5,11 +5,7 @@
import * as fs from 'fs';
import * as path from 'path';
function repeat(s: string, count: number) {
return Array(count + 1).join(s);
}
const home = path.join(__dirname, '..');
const home = path.join(__dirname, "..", "types");
for (const dirName of fs.readdirSync(home)) {
if (dirName.startsWith(".") || dirName === "node_modules" || dirName === "scripts") {
@@ -1,50 +0,0 @@
import packer = require("3d-bin-packing");
import samchon = require("samchon");
function main(): void
{
///////////////////////////
// CONSTRUCT OBJECTS
///////////////////////////
let wrapperArray: bws.packer.WrapperArray = new packer.WrapperArray();
let instanceArray: bws.packer.InstanceArray = new packer.InstanceArray();
// Wrappers
wrapperArray.push
(
new packer.Wrapper("Large", 1000, 40, 40, 15, 0),
new packer.Wrapper("Medium", 700, 20, 20, 10, 0),
new packer.Wrapper("Small", 500, 15, 15, 8, 0)
);
///////
// Each Instance is repeated #15
///////
instanceArray.insert(instanceArray.end(), 15, new packer.Product("Eraser", 1, 2, 5));
instanceArray.insert(instanceArray.end(), 15, new packer.Product("Book", 15, 30, 3));
instanceArray.insert(instanceArray.end(), 15, new packer.Product("Drink", 3, 3, 10));
instanceArray.insert(instanceArray.end(), 15, new packer.Product("Umbrella", 5, 5, 20));
// Wrappers also can be packed into another Wrapper.
instanceArray.insert(instanceArray.end(), 15, new packer.Wrapper("Notebook-Box", 2000, 30, 40, 4, 2));
instanceArray.insert(instanceArray.end(), 15, new packer.Wrapper("Tablet-Box", 2500, 20, 28, 2, 0));
///////////////////////////
// BEGINS PACKING
///////////////////////////
// CONSTRUCT PACKER
let my_packer: bws.packer.Packer = new packer.Packer(wrapperArray, instanceArray);
///////
// PACK (OPTIMIZE)
let result: bws.packer.WrapperArray = my_packer.optimize();
///////
///////////////////////////
// TRACE PACKING RESULT
///////////////////////////
let xml: samchon.library.XML = result.toXML();
console.log(xml.toString());
}
main();
-1383
View File
File diff suppressed because it is too large Load Diff
-23
View File
@@ -1,23 +0,0 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6",
"dom"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": false,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.d.ts",
"3d-bin-packing-tests.ts"
]
}
+13
View File
@@ -0,0 +1,13 @@
import abbrev = require('abbrev');
let abbrs: { [abbreviation: string]: string; };
abbrs = abbrev();
abbrs = abbrev('foo', 'fool', 'folding', 'flop');
abbrs = abbrev(['foo', 'fool', 'folding', 'flop']);
abbrev.monkeyPatch();
abbrs = [].abbrev();
const roArr: ReadonlyArray<string> = [];
abbrs = roArr.abbrev();
abbrs = ({}).abbrev();
+27
View File
@@ -0,0 +1,27 @@
// Type definitions for abbrev 1.1
// Project: https://github.com/isaacs/abbrev-js#readme
// Definitions by: BendingBender <https://github.com/BendingBender>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
export = abbrev;
declare function abbrev(words: string[]): {[abbreviation: string]: string};
declare function abbrev(...words: string[]): {[abbreviation: string]: string};
declare namespace abbrev {
function monkeyPatch(): void;
}
declare global {
interface Array<T> {
abbrev(): {[abbreviation: string]: string};
}
interface ReadonlyArray<T> {
abbrev(): {[abbreviation: string]: string};
}
interface Object {
abbrev(): {[abbreviation: string]: string};
}
}
+24
View File
@@ -0,0 +1,24 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
"abbrev-tests.ts"
]
}
-253
View File
@@ -1,253 +0,0 @@
import * as Ably from 'ably';
declare const console: { log(message: any): void };
const ApiKey = 'appId.keyId:secret';
const client = new Ably.Realtime(ApiKey);
const restClient = new Ably.Rest(ApiKey);
// Connection
// Successful connection:
client.connection.on('connected', () => {
// successful connection
});
// Failed connection:
client.connection.on('failed', () => {
// failed connection
});
// Subscribing to a channel
const channel = client.channels.get('test');
channel.subscribe(message => {
message.name; // 'greeting'
message.data; // 'Hello World!'
});
// Only certain events:
channel.subscribe('myEvent', message => {
message.name; // 'myEvent'
message.data; // 'myData'
});
// Publishing to a channel
// Publish a single message with name and data
channel.publish('greeting', 'Hello World!');
// Optionally, you can use a callback to be notified of success or failure
channel.publish('greeting', 'Hello World!', err => {
if (err) {
console.log('publish failed with error ' + err);
} else {
console.log('publish succeeded');
}
});
// Publish several messages at once
channel.publish([{name: 'greeting', data: 'Hello World!'}], () => { });
// Querying the History
channel.history((err, messagesPage) => {
messagesPage.items; // array of Message
messagesPage.items[0].data; // payload for first message
messagesPage.items.length; // number of messages in the current page of history
messagesPage.hasNext(); // true if there are further pages
messagesPage.isLast(); // true if this page is the last page
messagesPage.next(nextPage => { nextPage; }); // retrieves the next page as PaginatedResult
});
// Can optionally take an options param, see https://www.ably.io/documentation/rest-api/#message-history
channel.history({ start: Date.now() - 10000, end: Date.now(), limit: 100, direction: 'forwards'}, (err, messagesPage) => {
console.log(messagesPage.items.length);
});
// Presence on a channel
// Getting presence:
channel.presence.get(presenceSet => {
presenceSet; // array of PresenceMessages
});
// Note that presence#get on a realtime channel does not return a PaginatedResult, as the library maintains a local copy of the presence set.
// Entering (and leaving) the presence set:
channel.presence.enter('my status', err => {
// now I am entered
});
channel.presence.update('new status', err => {
// my presence data is updated
});
channel.presence.leave(null, err => {
// I've left the presence set
});
channel.presence.enterClient('myClientId', 'status', err => {
});
// and similiarly, updateClient and leaveClient
// Querying the Presence History
channel.presence.history((err, messagesPage) => { // PaginatedResult
messagesPage.items; // array of PresenceMessage
messagesPage.items[0].data; // payload for first message
messagesPage.items.length; // number of messages in the current page of history
messagesPage.hasNext(); // true if there are further pages
messagesPage.isLast(); // true if this page is the last page
messagesPage.next(nextPage => { }); // retrieves the next page as PaginatedResult
});
// Can optionally take an options param, see https://www.ably.io/documentation/rest-api/#message-history
channel.history({ start: Date.now() - 10000, end: Date.now(), limit: 100, direction: 'forwards' }, (err, messagesPage) => {});
// Symmetrical end-to-end encrypted payloads on a channel
// When a 128 bit or 256 bit key is provided to the library, the data attributes of all messages are encrypted and decrypted automatically using that key.
// The secret key is never transmitted to Ably. See https://www.ably.io/documentation/realtime/encryption
// Generate a random 256-bit key for demonstration purposes (in
// practice you need to create one and distribute it to clients yourselves)
Ably.Realtime.Crypto.generateRandomKey((err, key) => {
const channel = client.channels.get('channelName', { cipher: { key } });
channel.subscribe(message => {
message.name; // 'name is not encrypted'
message.data; // 'sensitive data is encrypted'
});
channel.publish('name is not encrypted', 'sensitive data is encrypted');
});
// You can also change the key on an existing channel using setOptions (which takes a callback which is called after the new encryption settings have taken effect):
channel.setOptions({cipher: {key: '<KEY>'}}, () => {
// New encryption settings are in effect
});
// Using the REST API
const restChannel = restClient.channels.get('test');
// Publishing to a channel
// Publish a single message with name and data
restChannel.publish('greeting', 'Hello World!');
// Optionally, you can use a callback to be notified of success or failure
restChannel.publish('greeting', 'Hello World!', err => {
if (err) {
console.log('publish failed with error ' + err);
} else {
console.log('publish succeeded');
}
});
// Publish several messages at once
restChannel.publish([{name: 'greeting', data: 'Hello World!'}], () => {});
// Querying the History
restChannel.history((err, messagesPage) => {
messagesPage; // PaginatedResult
messagesPage.items; // array of Message
messagesPage.items[0].data; // payload for first message
messagesPage.items.length; // number of messages in the current page of history
messagesPage.hasNext(); // true if there are further pages
messagesPage.isLast(); // true if this page is the last page
messagesPage.next(nextPage => {}); // retrieves the next page as PaginatedResult
});
// Can optionally take an options param, see https://www.ably.io/documentation/rest-api/#message-history
restChannel.history({ start: Date.now() - 10000, end: Date.now(), limit: 100, direction: 'forwards' }, (err, messagesPage) => {});
// Presence on a channel
restChannel.presence.get((err, presencePage) => { // PaginatedResult
presencePage.items; // array of PresenceMessage
presencePage.items[0].data; // payload for first message
presencePage.items.length; // number of messages in the current page of members
presencePage.hasNext(); // true if there are further pages
presencePage.isLast(); // true if this page is the last page
presencePage.next(nextPage => {}); // retrieves the next page as PaginatedResult
});
// Querying the Presence History
restChannel.presence.history((err, messagesPage) => { // PaginatedResult
messagesPage.items; // array of PresenceMessage
messagesPage.items[0].data; // payload for first message
messagesPage.items.length; // number of messages in the current page of history
messagesPage.hasNext(); // true if there are further pages
messagesPage.isLast(); // true if this page is the last page
messagesPage.next(nextPage => { }); // retrieves the next page as PaginatedResult
});
// Can optionally take an options param, see https://www.ably.io/documentation/rest-api/#message-history
restChannel.history({ start: Date.now() - 10000, end: Date.now(), limit: 100, direction: 'forwards' }, (err, messagesPage) => {});
// Generate Token and Token Request
// See https://www.ably.io/documentation/general/authentication for an explanation of Ably's authentication mechanism.
// Requesting a token:
client.auth.requestToken((err, tokenDetails) => {
// tokenDetails is instance of TokenDetails
// see https://www.ably.io/documentation/rest/authentication/#token-details for its properties
// Now we have the token, we can send it to someone who can instantiate a client with it:
const clientUsingToken = new Ably.Realtime(tokenDetails.token);
});
// requestToken can take two optional params
// tokenParams: https://www.ably.io/documentation/rest/authentication/#token-params
// authOptions: https://www.ably.io/documentation/rest/authentication/#auth-options
client.auth.requestToken({}, {}, (err, tokenDetails) => { });
// Creating a token request (for example, on a server in response to a request by a client using the authCallback or authUrl mechanisms):
client.auth.createTokenRequest((err, tokenRequest) => {
// now send the tokenRequest back to the client, which will
// use it to request a token and connect to Ably
});
// createTokenRequest can take two optional params
// tokenParams: https://www.ably.io/documentation/rest/authentication/#token-params
// authOptions: https://www.ably.io/documentation/rest/authentication/#auth-options
client.auth.createTokenRequest({}, {}, (err, tokenRequest) => { });
// Fetching your application's stats
client.stats({ limit: 50 }, (err, statsPage) => { // statsPage as PaginatedResult
statsPage.items; // array of Stats
statsPage.items[0].inbound.rest.messages.count; // total messages published over REST
statsPage.items.length; // number of stats in the current page of history
statsPage.hasNext(); // true if there are wrther pages
statsPage.isLast(); // true if this page is the last page
statsPage.next((nextPage) => {}); // retrieves the next page as PaginatedResult
});
// Fetching the Ably service time
client.time({}, (err, time) => {}); // time is in ms since epoch
// Getting decoded Message objects from JSON
const messages = Ably.Realtime.Message.fromEncodedArray([{ id: 'foo' }]);
console.log(messages[0].id);
const message = Ably.Rest.Message.fromEncoded({ id: 'foo' });
console.log(message.id);
// Getting decoded PresenceMessage objects from JSON
const presenceMessages = Ably.Realtime.PresenceMessage.fromEncodedArray([{ id: 'foo' }]);
console.log(presenceMessages[0].action);
const presenceMessage = Ably.Rest.PresenceMessage.fromEncoded({ id: 'foo' });
console.log(presenceMessage.action);
-473
View File
@@ -1,473 +0,0 @@
// Type definitions for Ably Realtime and Rest client library 0.9
// Project: https://www.ably.io/
// Definitions by: Ably <https://github.com/ably/>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
export namespace ablyLib {
namespace ChannelState {
type INITIALIZED = 'initialized';
type ATTACHING = 'attaching';
type ATTACHED = "attached";
type DETACHING = "detaching";
type DETACHED = "detached";
type SUSPENDED = "suspended";
type FAILED = "failed";
}
type ChannelState = ChannelState.FAILED | ChannelState.INITIALIZED | ChannelState.SUSPENDED | ChannelState.ATTACHED | ChannelState.ATTACHING | ChannelState.DETACHED | ChannelState.DETACHING;
namespace ConnectionState {
type INITIALIZED = "initialized";
type CONNECTING = "connecting";
type CONNECTED = "connected";
type DISCONNECTED = "disconnected";
type SUSPENDED = "suspended";
type CLOSING = "closing";
type CLOSED = "closed";
type FAILED = "failed";
}
type ConnectionState = ConnectionState.INITIALIZED | ConnectionState.CONNECTED | ConnectionState.CONNECTING | ConnectionState.DISCONNECTED |
ConnectionState.SUSPENDED | ConnectionState.CLOSED | ConnectionState.CLOSING | ConnectionState.FAILED;
namespace ConnectionEvent {
type INITIALIZED = "initialized";
type CONNECTING = "connecting";
type CONNECTED = "connected";
type DISCONNECTED = "disconnected";
type SUSPENDED = "suspended";
type CLOSING = "closing";
type CLOSED = "closed";
type FAILED = "failed";
type UPDATE = "update";
}
type ConnectionEvent = ConnectionEvent.INITIALIZED | ConnectionEvent.CONNECTED | ConnectionEvent.CONNECTING | ConnectionEvent.DISCONNECTED |
ConnectionEvent.SUSPENDED | ConnectionEvent.CLOSED | ConnectionEvent.CLOSING | ConnectionEvent.FAILED | ConnectionEvent.UPDATE;
namespace PresenceAction {
type ABSENT = "absent";
type PRESENT = "present";
type ENTER = "enter";
type LEAVE = "leave";
type UPDATE = "update";
}
type PresenceAction = PresenceAction.ABSENT | PresenceAction.PRESENT | PresenceAction.ENTER | PresenceAction.LEAVE | PresenceAction.UPDATE;
namespace StatsIntervalGranularity {
type MINUTE = "minute";
type HOUR = "hour";
type DAY = "day";
type MONTH = "month";
}
type StatsIntervalGranularity = StatsIntervalGranularity.MINUTE | StatsIntervalGranularity.HOUR | StatsIntervalGranularity.DAY | StatsIntervalGranularity.MONTH;
namespace HTTPMethods {
type POST = "POST";
type GET = "GET";
}
type HTTPMethods = HTTPMethods.GET | HTTPMethods.POST;
// Interfaces
interface ClientOptions extends AuthOptions {
/**
* When true will automatically connect to Ably when library is instanced. This is true by default
*/
autoConnect?: boolean;
/**
* Optional clientId that can be used to specify the identity for this client. In most cases
* it is preferable to instead specift a clientId in the token issued to this client.
*/
clientId?: string;
defaultTokenParams?: TokenParams;
/**
* When true, messages published on channels by this client will be echoed back to this client.
* This is true by default
*/
echoMessages?: boolean;
/**
* Use this only if you have been provided a dedicated environment by Ably
*/
environment?: string;
/**
* Logger configuration
*/
log?: LogInfo;
port?: number;
/**
* When true, messages will be queued whilst the connection is disconnected. True by default.
*/
queueMessages?: boolean;
restHost?: string;
realtimeHost?: string;
fallbackHosts?: string[];
/**
* Can be used to explicitly recover a connection.
* See https://www.ably.io/documentation/realtime/connection#connection-state-recovery
*/
recover?: standardCallback | string;
/**
* Use a non-secure connection connection. By default, a TLS connection is used to connect to Ably
*/
tls?: boolean;
tlsPort?: number;
/**
* When true, the more efficient MsgPack binary encoding is used.
* When false, JSON text encoding is used.
*/
useBinaryProtocol?: boolean;
}
interface AuthOptions {
/**
* A function which is called when a new token is required.
* The role of the callback is to either generate a signed TokenRequest which may then be submitted automatically
* by the library to the Ably REST API requestToken; or to provide a valid token in as a TokenDetails object.
*/
authCallback?(data: TokenParams, callback: (error: ErrorInfo | string, tokenRequestOrDetails: TokenDetails | TokenRequest | string) => void): void;
authHeaders?: { [index: string]: string };
authMethod?: HTTPMethods;
authParams?: { [index: string]: string };
/**
* A URL that the library may use to obtain a token string (in plain text format), or a signed TokenRequest or TokenDetails (in JSON format).
*/
authUrl?: string;
key?: string;
queryTime?: boolean;
token?: TokenDetails | string;
tokenDetails?: TokenDetails;
useTokenAuth?: boolean;
}
interface TokenParams {
capability?: string;
clientId?: string;
nonce?: string;
timestamp?: number;
ttl?: number;
}
interface CipherParams {
algorithm: string;
key: any;
keyLength: number;
mode: string;
}
interface ErrorInfo {
code: number;
message: string;
statusCode: number;
}
interface StatsMessageCount {
count: number;
data: number;
}
interface StatsMessageTypes {
all: StatsMessageCount;
messages: StatsMessageCount;
presence: StatsMessageCount;
}
interface StatsRequestCount {
failed: number;
refused: number;
succeeded: number;
}
interface StatsResourceCount {
mean: number;
min: number;
opened: number;
peak: number;
refused: number;
}
interface StatsConnectionTypes {
all: StatsResourceCount;
plain: StatsResourceCount;
tls: StatsResourceCount;
}
interface StatsMessageTraffic {
all: StatsMessageTypes;
realtime: StatsMessageTypes;
rest: StatsMessageTypes;
webhook: StatsMessageTypes;
}
interface TokenDetails {
capability: string;
clientId?: string;
expires: number;
issued: number;
token: string;
}
interface TokenRequest {
capability: string;
clientId?: string;
keyName: string;
mac: string;
nonce: string;
timestamp: number;
ttl?: number;
}
interface ChannelOptions {
cipher: any;
}
interface RestPresenceHistoryParams {
start?: number;
end?: number;
direction?: string;
limit?: number;
}
interface RestPresenceParams {
limit?: number;
clientId?: string;
connectionId?: string;
}
interface RealtimePresenceParams {
waitForSync?: boolean;
clientId?: string;
connectionId?: string;
}
interface RealtimePresenceHistoryParams {
start?: number;
end?: number;
direction?: string;
limit?: number;
untilAttach?: boolean;
}
interface LogInfo {
/**
* A number controlling the verbosity of the output. Valid values are: 0 (no logs), 1 (errors only),
* 2 (errors plus connection and channel state changes), 3 (high-level debug output), and 4 (full debug output).
*/
level?: number;
/**
* A function to handle each line of log output. If handler is not specified, console.log is used.
*/
handler?(...args: any[]): void;
}
interface ChannelEvent {
state: ChannelState;
}
interface ChannelStateChange {
current: ChannelState;
previous: ChannelState;
reason?: ErrorInfo;
resumed: boolean;
}
interface ConnectionStateChange {
current: ConnectionState;
previous: ConnectionState;
reason?: ErrorInfo;
retryIn?: number;
}
// Common Listeners
type paginatedResultCallback<T> = (error: ErrorInfo, results: PaginatedResult<T> ) => void;
type standardCallback = (error: ErrorInfo, results: any) => void;
type messageCallback<T> = (message: T) => void;
type errorCallback = (error: ErrorInfo) => void;
type channelEventCallback = (channelEvent: ChannelEvent, changeStateChange: ChannelStateChange) => void;
type connectionEventCallback = (connectionEvent: ConnectionEvent, connectionStateChange: ConnectionStateChange) => void;
type timeCallback = (error: ErrorInfo, time: number) => void;
type realtimePresenceGetCallback = (error: ErrorInfo, messages: PresenceMessage[]) => void;
type tokenDetailsCallback = (error: ErrorInfo, Results: TokenDetails) => void;
type tokenRequestCallback = (error: ErrorInfo, Results: TokenRequest) => void;
type fromEncoded<T> = (JsonObject: any, channelOptions?: ChannelOptions) => T;
type fromEncodedArray<T> = (JsonArray: any[], channelOptions?: ChannelOptions) => T[];
// Internal Classes
class EventEmitter<T> {
on: (eventOrCallback: string | T, callback?: T) => void;
once: (eventOrCallback: string | T, callback?: T) => void;
off: (eventOrCallback?: string | T, callback?: T) => void;
}
// Classes
class Auth {
clientId: string;
authorize: (tokenParams?: TokenParams | tokenDetailsCallback, authOptions?: AuthOptions | tokenDetailsCallback, callback?: tokenDetailsCallback) => void;
createTokenRequest: (tokenParams?: TokenParams | tokenRequestCallback, authOptions?: AuthOptions | tokenRequestCallback, callback?: tokenRequestCallback) => void;
requestToken: (TokenParams?: TokenParams | tokenDetailsCallback, authOptions?: AuthOptions | tokenDetailsCallback, callback?: tokenDetailsCallback) => void;
}
class Presence {
get: (params: RestPresenceParams | paginatedResultCallback<PresenceMessage>, callback?: paginatedResultCallback<PresenceMessage>) => void;
history: (params: RestPresenceHistoryParams | paginatedResultCallback<PresenceMessage>, callback?: paginatedResultCallback<PresenceMessage>) => void;
}
class RealtimePresence {
syncComplete: () => boolean;
get: (Params: realtimePresenceGetCallback | RealtimePresenceParams, callback?: realtimePresenceGetCallback) => void;
history: (ParamsOrCallback: RealtimePresenceHistoryParams | paginatedResultCallback<PresenceMessage>, callback?: paginatedResultCallback<PresenceMessage>) => void;
subscribe: (presenceOrCallback: PresenceAction | messageCallback<PresenceMessage>, listener?: messageCallback<PresenceMessage>) => void;
unsubscribe: (presence?: PresenceAction, listener?: messageCallback<PresenceMessage>) => void;
enter: (data?: errorCallback | any, callback?: errorCallback) => void;
update: (data?: errorCallback | any, callback?: errorCallback) => void;
leave: (data?: errorCallback | any, callback?: errorCallback) => void;
enterClient: (clientId: string, data?: errorCallback | any, callback?: errorCallback) => void;
updateClient: (clientId: string, data?: errorCallback | any, callback?: errorCallback) => void;
leaveClient: (clientId: string, data?: errorCallback | any, callback?: errorCallback) => void;
}
class Channel {
name: string;
presence: Presence;
history: (paramsOrCallback?: RestPresenceHistoryParams | paginatedResultCallback<Message>, callback?: paginatedResultCallback<Message>) => void;
publish: (messagesOrName: any, messagedataOrCallback?: errorCallback | any, callback?: errorCallback) => void;
}
class RealtimeChannel extends EventEmitter<channelEventCallback> {
name: string;
errorReason: ErrorInfo;
state: ChannelState;
presence: RealtimePresence;
attach: (callback?: standardCallback) => void;
detach: (callback?: standardCallback) => void;
history: (paramsOrCallback?: RealtimePresenceHistoryParams | paginatedResultCallback<Message>, callback?: paginatedResultCallback<Message>) => void;
subscribe: (eventOrCallback: messageCallback<Message> | string, listener?: messageCallback<Message>) => void;
unsubscribe: (eventOrCallback?: messageCallback<Message> | string, listener?: messageCallback<Message>) => void;
publish: (messagesOrName: any, messageDataOrCallback?: errorCallback | any, callback?: errorCallback) => void;
setOptions: (options: any, callback?: errorCallback) => void;
}
class Channels<T> {
get: (name: string, channelOptions?: ChannelOptions) => T;
release: (name: string) => void;
}
class Message {
constructor();
static fromEncoded: fromEncoded<Message>;
static fromEncodedArray: fromEncodedArray<Message>;
clientId: string;
connectionId: string;
data: any;
encoding: string;
extras: any;
id: string;
name: string;
timestamp: number;
}
interface MessageStatic {
fromEncoded: fromEncoded<Message>;
fromEncodedArray: fromEncodedArray<Message>;
}
class PresenceMessage {
constructor();
static fromEncoded: fromEncoded<PresenceMessage>;
static fromEncodedArray: fromEncodedArray<PresenceMessage>;
action: PresenceAction;
clientId: string;
connectionId: string;
data: any;
encoding: string;
id: string;
timestamp: number;
}
interface PresenceMessageStatic {
fromEncoded: fromEncoded<PresenceMessage>;
fromEncodedArray: fromEncodedArray<PresenceMessage>;
}
interface Crypto {
generateRandomKey(callback: (error: ErrorInfo, key: string) => void): void;
}
class Connection extends EventEmitter<connectionEventCallback> {
errorReason: ErrorInfo;
id: string;
key: string;
recoveryKey: string;
serial: number;
state: ConnectionState;
close: () => void;
connect: () => void;
ping: (callback?: (error: ErrorInfo, responseTime: number ) => void ) => void;
}
class Stats {
all: StatsMessageTypes;
apiRequests: StatsRequestCount;
channels: StatsResourceCount;
connections: StatsConnectionTypes;
inbound: StatsMessageTraffic;
intervalId: string;
outbound: StatsMessageTraffic;
persisted: StatsMessageTypes;
tokenRequests: StatsRequestCount;
}
class PaginatedResult<T> {
items: T[];
first: (results: paginatedResultCallback<T>) => void;
next: (results: paginatedResultCallback<T>) => void;
current: (results: paginatedResultCallback<T>) => void;
hasNext: () => boolean;
isLast: () => boolean;
}
class HttpPaginatedResponse extends PaginatedResult<any> {
items: string[];
statusCode: number;
success: boolean;
errorCode: number;
errorMessage: string;
headers: any;
}
}
export class Rest {
constructor(options: ablyLib.ClientOptions | string);
static Crypto: ablyLib.Crypto;
static Message: ablyLib.MessageStatic;
static PresenceMessage: ablyLib.PresenceMessageStatic;
auth: ablyLib.Auth;
channels: ablyLib.Channels<ablyLib.Channel>;
request: (method: string, path: string, params?: any, body?: any[] | any, headers?: any, callback?: (error: ablyLib.ErrorInfo, response: ablyLib.HttpPaginatedResponse) => void) => void;
stats: (paramsOrCallback?: ablyLib.paginatedResultCallback<ablyLib.Stats> | any, callback?: ablyLib.paginatedResultCallback<ablyLib.Stats>) => void;
time: (paramsOrCallback?: ablyLib.timeCallback | any, callback?: ablyLib.timeCallback) => void;
}
export class Realtime {
constructor(options: ablyLib.ClientOptions | string);
static Crypto: ablyLib.Crypto;
static Message: ablyLib.MessageStatic;
static PresenceMessage: ablyLib.PresenceMessageStatic;
auth: ablyLib.Auth;
channels: ablyLib.Channels<ablyLib.RealtimeChannel>;
clientId: string;
connection: ablyLib.Connection;
request: (method: string, path: string, params?: any, body?: any[] | any, headers?: any, callback?: (error: ablyLib.ErrorInfo, response: ablyLib.HttpPaginatedResponse) => void) => void;
stats: (paramsOrCallback?: ablyLib.paginatedResultCallback<ablyLib.Stats> | any, callback?: ablyLib.paginatedResultCallback<ablyLib.Stats>) => void;
close: () => void;
connect: () => void;
time: (paramsOrCallback?: ablyLib.timeCallback | any, callback?: ablyLib.timeCallback) => void;
}
-22
View File
@@ -1,22 +0,0 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.d.ts",
"ably-tests.ts"
]
}
+3 -1
View File
@@ -7,13 +7,15 @@
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
+3 -1
View File
@@ -7,13 +7,15 @@
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": false,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
+79
View File
@@ -0,0 +1,79 @@
{
"extends": "dtslint/dt.json",
"rules": {
"adjacent-overload-signatures": false,
"array-type": false,
"arrow-return-shorthand": false,
"ban-types": false,
"callable-types": false,
"comment-format": false,
"dt-header": false,
"eofline": false,
"export-just-namespace": false,
"import-spacing": false,
"interface-name": false,
"interface-over-type-literal": false,
"jsdoc-format": false,
"max-line-length": false,
"member-access": false,
"new-parens": false,
"no-any-union": false,
"no-boolean-literal-compare": false,
"no-conditional-assignment": false,
"no-consecutive-blank-lines": false,
"no-construct": false,
"no-declare-current-package": false,
"no-duplicate-imports": false,
"no-duplicate-variable": false,
"no-empty-interface": false,
"no-for-in-array": false,
"no-inferrable-types": false,
"no-internal-module": false,
"no-irregular-whitespace": false,
"no-mergeable-namespace": false,
"no-misused-new": false,
"no-namespace": false,
"no-object-literal-type-assertion": false,
"no-padding": false,
"no-redundant-jsdoc": false,
"no-redundant-jsdoc-2": false,
"no-redundant-undefined": false,
"no-reference-import": false,
"no-relative-import-in-test": false,
"no-self-import": false,
"no-single-declare-module": false,
"no-string-throw": false,
"no-unnecessary-callback-wrapper": false,
"no-unnecessary-class": false,
"no-unnecessary-generics": false,
"no-unnecessary-qualifier": false,
"no-unnecessary-type-assertion": false,
"no-useless-files": false,
"no-var-keyword": false,
"no-var-requires": false,
"no-void-expression": false,
"no-trailing-whitespace": false,
"object-literal-key-quotes": false,
"object-literal-shorthand": false,
"one-line": false,
"one-variable-per-declaration": false,
"only-arrow-functions": false,
"prefer-conditional-expression": false,
"prefer-const": false,
"prefer-declare-function": false,
"prefer-for-of": false,
"prefer-method-signature": false,
"prefer-template": false,
"radix": false,
"semicolon": false,
"space-before-function-paren": false,
"space-within-parens": false,
"strict-export-declare-modifiers": false,
"trim-file": false,
"triple-equals": false,
"typedef-whitespace": false,
"unified-signatures": false,
"void-return": false,
"whitespace": false
}
}
+2 -1
View File
@@ -2,6 +2,7 @@
// Project: https://github.com/sathomas/acc-wizard
// Definitions by: Cyril Schumacher <https://github.com/cyrilschumacher>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.3
interface AccWizardOptions {
/**
@@ -110,4 +111,4 @@ interface AccWizardOptions {
*/
interface JQuery {
accwizard(options?: AccWizardOptions): void;
}
}
+3 -1
View File
@@ -8,13 +8,15 @@
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": false,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
+79
View File
@@ -0,0 +1,79 @@
{
"extends": "dtslint/dt.json",
"rules": {
"adjacent-overload-signatures": false,
"array-type": false,
"arrow-return-shorthand": false,
"ban-types": false,
"callable-types": false,
"comment-format": false,
"dt-header": false,
"eofline": false,
"export-just-namespace": false,
"import-spacing": false,
"interface-name": false,
"interface-over-type-literal": false,
"jsdoc-format": false,
"max-line-length": false,
"member-access": false,
"new-parens": false,
"no-any-union": false,
"no-boolean-literal-compare": false,
"no-conditional-assignment": false,
"no-consecutive-blank-lines": false,
"no-construct": false,
"no-declare-current-package": false,
"no-duplicate-imports": false,
"no-duplicate-variable": false,
"no-empty-interface": false,
"no-for-in-array": false,
"no-inferrable-types": false,
"no-internal-module": false,
"no-irregular-whitespace": false,
"no-mergeable-namespace": false,
"no-misused-new": false,
"no-namespace": false,
"no-object-literal-type-assertion": false,
"no-padding": false,
"no-redundant-jsdoc": false,
"no-redundant-jsdoc-2": false,
"no-redundant-undefined": false,
"no-reference-import": false,
"no-relative-import-in-test": false,
"no-self-import": false,
"no-single-declare-module": false,
"no-string-throw": false,
"no-unnecessary-callback-wrapper": false,
"no-unnecessary-class": false,
"no-unnecessary-generics": false,
"no-unnecessary-qualifier": false,
"no-unnecessary-type-assertion": false,
"no-useless-files": false,
"no-var-keyword": false,
"no-var-requires": false,
"no-void-expression": false,
"no-trailing-whitespace": false,
"object-literal-key-quotes": false,
"object-literal-shorthand": false,
"one-line": false,
"one-variable-per-declaration": false,
"only-arrow-functions": false,
"prefer-conditional-expression": false,
"prefer-const": false,
"prefer-declare-function": false,
"prefer-for-of": false,
"prefer-method-signature": false,
"prefer-template": false,
"radix": false,
"semicolon": false,
"space-before-function-paren": false,
"space-within-parens": false,
"strict-export-declare-modifiers": false,
"trim-file": false,
"triple-equals": false,
"typedef-whitespace": false,
"unified-signatures": false,
"void-return": false,
"whitespace": false
}
}
@@ -0,0 +1,25 @@
// https://github.com/opentable/accept-language-parser/blob/v1.4.1/index.js
import * as AcceptLanguageParser from 'accept-language-parser';
const l1: AcceptLanguageParser.Language = {
code: 'en',
script: 'Latn',
region: 'GB',
quality: 0.9
};
const l2: AcceptLanguageParser.Language = {
code: 'en',
quality: 0.9
};
const l3: AcceptLanguageParser.Language = {
code: 'en',
script: null,
quality: 0.9
};
const parsed1: AcceptLanguageParser.Language[] = AcceptLanguageParser.parse('');
const pick1: string | null = AcceptLanguageParser.pick([''], '');
const pick2: string | null = AcceptLanguageParser.pick([''], [l1, l2, l3]);
+17
View File
@@ -0,0 +1,17 @@
// Type definitions for accept-language-parser 1.4
// Project: https://github.com/opentable/accept-language-parser
// Definitions by: Niklas Wulf <https://github.com/kampfgnom>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.1
// https://github.com/opentable/accept-language-parser/blob/v1.4.1/index.js
export function parse(acceptLanguage: string): Language[];
export function pick(supportedLanguages: string[], acceptLanguage: string | Language[]): string | null;
export interface Language {
code: string;
script?: string | null;
region?: string;
quality: number;
}
@@ -0,0 +1,24 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
"accept-language-parser-tests.ts"
]
}
+11 -12
View File
@@ -1,13 +1,14 @@
// Type definitions for accepts 1.3
// Project: https://github.com/jshttp/accepts
// Definitions by: Stefan Reichel <https://github.com/bomret>
// Brice BERNARD <https://github.com/brikou>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare namespace accepts {
interface Headers {
[key: string]: string | string[];
}
/// <reference types="node" />
import { IncomingMessage } from "http";
declare namespace accepts {
interface Accepts {
/**
* Return the first accepted charset. If nothing in `charsets` is accepted, then `false` is returned.
@@ -44,19 +45,17 @@ declare namespace accepts {
/**
* Return the first accepted type (and it is returned as the same text as what appears in the `types` array). If nothing in `types` is accepted, then `false` is returned.
* If no types are supplied, return the entire set of acceptable types.
*
* The `types` array can contain full MIME types or file extensions. Any value that is not a full MIME types is passed to `require('mime-types').lookup`.
*/
type(types: string[]): string | false;
type(...types: string[]): string | false;
/**
* Return the types that the request accepts, in the order of the client's preference (most preferred first).
*/
types(): string[];
type(types: string[]): string[] | string | false;
type(...types: string[]): string[] | string | false;
types(types: string[]): string[] | string | false;
types(...types: string[]): string[] | string | false;
}
}
declare function accepts(req: { headers: accepts.Headers }): accepts.Accepts;
declare function accepts(req: IncomingMessage): accepts.Accepts;
export = accepts;
+3 -1
View File
@@ -7,13 +7,15 @@
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
+3
View File
@@ -3,6 +3,9 @@
// Default usage:
accounting.formatMoney(12345678); // $12,345,678.00
// Stringified usage:
accounting.formatMoney('$4394958309392.9401'); // $4,394,958,309,392.94
// European formatting (custom symbol and separators), could also use options object as second param:
accounting.formatMoney(4999.99, "€", 2, ".", ","); // €4.999,99
+7 -6
View File
@@ -1,6 +1,7 @@
// Type definitions for accounting.js 0.3
// Project: http://josscrowcroft.github.io/accounting.js/
// Definitions by: Sergey Gerasimov <https://github.com/gerich-home/>
// Type definitions for accounting.js 0.4
// Project: http://openexchangerates.github.io/accounting.js/
// Definitions by: Sergey Gerasimov <https://github.com/gerich-home>
// Christopher Eck <https://github.com/chrisleck>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare namespace accounting {
@@ -30,9 +31,9 @@ declare namespace accounting {
}
interface Static {
// format any number into currency
formatMoney(number: number, symbol?: string, precision?: number, thousand?: string, decimal?: string, format?: string): string;
formatMoney(number: number, options: CurrencySettings<string> | CurrencySettings<CurrencyFormat>): string;
// format any number or stringified number into currency
formatMoney(number: number | string, symbol?: string, precision?: number, thousand?: string, decimal?: string, format?: string): string;
formatMoney(number: number | string, options: CurrencySettings<string> | CurrencySettings<CurrencyFormat>): string;
formatMoney(numbers: number[], symbol?: string, precision?: number, thousand?: string, decimal?: string, format?: string): string[];
formatMoney(numbers: number[], options: CurrencySettings<string> | CurrencySettings<CurrencyFormat>): string[];
+3 -1
View File
@@ -7,13 +7,15 @@
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": false,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
+65 -11
View File
@@ -345,18 +345,47 @@ declare namespace AceAjax {
insert(position: Position, text: string): any;
/**
* Inserts the elements in `lines` into the document, starting at the row index given by `row`. This method also triggers the `'change'` event.
* @param row The index of the row to insert at
* @param lines An array of strings
**/
* @deprecated Use the insertFullLines method instead.
*/
insertLines(row: number, lines: string[]): any;
/**
* Inserts a new line into the document at the current row's `position`. This method also triggers the `'change'` event.
* @param position The position to insert at
**/
* Inserts the elements in `lines` into the document as full lines (does not merge with existing line), starting at the row index given by `row`. This method also triggers the `"change"` event.
* @param {Number} row The index of the row to insert at
* @param {Array} lines An array of strings
* @returns {Object} Contains the final row and column, like this:
* ```
* {row: endRow, column: 0}
* ```
* If `lines` is empty, this function returns an object containing the current row, and column, like this:
* ```
* {row: row, column: 0}
* ```
*
**/
insertFullLines(row: number, lines: string[]): any;
/**
* @deprecated Use insertMergedLines(position, ['', '']) instead.
*/
insertNewLine(position: Position): any;
/**
* Inserts the elements in `lines` into the document, starting at the position index given by `row`. This method also triggers the `"change"` event.
* @param {Number} row The index of the row to insert at
* @param {Array} lines An array of strings
* @returns {Object} Contains the final row and column, like this:
* ```
* {row: endRow, column: 0}
* ```
* If `lines` is empty, this function returns an object containing the current row, and column, like this:
* ```
* {row: row, column: 0}
* ```
*
**/
insertMergedLines(row: number, lines: string[]): any;
/**
* Inserts `text` into the `position` at the current row. This method also triggers the `'change'` event.
* @param position The position to insert at
@@ -379,12 +408,19 @@ declare namespace AceAjax {
removeInLine(row: number, startColumn: number, endColumn: number): any;
/**
* Removes a range of full lines. This method also triggers the `'change'` event.
* @param firstRow The first row to be removed
* @param lastRow The last row to be removed
**/
* @deprecated Use the removeFullLines method instead.
*/
removeLines(firstRow: number, lastRow: number): string[];
/**
* Removes a range of full lines. This method also triggers the `"change"` event.
* @param {Number} firstRow The first row to be removed
* @param {Number} lastRow The last row to be removed
* @returns {[String]} Returns all the removed lines.
*
**/
removeFullLines(firstRow: number, lastRow: number): string[];
/**
* Removes the new line between `row` and the row immediately following it. This method also triggers the `'change'` event.
* @param row The row to check
@@ -475,6 +511,8 @@ declare namespace AceAjax {
expandFold(arg: any): void;
foldAll(startRow?: number, endRow?: number, depth?: number): void
unfold(arg1: any, arg2: boolean): void;
screenToDocumentColumn(row: number, column: number): void;
@@ -1039,6 +1077,12 @@ declare namespace AceAjax {
addEventListener(ev: 'change', callback: (ev: EditorChangeEvent) => any): void;
addEventListener(ev: string, callback: Function): void;
off(ev: string, callback: Function): void;
removeListener(ev: string, callback: Function): void;
removeEventListener(ev: string, callback: Function): void;
inMultiSelectMode: boolean;
selectMoreLines(n: number): void;
@@ -2164,8 +2208,16 @@ declare namespace AceAjax {
**/
export interface Selection {
on(ev: string, callback: Function): void;
addEventListener(ev: string, callback: Function): void;
off(ev: string, callback: Function): void;
removeListener(ev: string, callback: Function): void;
removeEventListener(ev: string, callback: Function): void;
moveCursorWordLeft(): void;
moveCursorWordRight(): void;
@@ -2644,6 +2696,8 @@ declare namespace AceAjax {
lineHeight: number;
setScrollMargin(top:number, bottom:number, left: number, right: number): void;
screenToTextCoordinates(left: number, top: number): void;
/**
+1
View File
@@ -15,6 +15,7 @@ const aceVirtualRendererTests = {
var renderer = new AceAjax.VirtualRenderer(el);
renderer.setPadding(0);
renderer.setScrollMargin(0,0,0,0)
renderer.setSession(new AceAjax.EditSession("1234"));
var r = renderer.scroller.getBoundingClientRect();
+3 -1
View File
@@ -8,13 +8,15 @@
"noImplicitAny": false,
"noImplicitThis": false,
"strictNullChecks": false,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
+79
View File
@@ -0,0 +1,79 @@
{
"extends": "dtslint/dt.json",
"rules": {
"adjacent-overload-signatures": false,
"array-type": false,
"arrow-return-shorthand": false,
"ban-types": false,
"callable-types": false,
"comment-format": false,
"dt-header": false,
"eofline": false,
"export-just-namespace": false,
"import-spacing": false,
"interface-name": false,
"interface-over-type-literal": false,
"jsdoc-format": false,
"max-line-length": false,
"member-access": false,
"new-parens": false,
"no-any-union": false,
"no-boolean-literal-compare": false,
"no-conditional-assignment": false,
"no-consecutive-blank-lines": false,
"no-construct": false,
"no-declare-current-package": false,
"no-duplicate-imports": false,
"no-duplicate-variable": false,
"no-empty-interface": false,
"no-for-in-array": false,
"no-inferrable-types": false,
"no-internal-module": false,
"no-irregular-whitespace": false,
"no-mergeable-namespace": false,
"no-misused-new": false,
"no-namespace": false,
"no-object-literal-type-assertion": false,
"no-padding": false,
"no-redundant-jsdoc": false,
"no-redundant-jsdoc-2": false,
"no-redundant-undefined": false,
"no-reference-import": false,
"no-relative-import-in-test": false,
"no-self-import": false,
"no-single-declare-module": false,
"no-string-throw": false,
"no-unnecessary-callback-wrapper": false,
"no-unnecessary-class": false,
"no-unnecessary-generics": false,
"no-unnecessary-qualifier": false,
"no-unnecessary-type-assertion": false,
"no-useless-files": false,
"no-var-keyword": false,
"no-var-requires": false,
"no-void-expression": false,
"no-trailing-whitespace": false,
"object-literal-key-quotes": false,
"object-literal-shorthand": false,
"one-line": false,
"one-variable-per-declaration": false,
"only-arrow-functions": false,
"prefer-conditional-expression": false,
"prefer-const": false,
"prefer-declare-function": false,
"prefer-for-of": false,
"prefer-method-signature": false,
"prefer-template": false,
"radix": false,
"semicolon": false,
"space-before-function-paren": false,
"space-within-parens": false,
"strict-export-declare-modifiers": false,
"trim-file": false,
"triple-equals": false,
"typedef-whitespace": false,
"unified-signatures": false,
"void-return": false,
"whitespace": false
}
}
+5 -1
View File
@@ -2,6 +2,7 @@
// Project: https://github.com/optimalbits/node_acl
// Definitions by: Qubo <https://github.com/tkQubo>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.3
/// <reference types="bluebird" />
/// <reference types="node"/>
@@ -49,7 +50,10 @@ interface Acl {
allowedPermissions: (userId: Value, resources: strings, cb?: AnyCallback) => Promise<void>;
isAllowed: (userId: Value, resources: strings, permissions: strings, cb?: AllowedCallback) => Promise<boolean>;
areAnyRolesAllowed: (roles: strings, resource: strings, permissions: strings, cb?: AllowedCallback) => Promise<any>;
whatResources: (roles: strings, permissions: strings, cb?: AnyCallback) => Promise<any>;
whatResources: {
(roles: strings, cb?: AnyCallback): Promise<any>;
(roles: strings, permissions: strings, cb?: AnyCallback): Promise<any>;
}
permittedResources: (roles: strings, permissions: strings, cb?: Function) => Promise<void>;
middleware: (numPathComponents?: number, userId?: Value | GetUserId, actions?: strings) => express.RequestHandler;
}
+12
View File
@@ -66,6 +66,18 @@ acl.isAllowed('joed', 'blogs', 'view', (err, res) => {
}
});
acl.whatResources('foo', (err, res) => {
if (res) {
console.log(res);
}
});
acl.whatResources('foo', 'view', (err, res) => {
if (res) {
console.log(res);
}
});
acl.isAllowed('jsmith', 'blogs', ['edit','view','delete'])
.then((result) => {
console.dir('jsmith is allowed blogs ' + result);
+3 -1
View File
@@ -7,13 +7,15 @@
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": false,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
+79
View File
@@ -0,0 +1,79 @@
{
"extends": "dtslint/dt.json",
"rules": {
"adjacent-overload-signatures": false,
"array-type": false,
"arrow-return-shorthand": false,
"ban-types": false,
"callable-types": false,
"comment-format": false,
"dt-header": false,
"eofline": false,
"export-just-namespace": false,
"import-spacing": false,
"interface-name": false,
"interface-over-type-literal": false,
"jsdoc-format": false,
"max-line-length": false,
"member-access": false,
"new-parens": false,
"no-any-union": false,
"no-boolean-literal-compare": false,
"no-conditional-assignment": false,
"no-consecutive-blank-lines": false,
"no-construct": false,
"no-declare-current-package": false,
"no-duplicate-imports": false,
"no-duplicate-variable": false,
"no-empty-interface": false,
"no-for-in-array": false,
"no-inferrable-types": false,
"no-internal-module": false,
"no-irregular-whitespace": false,
"no-mergeable-namespace": false,
"no-misused-new": false,
"no-namespace": false,
"no-object-literal-type-assertion": false,
"no-padding": false,
"no-redundant-jsdoc": false,
"no-redundant-jsdoc-2": false,
"no-redundant-undefined": false,
"no-reference-import": false,
"no-relative-import-in-test": false,
"no-self-import": false,
"no-single-declare-module": false,
"no-string-throw": false,
"no-unnecessary-callback-wrapper": false,
"no-unnecessary-class": false,
"no-unnecessary-generics": false,
"no-unnecessary-qualifier": false,
"no-unnecessary-type-assertion": false,
"no-useless-files": false,
"no-var-keyword": false,
"no-var-requires": false,
"no-void-expression": false,
"no-trailing-whitespace": false,
"object-literal-key-quotes": false,
"object-literal-shorthand": false,
"one-line": false,
"one-variable-per-declaration": false,
"only-arrow-functions": false,
"prefer-conditional-expression": false,
"prefer-const": false,
"prefer-declare-function": false,
"prefer-for-of": false,
"prefer-method-signature": false,
"prefer-template": false,
"radix": false,
"semicolon": false,
"space-before-function-paren": false,
"space-within-parens": false,
"strict-export-declare-modifiers": false,
"trim-file": false,
"triple-equals": false,
"typedef-whitespace": false,
"unified-signatures": false,
"void-return": false,
"whitespace": false
}
}
+12 -17
View File
@@ -1,13 +1,13 @@
import acorn = require('acorn');
import * as ESTree from 'estree';
declare var token: acorn.Token;
declare var tokens: acorn.Token[];
declare var comment: acorn.Comment;
declare var comments: acorn.Comment[];
declare var program: ESTree.Program;
var any: any;
var string: string;
declare let token: acorn.Token;
declare let tokens: acorn.Token[];
declare let comment: acorn.Comment;
declare let comments: acorn.Comment[];
declare let program: ESTree.Program;
let any: any;
let string: string;
// acorn
string = acorn.version;
@@ -32,16 +32,12 @@ const parser = new acorn.Parser({}, 'export default ""', 0);
const node = new acorn.Node(parser, 1, 1);
class LooseParser {
constructor(input: string, options = {}) {
}
constructor(input: string, options = {}) {}
// this means you can extend LooseParser
test() {
}
test() {}
}
acorn.addLooseExports(function () {
acorn.addLooseExports(() => {
return {
type: 'Program',
sourceType: 'script',
@@ -50,7 +46,7 @@ acorn.addLooseExports(function () {
type: 'EmptyStatement'
}
]
}
};
}, LooseParser, {});
acorn.parseExpressionAt('string', 2);
@@ -63,8 +59,7 @@ acorn.isIdentifierChar(56);
acorn.getLineInfo('string', 56);
acorn.plugins['test'] = function (p: acorn.Parser, config: any) {
}
acorn.plugins['test'] = (p: acorn.Parser, config: any) => {};
acorn.tokenizer('console.log("hello world)', {locations: true}).getToken();
acorn.tokenizer('console.log("hello world)', {locations: true})[Symbol.iterator]().next();
+9 -14
View File
@@ -1,10 +1,8 @@
// Type definitions for Acorn v4.0.3
// Type definitions for Acorn 4.0
// Project: https://github.com/marijnh/acorn
// Definitions by: RReverser <https://github.com/RReverser>, e-cloud <https://github.com/e-cloud>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/// <reference types="estree" />
export as namespace acorn;
export = acorn;
import * as ESTree from 'estree';
@@ -181,7 +179,7 @@ declare namespace acorn {
_typeof: TokenType;
_void: TokenType;
_delete: TokenType;
}
};
class TokContext {
constructor(token: string, isExpr: boolean, preserveSpace: boolean, override: (p: Parser) => void);
@@ -230,19 +228,18 @@ declare namespace acorn {
const version: string;
interface IParse {
(input: string, options?: Options): ESTree.Program;
}
// TODO: rename type.
type IParse = (input: string, options?: Options) => ESTree.Program;
const parse: IParse;
function parseExpressionAt(input: string, pos?: number, options?: Options): ESTree.Expression;
interface ITokenizer {
getToken() : Token,
[Symbol.iterator](): Iterator<Token>
getToken(): Token;
[Symbol.iterator](): Iterator<Token>;
}
function tokenizer(input: string, options: Options): ITokenizer;
let parse_dammit: IParse | undefined;
@@ -250,12 +247,10 @@ declare namespace acorn {
let pluginsLoose: PluginsObject | undefined;
interface ILooseParserClass {
new (input: string, options?: Options): ILooseParser
new (input: string, options?: Options): ILooseParser;
}
interface ILooseParser {
}
interface ILooseParser {}
function addLooseExports(parse: IParse, parser: ILooseParserClass, plugins: PluginsObject): void;
}
+3 -1
View File
@@ -7,13 +7,15 @@
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": false,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
+9
View File
@@ -0,0 +1,9 @@
{
"extends": "dtslint/dt.json",
"rules": {
"export-just-namespace": false,
"interface-name": false,
"no-empty-interface": false,
"no-unnecessary-class": false
}
}
+3 -1
View File
@@ -8,13 +8,15 @@
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": false,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
+79
View File
@@ -0,0 +1,79 @@
{
"extends": "dtslint/dt.json",
"rules": {
"adjacent-overload-signatures": false,
"array-type": false,
"arrow-return-shorthand": false,
"ban-types": false,
"callable-types": false,
"comment-format": false,
"dt-header": false,
"eofline": false,
"export-just-namespace": false,
"import-spacing": false,
"interface-name": false,
"interface-over-type-literal": false,
"jsdoc-format": false,
"max-line-length": false,
"member-access": false,
"new-parens": false,
"no-any-union": false,
"no-boolean-literal-compare": false,
"no-conditional-assignment": false,
"no-consecutive-blank-lines": false,
"no-construct": false,
"no-declare-current-package": false,
"no-duplicate-imports": false,
"no-duplicate-variable": false,
"no-empty-interface": false,
"no-for-in-array": false,
"no-inferrable-types": false,
"no-internal-module": false,
"no-irregular-whitespace": false,
"no-mergeable-namespace": false,
"no-misused-new": false,
"no-namespace": false,
"no-object-literal-type-assertion": false,
"no-padding": false,
"no-redundant-jsdoc": false,
"no-redundant-jsdoc-2": false,
"no-redundant-undefined": false,
"no-reference-import": false,
"no-relative-import-in-test": false,
"no-self-import": false,
"no-single-declare-module": false,
"no-string-throw": false,
"no-unnecessary-callback-wrapper": false,
"no-unnecessary-class": false,
"no-unnecessary-generics": false,
"no-unnecessary-qualifier": false,
"no-unnecessary-type-assertion": false,
"no-useless-files": false,
"no-var-keyword": false,
"no-var-requires": false,
"no-void-expression": false,
"no-trailing-whitespace": false,
"object-literal-key-quotes": false,
"object-literal-shorthand": false,
"one-line": false,
"one-variable-per-declaration": false,
"only-arrow-functions": false,
"prefer-conditional-expression": false,
"prefer-const": false,
"prefer-declare-function": false,
"prefer-for-of": false,
"prefer-method-signature": false,
"prefer-template": false,
"radix": false,
"semicolon": false,
"space-before-function-paren": false,
"space-within-parens": false,
"strict-export-declare-modifiers": false,
"trim-file": false,
"triple-equals": false,
"typedef-whitespace": false,
"unified-signatures": false,
"void-return": false,
"whitespace": false
}
}
+13
View File
@@ -0,0 +1,13 @@
License Notices:
The API definitions are from Actions on Google reference site [1] and actions-on-google library [2].
The actions-on-google library is licensed under the Apache 2.0 License [3].
The code documentation is reproduced from work created and shared by Google [4]
and used according to terms described in the Creative Commons 3.0 Attribution License [5].
[1] https://developers.google.com/actions/
[2] https://github.com/actions-on-google/actions-on-google-nodejs
[3] http://www.apache.org/licenses/LICENSE-2.0
[4] https://developers.google.com/readme/policies/
[5] http://creativecommons.org/licenses/by/3.0/
@@ -0,0 +1,33 @@
import { ActionsSdkApp, ActionsSdkAppOptions, DialogflowApp, DialogflowAppOptions, AssistantApp,
Responses, Transactions } from 'actions-on-google';
import express = require('express');
function testActionsSdk(request: express.Request, response: express.Response) {
const app = new ActionsSdkApp({request, response});
const actionMap = new Map();
actionMap.set(app.StandardIntents.MAIN, () => {
const richResponse: Responses.RichResponse = app.buildRichResponse()
.addSimpleResponse('Hello world')
.addSuggestions(['foo', 'bar']);
app.ask(richResponse);
});
app.handleRequest(actionMap);
}
function testDialogflow(request: express.Request, response: express.Response) {
const app = new DialogflowApp({request, response});
const actionMap = new Map();
actionMap.set(app.StandardIntents.MAIN, () => {
const order: Transactions.Order = app.buildOrder('foo');
app.askForTransactionDecision(order, {
type: app.Transactions.PaymentType.PAYMENT_CARD,
displayName: 'VISA-1234',
deliveryAddressRequired: true
});
});
app.handleRequest(actionMap);
}
const expressApp = express();
expressApp.get('/actionssdk', testActionsSdk);
expressApp.get('/dialogflow', testDialogflow);
+427
View File
@@ -0,0 +1,427 @@
import * as express from 'express';
import { AssistantApp } from './assistant-app';
import { Carousel, List, RichResponse, SimpleResponse } from './response-builder';
// ---------------------------------------------------------------------------
// Actions SDK support
// ---------------------------------------------------------------------------
export interface ActionsSdkAppOptions {
/** Express HTTP request object. */
request: express.Request;
/** Express HTTP response object. */
response: express.Response;
/** Function callback when session starts. */
sessionStarted?(): any;
}
/**
* This is the class that handles the conversation API directly from Assistant,
* providing implementation for all the methods available in the API.
*/
export class ActionsSdkApp extends AssistantApp {
/**
* Constructor for ActionsSdkApp object.
* To be used in the Actions SDK HTTP endpoint logic.
*
* @example
* const ActionsSdkApp = require('actions-on-google').ActionsSdkApp;
* const app = new ActionsSdkApp({request: request, response: response,
* sessionStarted:sessionStarted});
*
* @actionssdk
*/
constructor(options: ActionsSdkAppOptions);
/**
* @deprecated
* Validates whether request is from Assistant through signature verification.
* Uses Google-Auth-Library to verify authorization token against given
* Google Cloud Project ID. Auth token is given in request header with key,
* "Authorization".
*
* @example
* const app = new ActionsSdkApp({request, response});
* app.isRequestFromAssistant('nodejs-cloud-test-project-1234')
* .then(() => {
* app.ask('Hey there, thanks for stopping by!');
* })
* .catch(err => {
* response.status(400).send();
* });
*
* @param projectId Google Cloud Project ID for the Assistant app.
* @return Promise resolving with google-auth-library LoginTicket
* if request is from a valid source, otherwise rejects with the error reason
* for an invalid token.
* @actionssdk
*/
isRequestFromAssistant(projectId: string): Promise<object>;
/**
* Validates whether request is from Google through signature verification.
* Uses Google-Auth-Library to verify authorization token against given
* Google Cloud Project ID. Auth token is given in request header with key,
* "Authorization".
*
* @example
* const app = new ActionsSdkApp({request, response});
* app.isRequestFromGoogle('nodejs-cloud-test-project-1234')
* .then(() => {
* app.ask('Hey there, thanks for stopping by!');
* })
* .catch(err => {
* response.status(400).send();
* });
*
* @param projectId Google Cloud Project ID for the Assistant app.
* @return Promise resolving with google-auth-library LoginTicket
* if request is from a valid source, otherwise rejects with the error reason
* for an invalid token.
* @actionssdk
*/
isRequestFromGoogle(projectId: string): Promise<object>;
/**
* Gets the request Conversation API version.
*
* @example
* const app = new ActionsSdkApp({request: request, response: response});
* const apiVersion = app.getApiVersion();
*
* @return Version value or null if no value.
* @actionssdk
*/
getApiVersion(): string;
/**
* Gets the user's raw input query.
*
* @example
* const app = new ActionsSdkApp({request: request, response: response});
* app.tell('You said ' + app.getRawInput());
*
* @return User's raw query or null if no value.
* @actionssdk
*/
getRawInput(): string;
/**
* Gets previous JSON dialog state that the app sent to Assistant.
* Alternatively, use the app.data field to store JSON values between requests.
*
* @example
* const app = new ActionsSdkApp({request: request, response: response});
* const dialogState = app.getDialogState();
*
* @return JSON object provided to the Assistant in the previous
* user turn or {} if no value.
* @actionssdk
*/
getDialogState(): any;
/**
* Gets the "versionLabel" specified inside the Action Package.
* Used by app to do version control.
*
* @example
* const app = new ActionsSdkApp({request: request, response: response});
* const actionVersionLabel = app.getActionVersionLabel();
*
* @return The specified version label or null if unspecified.
* @actionssdk
*/
getActionVersionLabel(): string;
/**
* Gets the unique conversation ID. It's a new ID for the initial query,
* and stays the same until the end of the conversation.
*
* @example
* const app = new ActionsSdkApp({request: request, response: response});
* const conversationId = app.getConversationId();
*
* @return Conversation ID or null if no value.
* @actionssdk
*/
getConversationId(): string;
/**
* Get the current intent. Alternatively, using a handler Map with
* {@link AssistantApp#handleRequest|handleRequest}, the client library will
* automatically handle the incoming intents.
*
* @example
* const app = new ActionsSdkApp({request: request, response: response});
*
* function responseHandler (app) {
* const intent = app.getIntent();
* switch (intent) {
* case app.StandardIntents.MAIN:
* const inputPrompt = app.buildInputPrompt(false, 'Welcome to action snippets! Say anything.');
* app.ask(inputPrompt);
* break;
*
* case app.StandardIntents.TEXT:
* app.tell('You said ' + app.getRawInput());
* break;
* }
* }
*
* app.handleRequest(responseHandler);
*
* @return Intent id or null if no value.
* @actionssdk
*/
getIntent(): string;
/**
* Get the argument value by name from the current intent. If the argument
* is not a text argument, the entire argument object is returned.
*
* Note: If incoming request is using an API version under 2 (e.g. 'v1'),
* the argument object will be in Proto2 format (snake_case, etc).
*
* @param argName Name of the argument.
* @return Argument value matching argName
* or null if no matching argument.
* @actionssdk
*/
getArgument(argName: string): string;
/**
* Returns the option key user chose from options response.
*
* @example
* const app = new App({request: req, response: res});
*
* function pickOption (app) {
* if (app.hasSurfaceCapability(app.SurfaceCapabilities.SCREEN_OUTPUT)) {
* app.askWithCarousel('Which of these looks good?',
* app.buildCarousel().addItems(
* app.buildOptionItem('another_choice', ['Another choice']).
* setTitle('Another choice').setDescription('Choose me!')));
* } else {
* app.ask('What would you like?');
* }
* }
*
* function optionPicked (app) {
* app.ask('You picked ' + app.getSelectedOption());
* }
*
* const actionMap = new Map();
* actionMap.set(app.StandardIntents.TEXT, pickOption);
* actionMap.set(app.StandardIntents.OPTION, optionPicked);
*
* app.handleRequest(actionMap);
*
* @return Option key of selected item. Null if no option selected or
* if current intent is not OPTION intent.
* @actionssdk
*/
getSelectedOption(): string;
/**
* Asks to collect user's input; all user's queries need to be sent to the app.
* {@link https://developers.google.com/actions/policies/general-policies#user_experience|
* The guidelines when prompting the user for a response must be followed at all times}.
*
* @example
* const app = new ActionsSdkApp({request: request, response: response});
*
* const noInputs = [
* `I didn't hear a number`,
* `If you're still there, what's the number?`,
* 'What is the number?'
* ];
*
* function mainIntent (app) {
* const ssml = '<speak>Hi! <break time="1"/> ' +
* 'I can read out an ordinal like ' +
* '<say-as interpret-as="ordinal">123</say-as>. Say a number.</speak>';
* const inputPrompt = app.buildInputPrompt(true, ssml, noInputs);
* app.ask(inputPrompt);
* }
*
* function rawInput (app) {
* if (app.getRawInput() === 'bye') {
* app.tell('Goodbye!');
* } else {
* const ssml = '<speak>You said, <say-as interpret-as="ordinal">' +
* app.getRawInput() + '</say-as></speak>';
* const inputPrompt = app.buildInputPrompt(true, ssml, noInputs);
* app.ask(inputPrompt);
* }
* }
*
* const actionMap = new Map();
* actionMap.set(app.StandardIntents.MAIN, mainIntent);
* actionMap.set(app.StandardIntents.TEXT, rawInput);
*
* app.handleRequest(actionMap);
*
* @param inputPrompt Holding initial and
* no-input prompts.
* @param dialogState JSON object the app uses to hold dialog state that
* will be circulated back by App.
* @return The response that is sent to Assistant to ask user to provide input.
* @actionssdk
*/
ask(inputPrompt: object | SimpleResponse | RichResponse, dialogState?: object): express.Response | null;
/**
* Asks to collect user's input with a list.
*
* @example
* const app = new ActionsSdkApp({request, response});
*
* function welcomeIntent (app) {
* app.askWithList('Which of these looks good?',
* app.buildList('List title')
* .addItems([
* app.buildOptionItem(SELECTION_KEY_ONE,
* ['synonym of KEY_ONE 1', 'synonym of KEY_ONE 2'])
* .setTitle('Number one'),
* app.buildOptionItem(SELECTION_KEY_TWO,
* ['synonym of KEY_TWO 1', 'synonym of KEY_TWO 2'])
* .setTitle('Number two'),
* ]));
* }
*
* function optionIntent (app) {
* if (app.getSelectedOption() === SELECTION_KEY_ONE) {
* app.tell('Number one is a great choice!');
* } else {
* app.tell('Number two is a great choice!');
* }
* }
*
* const actionMap = new Map();
* actionMap.set(app.StandardIntents.TEXT, welcomeIntent);
* actionMap.set(app.StandardIntents.OPTION, optionIntent);
* app.handleRequest(actionMap);
*
* @param inputPrompt Holding initial and
* no-input prompts. Cannot contain basic card.
* @param list List built with {@link AssistantApp#buildList|buildList}.
* @param dialogState JSON object the app uses to hold dialog state that
* will be circulated back by Assistant.
* @return The response that is sent to Assistant to ask user to provide input.
* @actionssdk
*/
askWithList(inputPrompt: object | SimpleResponse | RichResponse, list: List, dialogState?: object): express.Response | null;
/**
* Asks to collect user's input with a carousel.
*
* @example
* const app = new ActionsSdkApp({request, response});
*
* function welcomeIntent (app) {
* app.askWithCarousel('Which of these looks good?',
* app.buildCarousel()
* .addItems([
* app.buildOptionItem(SELECTION_KEY_ONE,
* ['synonym of KEY_ONE 1', 'synonym of KEY_ONE 2'])
* .setTitle('Number one'),
* app.buildOptionItem(SELECTION_KEY_TWO,
* ['synonym of KEY_TWO 1', 'synonym of KEY_TWO 2'])
* .setTitle('Number two'),
* ]));
* }
*
* function optionIntent (app) {
* if (app.getSelectedOption() === SELECTION_KEY_ONE) {
* app.tell('Number one is a great choice!');
* } else {
* app.tell('Number two is a great choice!');
* }
* }
*
* const actionMap = new Map();
* actionMap.set(app.StandardIntents.TEXT, welcomeIntent);
* actionMap.set(app.StandardIntents.OPTION, optionIntent);
* app.handleRequest(actionMap);
*
* @param inputPrompt Holding initial and
* no-input prompts. Cannot contain basic card.
* @param carousel Carousel built with
* {@link AssistantApp#buildCarousel|buildCarousel}.
* @param dialogState JSON object the app uses to hold dialog state that
* will be circulated back by Assistant.
* @return The response that is sent to Assistant to ask user to provide input.
* @actionssdk
*/
askWithCarousel(inputPrompt: object | SimpleResponse | RichResponse, carousel: Carousel, dialogState?: object): express.Response | null;
/**
* Tells Assistant to render the speech response and close the mic.
*
* @example
* const app = new ActionsSdkApp({request: request, response: response});
*
* const noInputs = [
* `I didn't hear a number`,
* `If you're still there, what's the number?`,
* 'What is the number?'
* ];
*
* function mainIntent (app) {
* const ssml = '<speak>Hi! <break time="1"/> ' +
* 'I can read out an ordinal like ' +
* '<say-as interpret-as="ordinal">123</say-as>. Say a number.</speak>';
* const inputPrompt = app.buildInputPrompt(true, ssml, noInputs);
* app.ask(inputPrompt);
* }
*
* function rawInput (app) {
* if (app.getRawInput() === 'bye') {
* app.tell('Goodbye!');
* } else {
* const ssml = '<speak>You said, <say-as interpret-as="ordinal">' +
* app.getRawInput() + '</say-as></speak>';
* const inputPrompt = app.buildInputPrompt(true, ssml, noInputs);
* app.ask(inputPrompt);
* }
* }
*
* const actionMap = new Map();
* actionMap.set(app.StandardIntents.MAIN, mainIntent);
* actionMap.set(app.StandardIntents.TEXT, rawInput);
*
* app.handleRequest(actionMap);
*
* @param textToSpeech Final response.
* Spoken response can be SSML.
* @return The HTTP response that is sent back to Assistant.
* @actionssdk
*/
tell(textToSpeech: string | SimpleResponse | RichResponse): express.Response | null;
/**
* Builds the {@link https://developers.google.com/actions/reference/conversation#InputPrompt|InputPrompt object}
* from initial prompt and no-input prompts.
*
* The App needs one initial prompt to start the conversation. If there is no user response,
* the App re-opens the mic and renders the no-input prompts three times
* (one for each no-input prompt that was configured) to help the user
* provide the right response.
*
* Note: we highly recommend app to provide all the prompts required here in order to ensure a
* good user experience.
*
* @example
* const inputPrompt = app.buildInputPrompt(false, 'Welcome to action snippets! Say a number.',
* ['Say any number', 'Pick a number', 'What is the number?']);
* app.ask(inputPrompt);
*
* @param isSsml Indicates whether the text to speech is SSML or not.
* @param initialPrompt The initial prompt the App asks the user.
* @param noInputs Array of re-prompts when the user does not respond (max 3).
* @return.
* @actionssdk
*/
buildInputPrompt(isSsml: boolean, initialPrompt: string, noInputs?: string[]): object;
}
File diff suppressed because it is too large Load Diff
+572
View File
@@ -0,0 +1,572 @@
import * as express from 'express';
import { AssistantApp } from './assistant-app';
import { Carousel, List, RichResponse, SimpleResponse } from './response-builder';
// ---------------------------------------------------------------------------
// Dialogflow support
// ---------------------------------------------------------------------------
/**
* Dialogflow {@link https://dialogflow.com/docs/concept-contexts|Context}.
*/
export interface Context {
/** Full name of the context. */
name: string;
/**
* Parameters carried within this context.
* See {@link https://dialogflow.com/docs/concept-actions#section-extracting-values-from-contexts|here}.
*/
parameters: object;
/** Remaining number of intents */
lifespan: number;
}
export interface DialogflowAppOptions {
/** Express HTTP request object. */
request: express.Request;
/** Express HTTP response object. */
response: express.Response;
/**
* Function callback when session starts.
* Only called if webhook is enabled for welcome/triggering intents, and
* called from Web Simulator or Google Home device (i.e., not Dialogflow simulator).
*/
sessionStarted?(): any;
}
/**
* This is the class that handles the communication with Dialogflow's fulfillment API v1.
* Doesn't currently support Dialogflow's fulfillment API v2.
*/
export class DialogflowApp extends AssistantApp {
/**
* Constructor for DialogflowApp object.
* To be used in the Dialogflow fulfillment webhook logic.
*
* @example
* const DialogflowApp = require('actions-on-google').DialogflowApp;
* const app = new DialogflowApp({request: request, response: response,
* sessionStarted:sessionStarted});
*
* @dialogflow
*/
constructor(options: DialogflowAppOptions);
/**
* @deprecated
* Verifies whether the request comes from Dialogflow.
*
* @param key The header key specified by the developer in the
* Dialogflow Fulfillment settings of the app.
* @param value The private value specified by the developer inside the
* fulfillment header.
* @return True if the request comes from Dialogflow.
* @dialogflow
*/
isRequestFromApiAi(key: string, value: string): boolean;
/**
* Verifies whether the request comes from Dialogflow.
*
* @param key The header key specified by the developer in the
* Dialogflow Fulfillment settings of the app.
* @param value The private value specified by the developer inside the
* fulfillment header.
* @return True if the request comes from Dialogflow.
* @dialogflow
*/
isRequestFromDialogflow(key: string, value: string): boolean;
/**
* Get the current intent. Alternatively, using a handler Map with
* {@link AssistantApp#handleRequest|handleRequest},
* the client library will automatically handle the incoming intents.
* 'Intent' in the Dialogflow context translates into the current action.
*
* @example
* const app = new DialogflowApp({request: request, response: response});
*
* function responseHandler (app) {
* const intent = app.getIntent();
* switch (intent) {
* case WELCOME_INTENT:
* app.ask('Welcome to action snippets! Say a number.');
* break;
*
* case NUMBER_INTENT:
* const number = app.getArgument(NUMBER_ARGUMENT);
* app.tell('You said ' + number);
* break;
* }
* }
*
* app.handleRequest(responseHandler);
*
* @return Intent id or null if no value (action name).
* @dialogflow
*/
getIntent(): string;
/**
* Get the argument value by name from the current intent. If the argument
* is included in originalRequest, and is not a text argument, the entire
* argument object is returned.
*
* Note: If incoming request is using an API version under 2 (e.g. 'v1'),
* the argument object will be in Proto2 format (snake_case, etc).
*
* @example
* const app = new DialogflowApp({request: request, response: response});
* const WELCOME_INTENT = 'input.welcome';
* const NUMBER_INTENT = 'input.number';
*
* function welcomeIntent (app) {
* app.ask('Welcome to action snippets! Say a number.');
* }
*
* function numberIntent (app) {
* const number = app.getArgument(NUMBER_ARGUMENT);
* app.tell('You said ' + number);
* }
*
* const actionMap = new Map();
* actionMap.set(WELCOME_INTENT, welcomeIntent);
* actionMap.set(NUMBER_INTENT, numberIntent);
* app.handleRequest(actionMap);
*
* @param argName Name of the argument.
* @return Argument value matching argName
* or null if no matching argument.
* @dialogflow
*/
getArgument(argName: string): object;
/**
* Get the context argument value by name from the current intent. Context
* arguments include parameters collected in previous intents during the
* lifespan of the given context. If the context argument has an original
* value, usually representing the underlying entity value, that will be given
* as part of the return object.
*
* @example
* const app = new DialogflowApp({request: request, response: response});
* const WELCOME_INTENT = 'input.welcome';
* const NUMBER_INTENT = 'input.number';
* const OUT_CONTEXT = 'output_context';
* const NUMBER_ARG = 'myNumberArg';
*
* function welcomeIntent (app) {
* const parameters = {};
* parameters[NUMBER_ARG] = '42';
* app.setContext(OUT_CONTEXT, 1, parameters);
* app.ask('Welcome to action snippets! Ask me for your number.');
* }
*
* function numberIntent (app) {
* const number = app.getContextArgument(OUT_CONTEXT, NUMBER_ARG);
* // number === { value: 42 }
* app.tell('Your number is ' + number.value);
* }
*
* const actionMap = new Map();
* actionMap.set(WELCOME_INTENT, welcomeIntent);
* actionMap.set(NUMBER_INTENT, numberIntent);
* app.handleRequest(actionMap);
*
* @param contextName Name of the context.
* @param argName Name of the argument.
* @return Object containing value property and optional original
* property matching context argument. Null if no matching argument.
* @dialogflow
*/
getContextArgument(contextName: string, argName: string): object;
/**
* Returns the RichResponse constructed in Dialogflow response builder.
*
* @example
* const app = new App({request: req, response: res});
*
* function tellFact (app) {
* let fact = 'Google was founded in 1998';
*
* if (app.hasSurfaceCapability(app.SurfaceCapabilities.SCREEN_OUTPUT)) {
* app.ask(app.getIncomingRichResponse().addSimpleResponse('Here\'s a ' +
* 'fact for you. ' + fact + ' Which one do you want to hear about ' +
* 'next, Google\'s history or headquarters?'));
* } else {
* app.ask('Here\'s a fact for you. ' + fact + ' Which one ' +
* 'do you want to hear about next, Google\'s history or headquarters?');
* }
* }
*
* const actionMap = new Map();
* actionMap.set('tell.fact', tellFact);
*
* app.handleRequest(actionMap);
*
* @return RichResponse created in Dialogflow. If no RichResponse was
* created, an empty RichResponse is returned.
* @dialogflow
*/
getIncomingRichResponse(): RichResponse;
/**
* Returns the List constructed in Dialogflow response builder.
*
* @example
* const app = new App({request: req, response: res});
*
* function pickOption (app) {
* if (app.hasSurfaceCapability(app.SurfaceCapabilities.SCREEN_OUTPUT)) {
* app.askWithList('Which of these looks good?',
* app.getIncomingList().addItems(
* app.buildOptionItem('another_choice', ['Another choice']).
* setTitle('Another choice')));
* } else {
* app.ask('What would you like?');
* }
* }
*
* const actionMap = new Map();
* actionMap.set('pick.option', pickOption);
*
* app.handleRequest(actionMap);
*
* @return List created in Dialogflow. If no List was created, an empty
* List is returned.
* @dialogflow
*/
getIncomingList(): List;
/**
* Returns the Carousel constructed in Dialogflow response builder.
*
* @example
* const app = new App({request: req, response: res});
*
* function pickOption (app) {
* if (app.hasSurfaceCapability(app.SurfaceCapabilities.SCREEN_OUTPUT)) {
* app.askWithCarousel('Which of these looks good?',
* app.getIncomingCarousel().addItems(
* app.buildOptionItem('another_choice', ['Another choice']).
* setTitle('Another choice').setDescription('Choose me!')));
* } else {
* app.ask('What would you like?');
* }
* }
*
* const actionMap = new Map();
* actionMap.set('pick.option', pickOption);
*
* app.handleRequest(actionMap);
*
* @return Carousel created in Dialogflow. If no Carousel was created,
* an empty Carousel is returned.
* @dialogflow
*/
getIncomingCarousel(): Carousel;
/**
* Returns the option key user chose from options response.
*
* @example
* const app = new App({request: req, response: res});
*
* function pickOption (app) {
* if (app.hasSurfaceCapability(app.SurfaceCapabilities.SCREEN_OUTPUT)) {
* app.askWithCarousel('Which of these looks good?',
* app.getIncomingCarousel().addItems(
* app.buildOptionItem('another_choice', ['Another choice']).
* setTitle('Another choice').setDescription('Choose me!')));
* } else {
* app.ask('What would you like?');
* }
* }
*
* function optionPicked (app) {
* app.ask('You picked ' + app.getSelectedOption());
* }
*
* const actionMap = new Map();
* actionMap.set('pick.option', pickOption);
* actionMap.set('option.picked', optionPicked);
*
* app.handleRequest(actionMap);
*
* @return Option key of selected item. Null if no option selected or
* if current intent is not OPTION intent.
* @dialogflow
*/
getSelectedOption(): string;
/**
* Asks to collect the user's input.
* {@link https://developers.google.com/actions/policies/general-policies#user_experience|The guidelines when prompting the user for a response must be followed at all times}.
*
* NOTE: Due to a bug, if you specify the no-input prompts,
* the mic is closed after the 3rd prompt, so you should use the 3rd prompt
* for a bye message until the bug is fixed.
*
* @example
* const app = new DialogflowApp({request: request, response: response});
* const WELCOME_INTENT = 'input.welcome';
* const NUMBER_INTENT = 'input.number';
*
* function welcomeIntent (app) {
* app.ask('Welcome to action snippets! Say a number.',
* ['Say any number', 'Pick a number', 'We can stop here. See you soon.']);
* }
*
* function numberIntent (app) {
* const number = app.getArgument(NUMBER_ARGUMENT);
* app.tell('You said ' + number);
* }
*
* const actionMap = new Map();
* actionMap.set(WELCOME_INTENT, welcomeIntent);
* actionMap.set(NUMBER_INTENT, numberIntent);
* app.handleRequest(actionMap);
*
* @param inputPrompt The input prompt
* response.
* @param noInputs Array of re-prompts when the user does not respond (max 3).
* @return HTTP response.
* @dialogflow
*/
ask(inputPrompt: string | SimpleResponse | RichResponse, noInputs?: string[]): express.Response | null;
/**
* Asks to collect the user's input with a list.
*
* @example
* const app = new DialogflowApp({request, response});
* const WELCOME_INTENT = 'input.welcome';
* const OPTION_INTENT = 'option.select';
*
* function welcomeIntent (app) {
* app.askWithList('Which of these looks good?',
* app.buildList('List title')
* .addItems([
* app.buildOptionItem(SELECTION_KEY_ONE,
* ['synonym of KEY_ONE 1', 'synonym of KEY_ONE 2'])
* .setTitle('Title of First List Item'),
* app.buildOptionItem(SELECTION_KEY_TWO,
* ['synonym of KEY_TWO 1', 'synonym of KEY_TWO 2'])
* .setTitle('Title of Second List Item'),
* ]));
* }
*
* function optionIntent (app) {
* if (app.getSelectedOption() === SELECTION_KEY_ONE) {
* app.tell('Number one is a great choice!');
* } else {
* app.tell('Number two is a great choice!');
* }
* }
*
* const actionMap = new Map();
* actionMap.set(WELCOME_INTENT, welcomeIntent);
* actionMap.set(OPTION_INTENT, optionIntent);
* app.handleRequest(actionMap);
*
* @param inputPrompt The input prompt
* response.
* @param.list List built with {@link AssistantApp#buildList|buildList}
* @return HTTP response.
* @dialogflow
*/
askWithList(inputPrompt: string | RichResponse | SimpleResponse, list: List): express.Response | null;
/**
* Asks to collect the user's input with a carousel.
*
* @example
* const app = new DialogflowApp({request, response});
* const WELCOME_INTENT = 'input.welcome';
* const OPTION_INTENT = 'option.select';
*
* function welcomeIntent (app) {
* app.askWithCarousel('Which of these looks good?',
* app.buildCarousel()
* .addItems([
* app.buildOptionItem(SELECTION_KEY_ONE,
* ['synonym of KEY_ONE 1', 'synonym of KEY_ONE 2'])
* .setTitle('Number one'),
* app.buildOptionItem(SELECTION_KEY_TWO,
* ['synonym of KEY_TWO 1', 'synonym of KEY_TWO 2'])
* .setTitle('Number two'),
* ]));
* }
*
* function optionIntent (app) {
* if (app.getSelectedOption() === SELECTION_KEY_ONE) {
* app.tell('Number one is a great choice!');
* } else {
* app.tell('Number two is a great choice!');
* }
* }
*
* const actionMap = new Map();
* actionMap.set(WELCOME_INTENT, welcomeIntent);
* actionMap.set(OPTION_INTENT, optionIntent);
* app.handleRequest(actionMap);
*
* @param inputPrompt The input prompt
* response.
* @param carousel Carousel built with
* {@link AssistantApp#buildCarousel|buildCarousel}.
* @return HTTP response.
* @dialogflow
*/
askWithCarousel(inputPrompt: string | RichResponse | SimpleResponse, carousel: Carousel): express.Response | null;
/**
* Tells the Assistant to render the speech response and close the mic.
*
* @example
* const app = new DialogflowApp({request: request, response: response});
* const WELCOME_INTENT = 'input.welcome';
* const NUMBER_INTENT = 'input.number';
*
* function welcomeIntent (app) {
* app.ask('Welcome to action snippets! Say a number.');
* }
*
* function numberIntent (app) {
* const number = app.getArgument(NUMBER_ARGUMENT);
* app.tell('You said ' + number);
* }
*
* const actionMap = new Map();
* actionMap.set(WELCOME_INTENT, welcomeIntent);
* actionMap.set(NUMBER_INTENT, numberIntent);
* app.handleRequest(actionMap);
*
* @param speechResponse Final response.
* Spoken response can be SSML.
* @return The response that is sent back to Assistant.
* @dialogflow
*/
tell(speechResponse: string | SimpleResponse | RichResponse): express.Response | null;
/**
* Set a new context for the current intent.
*
* @example
* const app = new DialogflowApp({request: request, response: response});
* const CONTEXT_NUMBER = 'number';
* const NUMBER_ARGUMENT = 'myNumber';
*
* function welcomeIntent (app) {
* app.setContext(CONTEXT_NUMBER);
* app.ask('Welcome to action snippets! Say a number.');
* }
*
* function numberIntent (app) {
* const number = app.getArgument(NUMBER_ARGUMENT);
* app.tell('You said ' + number);
* }
*
* const actionMap = new Map();
* actionMap.set(WELCOME_INTENT, welcomeIntent);
* actionMap.set(NUMBER_INTENT, numberIntent);
* app.handleRequest(actionMap);
*
* @param name Name of the context. Dialogflow converts to lowercase.
* @param [lifespan=1] Context lifespan.
* @param parameters Context JSON parameters.
* @return Null if the context name is not defined.
* @dialogflow
*/
setContext(name: string, lifespan?: number, parameters?: any): null | undefined;
/**
* Returns the incoming contexts for this intent.
*
* @example
* const app = new DialogflowApp({request: request, response: response});
* const CONTEXT_NUMBER = 'number';
* const NUMBER_ARGUMENT = 'myNumber';
*
* function welcomeIntent (app) {
* app.setContext(CONTEXT_NUMBER);
* app.ask('Welcome to action snippets! Say a number.');
* }
*
* function numberIntent (app) {
* let contexts = app.getContexts();
* // contexts === [{
* // name: 'number',
* // lifespan: 0,
* // parameters: {
* // myNumber: '23',
* // myNumber.original: '23'
* // }
* // }]
* const number = app.getArgument(NUMBER_ARGUMENT);
* app.tell('You said ' + number);
* }
*
* const actionMap = new Map();
* actionMap.set(WELCOME_INTENT, welcomeIntent);
* actionMap.set(NUMBER_INTENT, numberIntent);
* app.handleRequest(actionMap);
*
* @return Empty if no active contexts.
* @dialogflow
*/
getContexts(): Context[];
/**
* Returns the incoming context by name for this intent.
*
* @example
* const app = new DialogflowApp({request: request, response: response});
* const CONTEXT_NUMBER = 'number';
* const NUMBER_ARGUMENT = 'myNumber';
*
* function welcomeIntent (app) {
* app.setContext(CONTEXT_NUMBER);
* app.ask('Welcome to action snippets! Say a number.');
* }
*
* function numberIntent (app) {
* let context = app.getContext(CONTEXT_NUMBER);
* // context === {
* // name: 'number',
* // lifespan: 0,
* // parameters: {
* // myNumber: '23',
* // myNumber.original: '23'
* // }
* // }
* const number = app.getArgument(NUMBER_ARGUMENT);
* app.tell('You said ' + number);
* }
*
* const actionMap = new Map();
* actionMap.set(WELCOME_INTENT, welcomeIntent);
* actionMap.set(NUMBER_INTENT, numberIntent);
* app.handleRequest(actionMap);
*
* @param name The name of the Context to retrieve.
* @return Context value matching name
* or null if no matching context.
* @dialogflow
*/
getContext(name: string): object;
/**
* Gets the user's raw input query.
*
* @example
* const app = new DialogflowApp({request: request, response: response});
* app.tell('You said ' + app.getRawInput());
*
* @return User's raw query or null if no value.
* @dialogflow
*/
getRawInput(): string;
}
+24
View File
@@ -0,0 +1,24 @@
// Type definitions for actions-on-google 1.7
// Project: https://github.com/actions-on-google/actions-on-google-nodejs
// Definitions by: Joel Hegg <https://github.com/joelhegg>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.4
/**
* The Actions on Google client library.
* https://developers.google.com/actions/
*/
import * as Transactions from './transactions';
import * as Responses from './response-builder';
export { AssistantApp } from './assistant-app';
export { ActionsSdkApp, ActionsSdkAppOptions } from './actions-sdk-app';
export { DialogflowApp, DialogflowAppOptions } from './dialogflow-app';
export { Transactions };
export { Responses };
// Backwards compatibility
export { AssistantApp as Assistant } from './assistant-app';
export { ActionsSdkApp as ActionsSdkAssistant } from './actions-sdk-app';
export { DialogflowApp as ApiAiAssistant } from './dialogflow-app';
export { DialogflowApp as ApiAiApp } from './dialogflow-app';
+443
View File
@@ -0,0 +1,443 @@
/**
* A collection of response builders.
*/
import { OrderUpdate } from './transactions';
/**
* List of possible options to display the image in a BasicCard.
* When the aspect ratio of an image is not the same as the surface,
* this attribute changes how the image is displayed in the card.
*/
export enum ImageDisplays {
/**
* Pads the gaps between the image and image frame with a blurred copy of the
* same image.
*/
DEFAULT,
/**
* Fill the gap between the image and image container with white bars.
*/
WHITE,
/**
* Image is centered and resized so the image fits perfectly in the container.
*/
CROPPED
}
/**
* Simple Response type.
*/
export interface SimpleResponse {
/** Speech to be spoken to user. SSML allowed. */
speech: string;
/** Optional text to be shown to user */
displayText?: string;
}
/**
* Suggestions to show with response.
*/
export interface Suggestion {
/** Text of the suggestion. */
title: string;
}
/**
* Link Out Suggestion. Used in rich response as a suggestion chip which, when
* selected, links out to external URL.
*/
export interface LinkOutSuggestion {
/** Text shown on the suggestion chip. */
title: string;
/** String URL to open. */
url: string;
}
/**
* Image type shown on visual elements.
*/
export interface Image {
/** Image source URL. */
url: string;
/** Text to replace for image for accessibility. */
accessibilityText: string;
/** Width of the image. */
width: number;
/** Height of the image. */
height: number;
}
/**
* Basic Card Button. Shown below basic cards. Open a URL when selected.
*/
export interface Button {
/** Text shown on the button. */
title: string;
/** Action to take when selected. */
openUrlAction: {
/** String URL to open. */
url: string;
};
}
/**
* Option info. Provides unique identifier for a given OptionItem.
*/
export interface OptionInfo {
/** Unique string ID for this option. */
key: string;
/** Synonyms that can be used by the user to indicate this option if they do not use the key. */
synonyms: string[];
}
export interface StructuredResponse {
orderUpdate: OrderUpdate;
}
export interface ItemBasicCard {
basicCard: BasicCard;
}
export interface ItemSimpleResponse {
simpleResponse: SimpleResponse;
}
export interface ItemStructuredResponse {
structuredResponse: StructuredResponse;
}
export type RichResponseItem = ItemBasicCard | ItemSimpleResponse | ItemStructuredResponse;
/**
* Class for initializing and constructing Rich Responses with chainable interface.
*/
export class RichResponse {
/**
* Constructor for RichResponse. Accepts optional RichResponse to clone.
*
* @param richResponse Optional RichResponse to clone.
*/
constructor(richResponse?: RichResponse);
/**
* Ordered list of either SimpleResponse objects or BasicCard objects.
* First item must be SimpleResponse. There can be at most one card.
*/
items: RichResponseItem[];
/**
* Ordered list of text suggestions to display. Optional.
*/
suggestions: Suggestion[];
/**
* Link Out Suggestion chip for this rich response. Optional.
*/
linkOutSuggestion?: LinkOutSuggestion;
/**
* Adds a SimpleResponse to list of items.
*
* @param simpleResponse Simple response to present to
* user. If just a string, display text will not be set.
* @return Returns current constructed RichResponse.
*/
addSimpleResponse(simpleResponse: string | SimpleResponse): RichResponse;
/**
* Adds a BasicCard to list of items.
*
* @param basicCard Basic card to include in response.
* @return Returns current constructed RichResponse.
*/
addBasicCard(basicCard: BasicCard): RichResponse;
/**
* Adds a single suggestion or list of suggestions to list of items.
*
* @param suggestions Either a single string suggestion
* or list of suggestions to add.
* @return Returns current constructed RichResponse.
*/
addSuggestions(suggestions: string | string[]): RichResponse;
/**
* Returns true if the given suggestion text is valid to be added to the suggestion list. A valid
* text string is not longer than 25 characters.
* @param suggestionText Text to validate as suggestion.
* @return True if the text is valid, false otherwise.s
*/
isValidSuggestionText(suggestionText: string): boolean;
/**
* Sets the suggestion link for this rich response. The destination site must be verified
* (https://developers.google.com/actions/console/brand-verification).
*
* @param destinationName Name of the link out destination.
* @param suggestionUrl - String URL to open when suggestion is used.
* @return Returns current constructed RichResponse.
*/
addSuggestionLink(destinationName: string, suggestionUrl: string): RichResponse;
/**
* Adds an order update to this response. Use after a successful transaction
* decision to confirm the order.
*
* @param orderUpdate OrderUpdate object to add.
* @return Returns current constructed RichResponse.
*/
addOrderUpdate(orderUpdate: OrderUpdate): RichResponse;
}
/**
* Class for initializing and constructing Basic Cards with chainable interface.
*/
export class BasicCard {
/**
* Constructor for BasicCard. Accepts optional BasicCard to clone.
*
* @param basicCard Optional BasicCard to clone.
*/
constructor(basicCard?: BasicCard);
/**
* Title of the card. Optional.
*/
title?: string;
/**
* Body text to show on the card. Required, unless image is present.
*/
formattedText: string;
/**
* Subtitle of the card. Optional.
*/
subtitle?: string;
/**
* Image to show on the card. Optional.
*/
image?: Image;
/**
* Ordered list of buttons to show below card. Optional.
*/
buttons: Button[];
/**
* Sets the title for this Basic Card.
*
* @param title Title to show on card.
* @return Returns current constructed BasicCard.
*/
setTitle(title: string): BasicCard;
/**
* Sets the subtitle for this Basic Card.
*
* @param subtitle Subtitle to show on card.
* @return Returns current constructed BasicCard.
*/
setSubtitle(subtitle: string): BasicCard;
/**
* Sets the body text for this Basic Card.
*
* @param bodyText Body text to show on card.
* @return Returns current constructed BasicCard.
*/
setBodyText(bodyText: string): BasicCard;
/**
* Sets the image for this Basic Card.
*
* @param url Image source URL.
* @param accessibilityText Text to replace for image for
* accessibility.
* @param width Width of the image.
* @param height Height of the image.
* @return Returns current constructed BasicCard.
*/
setImage(url: string, accessibilityText: string, width?: number, height?: number): BasicCard;
/**
* Sets the display options for the image in this Basic Card.
* Use one of the image display constants. If none is chosen,
* ImageDisplays.DEFAULT will be enforced.
*
* @param option The option for displaying the image.
* @return Returns current constructed BasicCard.
*/
setImageDisplay(option: ImageDisplays): BasicCard;
/**
* Adds a button below card.
*
* @param text Text to show on button.
* @param url URL to open when button is selected.
* @return Returns current constructed BasicCard.
*/
addButton(text: string, url: string): BasicCard;
}
/**
* Class for initializing and constructing Lists with chainable interface.
*/
export class List {
/**
* Constructor for List. Accepts optional List to clone, string title, or
* list of items to copy.
*
* @param list Either a list to clone, a title
* to set for a new List, or an array of OptionItem to initialize a new
* list.
*/
constructor(list?: List | string | OptionItem[]);
/**
* Title of the list. Optional.
*/
title?: string;
/**
* List of 2-20 items to show in this list. Required.
*/
items: OptionItem[];
/**
* Sets the title for this List.
*
* @param title Title to show on list.
* @return Returns current constructed List.
*/
setTitle(title: string): List;
/**
* Adds a single item or list of items to the list.
*
* @param optionItems OptionItems to add.
* @return Returns current constructed List.
*/
addItems(optionItems: OptionItem | OptionItem[]): List;
}
/**
* Class for initializing and constructing Carousel with chainable interface.
*/
export class Carousel {
/**
* Constructor for Carousel. Accepts optional Carousel to clone or list of
* items to copy.
*
* @param carousel Either a carousel to clone
* or an array of OptionItem to initialize a new carousel
*/
constructor(carousel?: Carousel | OptionItem[]);
/**
* List of 2-20 items to show in this carousel. Required.
*/
items: OptionItem[];
/**
* Adds a single item or list of items to the carousel.
*
* @param optionItems OptionItems to add.
* @return Returns current constructed Carousel.
*/
addItems(optionItems: OptionItem | OptionItem[]): Carousel;
}
/**
* Class for initializing and constructing Option Items with chainable interface.
*/
export class OptionItem {
/**
* Constructor for OptionItem. Accepts optional OptionItem to clone.
*
* @param optionItem Optional OptionItem to clone.
*/
constructor(optionItem?: OptionItem);
/**
* Option info of the option item. Required.
*/
optionInfo: OptionInfo;
/**
* Title of the option item. Required.
*/
title: string;
/**
* Description text of the item. Optional.
*/
description?: string;
/**
* Image to show on item. Optional.
*/
image?: Image;
/**
* Sets the title for this Option Item.
*
* @param title Title to show on item.
* @return Returns current constructed OptionItem.
*/
setTitle(title: string): OptionItem;
/**
* Sets the description for this Option Item.
*
* @param description Description to show on item.
* @return Returns current constructed OptionItem.
*/
setDescription(description: string): OptionItem;
/**
* Sets the image for this Option Item.
*
* @param url Image source URL.
* @param accessibilityText Text to replace for image for
* accessibility.
* @param width Width of the image.
* @param height Height of the image.
* @return Returns current constructed OptionItem.
*/
setImage(url: string, accessibilityText: string, width?: number, height?: number): OptionItem;
/**
* Sets the key for the OptionInfo of this Option Item. This will be returned
* as an argument in the resulting actions.intent.OPTION intent.
*
* @param key Key to uniquely identify this item.
* @return Returns current constructed OptionItem.
*/
setKey(key: string): OptionItem;
/**
* Adds a single synonym or list of synonyms to item.
*
* @param synonyms Either a single string synonyms
* or list of synonyms to add.
* @return Returns current constructed OptionItem.
*/
addSynonyms(synonyms: string | string[]): OptionItem;
}
/**
* Check if given text contains SSML.
* @param text Text to check.
* @return True if text contains SSML, false otherwise.
*/
export function isSsml(text: string): boolean;
/**
* Check if given text contains SSML, allowing for whitespace padding.
* @param text Text to check.
* @return True if text contains possibly whitespace padded SSML, false otherwise.
*/
export function isPaddedSsml(text: string): boolean;
File diff suppressed because it is too large Load Diff
+29
View File
@@ -0,0 +1,29 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
"assistant-app.d.ts",
"actions-sdk-app.d.ts",
"dialogflow-app.d.ts",
"response-builder.d.ts",
"transactions.d.ts",
"actions-on-google-tests.ts"
]
}
@@ -0,0 +1,25 @@
let app = new ActiveXObject('Access.Application');
app.UserControl = true;
// opens a form
app.DoCmd.OpenForm('MyForm', Access.AcFormView.acNormal, '', 'LastName="Smith"');
// change the contents of a textbox
// tslint:disable-next-line:no-unnecessary-type-assertion
let textbox = app.Forms.Item('MyForm').Controls.Item('MyTextBox') as Access.TextBox;
textbox.Text = 'Not Smith';
// save the current record on the active form
app.RunCommand(Access.AcCommand.acCmdSaveRecord);
// close the form
app.DoCmd.Close(Access.AcObjectType.acForm, 'MyForm');
// open a report for printing
app.DoCmd.OpenReport('MyReport');
// open the same report in Design View
app.DoCmd.OpenReport('MyReport', Access.AcView.acViewDesign);
// run a VBA macro
app.Run('MyMacro', 'argument1', 2);
+8925
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -0,0 +1,6 @@
{
"private": true,
"dependencies": {
"activex-helpers": "*"
}
}
+25
View File
@@ -0,0 +1,25 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es5",
"scripthost"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
"activex-access-tests.ts"
]
}
+6
View File
@@ -0,0 +1,6 @@
{
"extends": "dtslint/dt.json",
"rules": {
"no-const-enum": false
}
}
@@ -0,0 +1,57 @@
let obj0 = new ActiveXObject('ADODB.Command');
let obj1 = new ActiveXObject('ADODB.Connection');
let obj2 = new ActiveXObject('ADODB.Parameter');
let obj3 = new ActiveXObject('ADODB.Record');
let obj4 = new ActiveXObject('ADODB.Recordset');
let obj5 = new ActiveXObject('ADODB.Stream');
// open connection to an Excel file
let pathToExcelFile = 'C:\\path\\to\\excel\\file.xlsx';
let conn = new ActiveXObject('ADODB.Connection');
conn.Provider = 'Microsoft.ACE.OLEDB.12.0';
conn.ConnectionString = `Data Source="${pathToExcelFile}";Extended Properties="Excel 12.0;HDR=Yes"`;
conn.Open();
// create a Command to access the data
let cmd = new ActiveXObject('ADODB.Command');
cmd.ActiveConnection = conn;
cmd.CommandText = 'SELECT DISTINCT LastName, CityName FROM [Sheet1$]';
// get a Recordset
let rs = cmd.Execute();
// build a string from the Recordset
let s = rs.GetString(ADODB.StringFormatEnum.adClipString, -1, '\t', '\n', '(NULL)');
rs.Close();
WScript.Echo(s);
// create a disconnected recordset -- https://support.microsoft.com/en-us/help/184397/how-to-create-ado-disconnected-recordsets-in-vba-c-java
(() => {
conn = new ActiveXObject('ADODB.Connection');
conn.Open(); // pass connection details here
rs = new ActiveXObject('ADODB.Recordset');
rs.CursorLocation = ADODB.CursorLocationEnum.adUseClient;
rs.Open('SELECT * FROM Table1', conn, ADODB.CursorTypeEnum.adOpenForwardOnly, ADODB.LockTypeEnum.adLockBatchOptimistic);
rs.ActiveConnection = null;
const v = rs.Fields.Item(0).Value;
conn.Close();
})();
// helper function
const toSafeArray = <T>(...items: T[]): SafeArray<T> => {
const dict = new ActiveXObject('Scripting.Dictionary');
items.forEach((x, index) => dict.Add(index, x));
return dict.Items() as SafeArray<T>;
};
// update with SafeArray
(() => {
const fields = toSafeArray('FirstName', 'LastName', 'DOB');
const values = toSafeArray<any>('Plony', 'Almony', new Date(1980, 1, 1).getVarDate());
rs.Update(fields, values);
})();
+1086
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -0,0 +1,6 @@
{
"private": true,
"dependencies": {
"activex-helpers": "*"
}
}
+25
View File
@@ -0,0 +1,25 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es5",
"scripthost"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
"activex-adodb-tests.ts"
]
}
+6
View File
@@ -0,0 +1,6 @@
{
"extends": "dtslint/dt.json",
"rules": {
"no-const-enum": false
}
}
+154
View File
@@ -0,0 +1,154 @@
let engine = new ActiveXObject('DAO.DBEngine.120');
let dbsNorthwind = engine.OpenDatabase('c:\\path\\to\\northwind.mdb');
// adding a record to a recordset -- https://msdn.microsoft.com/VBA/Access-VBA/articles/add-a-record-to-a-dao-recordset
let rstShippers = dbsNorthwind.OpenRecordset('Shippers');
rstShippers.AddNew();
rstShippers.Fields.Item('CompanyName').Value = 'Global Parcel Service';
// Set remaining fields
rstShippers.Update();
rstShippers.Close();
// create a QueryDef with the given SQL -- https://msdn.microsoft.com/VBA/Access-VBA/articles/build-sql-statements-that-include-variables-and-controls
let sql = 'SELECT * FROM Orders WHERE OrderDate > #3-31-2006#';
let qdf = dbsNorthwind.CreateQueryDef('Second quarter', sql);
// using parameters
sql = `
PARAMETERS QuarterStart DATETIME
SELECT *
FROM Orders
WHERE OrderDate > QuarterStart
`;
qdf = dbsNorthwind.CreateQueryDef('Second quarter (parameters)', sql);
// count the number of records in a Recordset -- https://msdn.microsoft.com/VBA/Access-VBA/articles/count-the-number-of-records-in-a-dao-recordset
const findRecordCount = (dbs: DAO.Database, sql: string) => {
let count = 0;
const rstRecords = dbs.OpenRecordset(sql);
if (!rstRecords.EOF) {
rstRecords.MoveLast();
count = rstRecords.RecordCount;
}
rstRecords.Close();
return count;
};
// delete records from a Recordset -- https://msdn.microsoft.com/VBA/Access-VBA/articles/delete-a-record-from-a-dao-recordset
rstShippers = dbsNorthwind.OpenRecordset('SELECT * FROM Shippers ORDER BY CompanyName, ShipperID', DAO.RecordsetTypeEnum.dbOpenDynaset);
if (!rstShippers.EOF) {
let name = rstShippers.Fields.Item('CompanyName').Value;
rstShippers.MoveNext();
while (!rstShippers.EOF) {
const recordName: string = rstShippers.Fields.Item('CompanyName').Value;
if (recordName === name) {
rstShippers.Delete();
} else {
name = recordName;
}
rstShippers.MoveNext();
}
}
rstShippers.Close();
// copy entire records to an array -- https://msdn.microsoft.com/VBA/Access-VBA/articles/extract-data-from-a-record-in-a-dao-recordset
let rstEmployees = dbsNorthwind.OpenRecordset('SELECT FirstName, LastName, Title FROM Employees', DAO.RecordsetTypeEnum.dbOpenSnapshot);
let records = new VBArray<string>(rstEmployees.GetRows(3));
let recordCount = records.ubound(2) + 1;
let columnCount = records.ubound(1) + 1;
for (let row = 0; row < recordCount; row += 1) {
for (let column = 0; column < columnCount; column += 1) {
WScript.Echo(records.getItem(column, row));
}
}
if (rstEmployees.EOF) { WScript.Echo('At end of recordset'); }
rstEmployees.Close();
// find a record in a dynaset-type or snapshot-type DAO Recordset -- https://msdn.microsoft.com/en-us/vba/access-vba/articles/find-a-record-in-a-dynaset-type-or-snapshot-type-dao-recordset
const findOrdersWithoutDetails = () => {
const orders: number[] = [];
const rstOrders = dbsNorthwind.OpenRecordset('SELECT * FROM Orders ORDER BY OrderID', DAO.RecordsetTypeEnum.dbOpenSnapshot);
const rstOrderDetails = dbsNorthwind.OpenRecordset('SELECT * FROM [Order Details] ORDER BY OrderID', DAO.RecordsetTypeEnum.dbOpenSnapshot);
const closeRecordsets = () => {
rstOrders.Close();
rstOrderDetails.Close();
};
if (rstOrders.EOF || rstOrderDetails.EOF) {
closeRecordsets();
return;
}
while (!rstOrders.EOF) {
const orderID = rstOrders.Fields.Item('OrderID').Value;
rstOrderDetails.FindFirst(`OrderID=${orderID}`);
if (rstOrderDetails.NoMatch) {
orders.push(orderID);
}
rstOrders.MoveNext();
}
closeRecordsets();
return orders;
};
// find a record in a table-type DAO Recordset -- https://msdn.microsoft.com/VBA/Access-VBA/articles/find-a-record-in-a-table-type-dao-recordset
const getHireDate = (employeeID: number) => {
let hireDate: Date | undefined;
const rstEmployees = dbsNorthwind.OpenRecordset('Employees');
rstEmployees.Index = 'PrimaryKey';
rstEmployees.Seek('=', employeeID);
if (!rstEmployees.NoMatch) {
hireDate = new Date(rstEmployees.Fields.Item('HireDate').Value as VarDate);
}
return hireDate;
};
// manipulate multiple fields with DAO -- https://msdn.microsoft.com/VBA/Access-VBA/articles/manipulate-multivalued-fields-with-dao
const browseMultiValueField = () => {
const rs = dbsNorthwind.OpenRecordset('Tasks');
rs.MoveFirst();
while (!rs.EOF) {
WScript.Echo(rs.Fields.Item('TaskName').Value);
const childRs = rs.Fields.Item('AssignedTo').Value as DAO.Recordset;
if (childRs.EOF) { continue; }
childRs.MoveFirst();
while (!childRs.EOF) {
WScript.Echo('\t' + childRs.Fields.Item('Value').Value);
}
}
};
// modifying an existing record in a DAO Recordset -- https://msdn.microsoft.com/VBA/Access-VBA/articles/modify-an-existing-record-in-a-dao-recordset
const changeTitleWithoutTransaction = () => {
rstEmployees = dbsNorthwind.OpenRecordset('Employees');
while (!rstEmployees.EOF) {
if (rstEmployees.Fields.Item('Title').Value === 'Sales Representative') {
rstEmployees.Edit();
rstEmployees.Fields.Item('Title').Value = 'Account Executive';
rstEmployees.Update();
}
rstEmployees.MoveNext();
}
rstEmployees.Close();
};
// using transactions in a DAO Recordset -- https://msdn.microsoft.com/VBA/Access-VBA/articles/use-transactions-in-a-dao-recordset
const changeTitleWithTransaction = (commitTransaction: boolean) => {
const currentWorkspace = engine.Workspaces.Item(0);
rstEmployees = dbsNorthwind.OpenRecordset('Employees');
currentWorkspace.BeginTrans();
while (!rstEmployees.EOF) {
if (rstEmployees.Fields.Item('Title').Value === 'Sales Representative') {
rstEmployees.Edit();
rstEmployees.Fields.Item('Title').Value = 'Account Executive';
rstEmployees.Update();
}
rstEmployees.MoveNext();
}
if (commitTransaction) {
currentWorkspace.CommitTrans();
} else {
currentWorkspace.Rollback();
}
rstEmployees.Close();
currentWorkspace.Close();
};
+910
View File
@@ -0,0 +1,910 @@
// Type definitions for Microsoft Office 14.0 Access Database Engine Object Library - DAO 14.0
// Project: https://msdn.microsoft.com/en-us/library/dn124645.aspx
// Definitions by: Zev Spitz <https://github.com/zspitz>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.4
declare namespace DAO {
const enum _DAOSuppHelp {
KeepLocal = 0,
LogMessages = 0,
Replicable = 0,
ReplicableBool = 0,
V1xNullBehavior = 0,
}
const enum CollatingOrderEnum {
dbSortArabic = 1025,
dbSortChineseSimplified = 2052,
dbSortChineseTraditional = 1028,
dbSortCyrillic = 1049,
dbSortCzech = 1029,
dbSortDutch = 1043,
dbSortGeneral = 1033,
dbSortGreek = 1032,
dbSortHebrew = 1037,
dbSortHindi = 1081,
dbSortHungarian = 1038,
dbSortIcelandic = 1039,
dbSortJapanese = 1041,
dbSortJapaneseRadicalStrokeCount = 263185,
dbSortKorean = 1042,
dbSortNeutral = 1024,
dbSortNorwdan = 1030,
dbSortPDXIntl = 1033,
dbSortPDXNor = 1030,
dbSortPDXSwe = 1053,
dbSortPolish = 1045,
dbSortSlovenian = 1060,
dbSortSpanish = 1034,
dbSortSwedFin = 1053,
dbSortThai = 1054,
dbSortTurkish = 1055,
dbSortUndefined = -1,
}
const enum CommitTransOptionsEnum {
dbForceOSFlush = 1,
}
const enum CursorDriverEnum {
dbUseClientBatchCursor = 3,
dbUseDefaultCursor = -1,
dbUseNoCursor = 4,
dbUseODBCCursor = 1,
dbUseServerCursor = 2,
}
const enum DatabaseTypeEnum {
dbDecrypt = 4,
dbEncrypt = 2,
dbVersion10 = 1,
dbVersion11 = 8,
dbVersion120 = 128,
dbVersion140 = 256,
dbVersion20 = 16,
dbVersion30 = 32,
dbVersion40 = 64,
}
const enum DataTypeEnum {
dbAttachment = 101,
dbBigInt = 16,
dbBinary = 9,
dbBoolean = 1,
dbByte = 2,
dbChar = 18,
dbComplexByte = 102,
dbComplexDecimal = 108,
dbComplexDouble = 106,
dbComplexGUID = 107,
dbComplexInteger = 103,
dbComplexLong = 104,
dbComplexSingle = 105,
dbComplexText = 109,
dbCurrency = 5,
dbDate = 8,
dbDecimal = 20,
dbDouble = 7,
dbFloat = 21,
dbGUID = 15,
dbInteger = 3,
dbLong = 4,
dbLongBinary = 11,
dbMemo = 12,
dbNumeric = 19,
dbSingle = 6,
dbText = 10,
dbTime = 22,
dbTimeStamp = 23,
dbVarBinary = 17,
}
const enum DriverPromptEnum {
dbDriverComplete = 0,
dbDriverCompleteRequired = 3,
dbDriverNoPrompt = 1,
dbDriverPrompt = 2,
}
const enum EditModeEnum {
dbEditAdd = 2,
dbEditInProgress = 1,
dbEditNone = 0,
}
const enum FieldAttributeEnum {
dbAutoIncrField = 16,
dbDescending = 1,
dbFixedField = 1,
dbHyperlinkField = 32768,
dbSystemField = 8192,
dbUpdatableField = 32,
dbVariableField = 2,
}
const enum IdleEnum {
dbFreeLocks = 1,
dbRefreshCache = 8,
}
const enum LanguageConstants {
dbLangArabic = ';LANGID=0x0401;CP=1256;COUNTRY=0',
dbLangChineseSimplified = ';LANGID=0x0804;CP=936;COUNTRY=0',
dbLangChineseTraditional = ';LANGID=0x0404;CP=950;COUNTRY=0',
dbLangCyrillic = ';LANGID=0x0419;CP=1251;COUNTRY=0',
dbLangCzech = ';LANGID=0x0405;CP=1250;COUNTRY=0',
dbLangDutch = ';LANGID=0x0413;CP=1252;COUNTRY=0',
dbLangGeneral = ';LANGID=0x0409;CP=1252;COUNTRY=0',
dbLangGreek = ';LANGID=0x0408;CP=1253;COUNTRY=0',
dbLangHebrew = ';LANGID=0x040D;CP=1255;COUNTRY=0',
dbLangHindi = ';LANGID=0x00000439;CP=65001;COUNTRY=0',
dbLangHungarian = ';LANGID=0x040E;CP=1250;COUNTRY=0',
dbLangIcelandic = ';LANGID=0x040F;CP=1252;COUNTRY=0',
dbLangJapanese = ';LANGID=0x0411;CP=932;COUNTRY=0',
dbLangJapaneseRadicalStrokeCount = ';LANGID=0x00040411;CP=65001;COUNTRY=0',
dbLangKorean = ';LANGID=0x0412;CP=949;COUNTRY=0',
dbLangNordic = ';LANGID=0x041D;CP=1252;COUNTRY=0',
dbLangNorwDan = ';LANGID=0x0406;CP=1252;COUNTRY=0',
dbLangPolish = ';LANGID=0x0415;CP=1250;COUNTRY=0',
dbLangSlovenian = ';LANGID=0x0424;CP=1250;COUNTRY=0',
dbLangSpanish = ';LANGID=0x040A;CP=1252;COUNTRY=0',
dbLangSwedFin = ';LANGID=0x041D;CP=1252;COUNTRY=0',
dbLangThai = ';LANGID=0x041E;CP=874;COUNTRY=0',
dbLangTurkish = ';LANGID=0x041F;CP=1254;COUNTRY=0',
}
const enum LockTypeEnum {
dbOptimistic = 3,
dbOptimisticBatch = 5,
dbOptimisticValue = 1,
dbPessimistic = 2,
}
const enum ParameterDirectionEnum {
dbParamInput = 1,
dbParamInputOutput = 3,
dbParamOutput = 2,
dbParamReturnValue = 4,
}
const enum PermissionEnum {
dbSecCreate = 1,
dbSecDBAdmin = 8,
dbSecDBCreate = 1,
dbSecDBExclusive = 4,
dbSecDBOpen = 2,
dbSecDelete = 65536,
dbSecDeleteData = 128,
dbSecFullAccess = 1048575,
dbSecInsertData = 32,
dbSecNoAccess = 0,
dbSecReadDef = 4,
dbSecReadSec = 131072,
dbSecReplaceData = 64,
dbSecRetrieveData = 20,
dbSecWriteDef = 65548,
dbSecWriteOwner = 524288,
dbSecWriteSec = 262144,
}
const enum QueryDefStateEnum {
dbQPrepare = 1,
dbQUnprepare = 2,
}
const enum QueryDefTypeEnum {
dbQAction = 240,
dbQAppend = 64,
dbQCompound = 160,
dbQCrosstab = 16,
dbQDDL = 96,
dbQDelete = 32,
dbQMakeTable = 80,
dbQProcedure = 224,
dbQSelect = 0,
dbQSetOperation = 128,
dbQSPTBulk = 144,
dbQSQLPassThrough = 112,
dbQUpdate = 48,
}
const enum RecordsetOptionEnum {
dbAppendOnly = 8,
dbConsistent = 32,
dbDenyRead = 2,
dbDenyWrite = 1,
dbExecDirect = 2048,
dbFailOnError = 128,
dbForwardOnly = 256,
dbInconsistent = 16,
dbReadOnly = 4,
dbRunAsync = 1024,
dbSeeChanges = 512,
dbSQLPassThrough = 64,
}
const enum RecordsetTypeEnum {
dbOpenDynamic = 16,
dbOpenDynaset = 2,
dbOpenForwardOnly = 8,
dbOpenSnapshot = 4,
dbOpenTable = 1,
}
const enum RecordStatusEnum {
dbRecordDBDeleted = 4,
dbRecordDeleted = 3,
dbRecordModified = 1,
dbRecordNew = 2,
dbRecordUnmodified = 0,
}
const enum RelationAttributeEnum {
dbRelationDeleteCascade = 4096,
dbRelationDontEnforce = 2,
dbRelationInherited = 4,
dbRelationLeft = 16777216,
dbRelationRight = 33554432,
dbRelationUnique = 1,
dbRelationUpdateCascade = 256,
}
const enum ReplicaTypeEnum {
dbRepMakePartial = 1,
dbRepMakeReadOnly = 2,
}
const enum SetOptionEnum {
dbExclusiveAsyncDelay = 60,
dbFlushTransactionTimeout = 66,
dbImplicitCommitSync = 59,
dbLockDelay = 63,
dbLockRetry = 57,
dbMaxBufferSize = 8,
dbMaxLocksPerFile = 62,
dbPageTimeout = 6,
dbPasswordEncryptionAlgorithm = 81,
dbPasswordEncryptionKeyLength = 82,
dbPasswordEncryptionProvider = 80,
dbRecycleLVs = 65,
dbSharedAsyncDelay = 61,
dbUserCommitSync = 58,
}
const enum SynchronizeTypeEnum {
dbRepExportChanges = 1,
dbRepImpExpChanges = 4,
dbRepImportChanges = 2,
dbRepSyncInternet = 16,
}
const enum TableDefAttributeEnum {
dbAttachedODBC = 536870912,
dbAttachedTable = 1073741824,
dbAttachExclusive = 65536,
dbAttachSavePWD = 131072,
dbHiddenObject = 1,
dbSystemObject = -2147483646,
}
const enum UpdateCriteriaEnum {
dbCriteriaAllCols = 4,
dbCriteriaDeleteInsert = 16,
dbCriteriaKey = 1,
dbCriteriaModValues = 2,
dbCriteriaTimestamp = 8,
dbCriteriaUpdate = 32,
}
const enum UpdateTypeEnum {
dbUpdateBatch = 4,
dbUpdateCurrentRecord = 2,
dbUpdateRegular = 1,
}
const enum WorkspaceTypeEnum {
dbUseJet = 2,
dbUseODBC = 1,
}
class Connection {
private 'DAO.Connection_typekey': Connection;
private constructor();
Cancel(): void;
Close(): void;
readonly Connect: string;
CreateQueryDef(Name?: any, SQLText?: any): QueryDef;
readonly Database: Database;
Execute(Query: string, Options?: any): void;
readonly hDbc: number;
readonly Name: string;
OpenRecordset(Name: string, Type?: any, Options?: any, LockEdit?: any): Recordset;
readonly QueryDefs: QueryDefs;
QueryTimeout: number;
readonly RecordsAffected: number;
readonly Recordsets: Recordsets;
readonly StillExecuting: boolean;
readonly Transactions: boolean;
readonly Updatable: boolean;
}
class Connections {
private 'DAO.Connections_typekey': Connections;
private constructor();
readonly Count: number;
Item(Item: any): Connection;
Refresh(): void;
}
class Container {
private 'DAO.Container_typekey': Container;
private constructor();
readonly AllPermissions: number;
readonly Documents: Documents;
Inherit: boolean;
readonly Name: string;
Owner: string;
Permissions: number;
readonly Properties: Properties;
UserName: string;
}
class Containers {
private 'DAO.Containers_typekey': Containers;
private constructor();
readonly Count: number;
Item(Item: any): Container;
Refresh(): void;
}
class Database {
private 'DAO.Database_typekey': Database;
private constructor();
Close(): void;
readonly CollatingOrder: number;
Connect: string;
readonly Connection: Connection;
readonly Containers: Containers;
CreateProperty(Name?: any, Type?: any, Value?: any, DDL?: any): Property;
CreateQueryDef(Name?: any, SQLText?: any): QueryDef;
CreateRelation(Name?: any, Table?: any, ForeignTable?: any, Attributes?: any): Relation;
CreateTableDef(Name?: any, Attributes?: any, SourceTableName?: any, Connect?: any): TableDef;
DesignMasterID: string;
Execute(Query: string, Options?: any): void;
MakeReplica(PathName: string, Description: string, Options?: any): void;
readonly Name: string;
NewPassword(bstrOld: string, bstrNew: string): void;
OpenRecordset(Name: string, Type?: any, Options?: any, LockEdit?: any): Recordset;
PopulatePartial(DbPathName: string): void;
readonly Properties: Properties;
readonly QueryDefs: QueryDefs;
QueryTimeout: number;
readonly RecordsAffected: number;
readonly Recordsets: Recordsets;
readonly Relations: Relations;
readonly ReplicaID: string;
Synchronize(DbPathName: string, ExchangeType?: any): void;
readonly TableDefs: TableDefs;
readonly Transactions: boolean;
readonly Updatable: boolean;
readonly Version: string;
}
class Databases {
private 'DAO.Databases_typekey': Databases;
private constructor();
readonly Count: number;
Item(Item: any): Database;
Refresh(): void;
}
class DBEngine {
private 'DAO.DBEngine_typekey': DBEngine;
private constructor();
BeginTrans(): void;
/** @param number [Option=0] */
CommitTrans(Option?: number): void;
CompactDatabase(SrcName: string, DstName: string, DstLocale?: any, Options?: any, SrcLocale?: any): void;
CreateDatabase(Name: string, Locale: string, Option?: any): Database;
CreateWorkspace(Name: string, UserName: string, Password: string, UseType?: any): Workspace;
readonly DefaultPassword: string;
DefaultType: number;
readonly DefaultUser: string;
readonly Errors: Errors;
Idle(Action?: any): void;
IniPath: string;
ISAMStats(StatNum: number, Reset?: any): number;
LoginTimeout: number;
OpenConnection(Name: string, Options?: any, ReadOnly?: any, Connect?: any): Connection;
OpenDatabase(Name: string, Options?: any, ReadOnly?: any, Connect?: any): Database;
readonly Properties: Properties;
RegisterDatabase(Dsn: string, Driver: string, Silent: boolean, Attributes: string): void;
RepairDatabase(Name: string): void;
Rollback(): void;
SetOption(Option: number, Value: any): void;
SystemDB: string;
readonly Version: string;
readonly Workspaces: Workspaces;
}
class Document {
private 'DAO.Document_typekey': Document;
private constructor();
readonly AllPermissions: number;
readonly Container: string;
CreateProperty(Name?: any, Type?: any, Value?: any, DDL?: any): Property;
readonly DateCreated: any;
readonly LastUpdated: any;
readonly Name: string;
Owner: string;
Permissions: number;
readonly Properties: Properties;
UserName: string;
}
class Documents {
private 'DAO.Documents_typekey': Documents;
private constructor();
readonly Count: number;
Item(Item: any): Document;
Refresh(): void;
}
class Error {
private 'DAO.Error_typekey': Error;
private constructor();
readonly Description: string;
readonly HelpContext: number;
readonly HelpFile: string;
readonly Number: number;
readonly Source: string;
}
class Errors {
private 'DAO.Errors_typekey': Errors;
private constructor();
readonly Count: number;
Item(Item: any): Error;
Refresh(): void;
}
class Field {
private 'DAO.Field_typekey': Field;
private constructor();
AllowZeroLength: boolean;
AppendChunk(Val: any): void;
Attributes: number;
readonly CollatingOrder: number;
readonly CollectionIndex: number;
CreateProperty(Name?: any, Type?: any, Value?: any, DDL?: any): Property;
readonly DataUpdatable: boolean;
DefaultValue: any;
readonly FieldSize: number;
ForeignName: string;
GetChunk(Offset: number, Bytes: number): any;
Name: string;
OrdinalPosition: number;
readonly OriginalValue: any;
readonly Properties: Properties;
Required: boolean;
Size: number;
readonly SourceField: string;
readonly SourceTable: string;
Type: number;
ValidateOnSet: boolean;
ValidationRule: string;
ValidationText: string;
Value: any;
readonly VisibleValue: any;
}
class Fields {
private 'DAO.Fields_typekey': Fields;
private constructor();
Append(Object: any): void;
readonly Count: number;
Delete(Name: string): void;
Item(Item: any): Field;
Refresh(): void;
}
class Group {
private 'DAO.Group_typekey': Group;
private constructor();
CreateUser(Name?: any, PID?: any, Password?: any): User;
Name: string;
readonly PID: string;
readonly Properties: Properties;
readonly Users: Users;
}
class Groups {
private 'DAO.Groups_typekey': Groups;
private constructor();
Append(Object: any): void;
readonly Count: number;
Delete(Name: string): void;
Item(Item: any): Group;
Refresh(): void;
}
class Index {
private 'DAO.Index_typekey': Index;
private constructor();
Clustered: boolean;
CreateField(Name?: any, Type?: any, Size?: any): Field;
CreateProperty(Name?: any, Type?: any, Value?: any, DDL?: any): Property;
readonly DistinctCount: number;
Fields: any;
readonly Foreign: boolean;
IgnoreNulls: boolean;
Name: string;
Primary: boolean;
readonly Properties: Properties;
Required: boolean;
Unique: boolean;
}
class Indexes {
private 'DAO.Indexes_typekey': Indexes;
private constructor();
Append(Object: any): void;
readonly Count: number;
Delete(Name: string): void;
Item(Item: any): Index;
Refresh(): void;
}
class Parameter {
private 'DAO.Parameter_typekey': Parameter;
private constructor();
Direction: number;
readonly Name: string;
readonly Properties: Properties;
Type: number;
Value: any;
}
class Parameters {
private 'DAO.Parameters_typekey': Parameters;
private constructor();
readonly Count: number;
Item(Item: any): Parameter;
Refresh(): void;
}
/** DAO 3.0 DBEngine (private) */
class PrivDBEngine {
private 'DAO.PrivDBEngine_typekey': PrivDBEngine;
private constructor();
BeginTrans(): void;
/** @param number [Option=0] */
CommitTrans(Option?: number): void;
CompactDatabase(SrcName: string, DstName: string, DstLocale?: any, Options?: any, SrcLocale?: any): void;
CreateDatabase(Name: string, Locale: string, Option?: any): Database;
CreateWorkspace(Name: string, UserName: string, Password: string, UseType?: any): Workspace;
readonly DefaultPassword: string;
DefaultType: number;
readonly DefaultUser: string;
readonly Errors: Errors;
Idle(Action?: any): void;
IniPath: string;
ISAMStats(StatNum: number, Reset?: any): number;
LoginTimeout: number;
OpenConnection(Name: string, Options?: any, ReadOnly?: any, Connect?: any): Connection;
OpenDatabase(Name: string, Options?: any, ReadOnly?: any, Connect?: any): Database;
readonly Properties: Properties;
RegisterDatabase(Dsn: string, Driver: string, Silent: boolean, Attributes: string): void;
RepairDatabase(Name: string): void;
Rollback(): void;
SetOption(Option: number, Value: any): void;
SystemDB: string;
readonly Version: string;
readonly Workspaces: Workspaces;
}
class Properties {
private 'DAO.Properties_typekey': Properties;
private constructor();
Append(Object: any): void;
readonly Count: number;
Delete(Name: string): void;
Item(Item: any): Property;
Refresh(): void;
}
class Property {
private 'DAO.Property_typekey': Property;
private constructor();
readonly Inherited: boolean;
Name: string;
readonly Properties: Properties;
Type: number;
Value: any;
}
class QueryDef {
private 'DAO.QueryDef_typekey': QueryDef;
private constructor();
CacheSize: number;
Cancel(): void;
Close(): void;
Connect: string;
CreateProperty(Name?: any, Type?: any, Value?: any, DDL?: any): Property;
readonly DateCreated: any;
Execute(Options?: any): void;
readonly Fields: Fields;
readonly hStmt: number;
readonly LastUpdated: any;
MaxRecords: number;
Name: string;
ODBCTimeout: number;
OpenRecordset(Type?: any, Options?: any, LockEdit?: any): Recordset;
readonly Parameters: Parameters;
Prepare: any;
readonly Properties: Properties;
readonly RecordsAffected: number;
ReturnsRecords: boolean;
SQL: string;
readonly StillExecuting: boolean;
readonly Type: number;
readonly Updatable: boolean;
}
class QueryDefs {
private 'DAO.QueryDefs_typekey': QueryDefs;
private constructor();
Append(Object: any): void;
readonly Count: number;
Delete(Name: string): void;
Item(Item: any): QueryDef;
Refresh(): void;
}
class Recordset {
private 'DAO.Recordset_typekey': Recordset;
private constructor();
AbsolutePosition: number;
AddNew(): void;
readonly BatchCollisionCount: number;
readonly BatchCollisions: any;
BatchSize: number;
readonly BOF: boolean;
Bookmark: SafeArray<number>;
readonly Bookmarkable: boolean;
CacheSize: number;
CacheStart: SafeArray<number>;
Cancel(): void;
/** @param number [UpdateType=1] */
CancelUpdate(UpdateType?: number): void;
Clone(): Recordset;
Close(): void;
Collect(Item: any): any;
Connection: Connection;
CopyQueryDef(): QueryDef;
readonly DateCreated: any;
Delete(): void;
Edit(): void;
readonly EditMode: number;
readonly EOF: boolean;
readonly Fields: Fields;
FillCache(Rows?: any, StartBookmark?: any): void;
Filter: string;
FindFirst(Criteria: string): void;
FindLast(Criteria: string): void;
FindNext(Criteria: string): void;
FindPrevious(Criteria: string): void;
GetRows(NumRows?: any): any;
readonly hStmt: number;
Index: string;
readonly LastModified: SafeArray<number>;
readonly LastUpdated: any;
LockEdits: boolean;
Move(Rows: number, StartBookmark?: any): void;
MoveFirst(): void;
/** @param number [Options=0] */
MoveLast(Options?: number): void;
MoveNext(): void;
MovePrevious(): void;
readonly Name: string;
NextRecordset(): boolean;
readonly NoMatch: boolean;
readonly ODBCFetchCount: number;
readonly ODBCFetchDelay: number;
OpenRecordset(Type?: any, Options?: any): Recordset;
readonly Parent: Database;
PercentPosition: number;
readonly Properties: Properties;
readonly RecordCount: number;
readonly RecordStatus: number;
Requery(NewQueryDef?: any): void;
readonly Restartable: boolean;
Seek(
Comparison: string, Key1: any, Key2?: any, Key3?: any, Key4?: any, Key5?: any, Key6?: any, Key7?: any, Key8?: any, Key9?: any, Key10?: any, Key11?: any, Key12?: any, Key13?: any): void;
Sort: string;
readonly StillExecuting: boolean;
readonly Transactions: boolean;
readonly Type: number;
readonly Updatable: boolean;
/**
* @param number [UpdateType=1]
* @param boolean [Force=false]
*/
Update(UpdateType?: number, Force?: boolean): void;
UpdateOptions: number;
readonly ValidationRule: string;
readonly ValidationText: string;
}
class Recordsets {
private 'DAO.Recordsets_typekey': Recordsets;
private constructor();
readonly Count: number;
Item(Item: any): Recordset;
Refresh(): void;
}
class Relation {
private 'DAO.Relation_typekey': Relation;
private constructor();
Attributes: number;
CreateField(Name?: any, Type?: any, Size?: any): Field;
readonly Fields: Fields;
ForeignTable: string;
Name: string;
PartialReplica: boolean;
readonly Properties: Properties;
Table: string;
}
class Relations {
private 'DAO.Relations_typekey': Relations;
private constructor();
Append(Object: any): void;
readonly Count: number;
Delete(Name: string): void;
Item(Item: any): Relation;
Refresh(): void;
}
class TableDef {
private 'DAO.TableDef_typekey': TableDef;
private constructor();
Attributes: number;
readonly ConflictTable: string;
Connect: string;
CreateField(Name?: any, Type?: any, Size?: any): Field;
CreateIndex(Name?: any): Index;
CreateProperty(Name?: any, Type?: any, Value?: any, DDL?: any): Property;
readonly DateCreated: any;
readonly Fields: Fields;
readonly Indexes: Indexes;
readonly LastUpdated: any;
Name: string;
OpenRecordset(Type?: any, Options?: any): Recordset;
readonly Properties: Properties;
readonly RecordCount: number;
RefreshLink(): void;
ReplicaFilter: any;
SourceTableName: string;
readonly Updatable: boolean;
ValidationRule: string;
ValidationText: string;
}
class TableDefs {
private 'DAO.TableDefs_typekey': TableDefs;
private constructor();
Append(Object: any): void;
readonly Count: number;
Delete(Name: string): void;
Item(Item: any): TableDef;
Refresh(): void;
}
class User {
private 'DAO.User_typekey': User;
private constructor();
CreateGroup(Name?: any, PID?: any): Group;
readonly Groups: Groups;
Name: string;
NewPassword(bstrOld: string, bstrNew: string): void;
readonly Password: string;
readonly PID: string;
readonly Properties: Properties;
}
class Users {
private 'DAO.Users_typekey': Users;
private constructor();
Append(Object: any): void;
readonly Count: number;
Delete(Name: string): void;
Item(Item: any): User;
Refresh(): void;
}
class Workspace {
private 'DAO.Workspace_typekey': Workspace;
private constructor();
BeginTrans(): void;
Close(): void;
/** @param number [Options=0] */
CommitTrans(Options?: number): void;
readonly Connections: Connections;
CreateDatabase(Name: string, Connect: string, Option?: any): Database;
CreateGroup(Name?: any, PID?: any): Group;
CreateUser(Name?: any, PID?: any, Password?: any): User;
readonly Databases: Databases;
DefaultCursorDriver: number;
readonly Groups: Groups;
readonly hEnv: number;
IsolateODBCTrans: number;
LoginTimeout: number;
Name: string;
OpenConnection(Name: string, Options?: any, ReadOnly?: any, Connect?: any): Connection;
OpenDatabase(Name: string, Options?: any, ReadOnly?: any, Connect?: any): Database;
readonly Properties: Properties;
Rollback(): void;
readonly Type: number;
readonly UserName: string;
readonly Users: Users;
}
class Workspaces {
private 'DAO.Workspaces_typekey': Workspaces;
private constructor();
Append(Object: any): void;
readonly Count: number;
Delete(Name: string): void;
Item(Item: any): Workspace;
Refresh(): void;
}
}
interface ActiveXObject {
new<K extends keyof ActiveXObjectNameMap = any>(progid: K): ActiveXObjectNameMap[K];
}
interface ActiveXObjectNameMap {
'DAO.DBEngine': DAO.DBEngine;
'DAO.DBEngine.120': DAO.DBEngine;
'DAO.Field': DAO.Field;
'DAO.Group': DAO.Group;
'DAO.Index': DAO.Index;
'DAO.PrivateDBEngine': DAO.PrivDBEngine;
'DAO.QueryDef': DAO.QueryDef;
'DAO.Relation': DAO.Relation;
'DAO.TableDef': DAO.TableDef;
'DAO.User': DAO.User;
}
interface EnumeratorConstructor {
new(col: DAO.Connections): Enumerator<DAO.Connection>;
new(col: DAO.Containers): Enumerator<DAO.Container>;
new(col: DAO.Databases): Enumerator<DAO.Database>;
new(col: DAO.Documents): Enumerator<DAO.Document>;
new(col: DAO.Errors): Enumerator<DAO.Error>;
new(col: DAO.Fields): Enumerator<DAO.Field>;
new(col: DAO.Groups): Enumerator<DAO.Group>;
new(col: DAO.Indexes): Enumerator<DAO.Index>;
new(col: DAO.Parameters): Enumerator<DAO.Parameter>;
new(col: DAO.Properties): Enumerator<DAO.Property>;
new(col: DAO.QueryDefs): Enumerator<DAO.QueryDef>;
new(col: DAO.Recordsets): Enumerator<DAO.Recordset>;
new(col: DAO.Relations): Enumerator<DAO.Relation>;
new(col: DAO.TableDefs): Enumerator<DAO.TableDef>;
new(col: DAO.Users): Enumerator<DAO.User>;
new(col: DAO.Workspaces): Enumerator<DAO.Workspace>;
}
interface SafeArray<T = any> {
_brand: SafeArray<T>;
}
+6
View File
@@ -0,0 +1,6 @@
{
"private": true,
"dependencies": {
"activex-helpers": "*"
}
}
+25
View File
@@ -0,0 +1,25 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es5",
"scripthost"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
"activex-dao-tests.ts"
]
}
+6
View File
@@ -0,0 +1,6 @@
{
"extends": "dtslint/dt.json",
"rules": {
"no-const-enum": false
}
}
@@ -1,18 +0,0 @@
//open connection to an Excel file
var pathToExcelFile = 'C:\\path\\to\\excel\\file.xlsx';
var conn = new ActiveXObject('ADODB.Connection');
conn.Provider = 'Microsoft.ACE.OLEDB.12.0';
conn.ConnectionString =
'Data Source="' + pathToExcelFile + '";' +
'Extended Properties="Excel 12.0;HDR=Yes"';
conn.Open();
//create a Command to access the data
var cmd = new ActiveXObject('ADODB.Command');
cmd.CommandText = 'SELECT DISTINCT LastName, CityName FROM [Sheet1$]';
//get a Recordset
var rs = cmd.Execute();
//build a string from the Recordset
var s = rs.GetString(ADODB.StringFormatEnum.adClipString, -1, '\t', '\n', '(NULL)');
rs.Close();
WScript.Echo(s);
-834
View File
@@ -1,834 +0,0 @@
// Type definitions for Microsoft ActiveX Data Objects
// Project: https://msdn.microsoft.com/en-us/library/windows/desktop/ms675532(v=vs.85).aspx
// Definitions by: Zev Spitz <https://github.com/zspitz>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare namespace ADODB {
//Enums
const enum ADCPROP_ASYNCTHREADPRIORITY_ENUM {
adPriorityAboveNormal = 4,
adPriorityBelowNormal = 2,
adPriorityHighest = 5,
adPriorityLowest = 1,
adPriorityNormal = 3
}
const enum ADCPROP_AUTORECALC_ENUM {
adRecalcAlways = 1,
adRecalcUpFront = 0
}
const enum ADCPROP_UPDATECRITERIA_ENUM {
adCriteriaAllCols = 1,
adCriteriaKey = 0,
adCriteriaTimeStamp = 3,
adCriteriaUpdCols = 2
}
const enum ADCPROP_UPDATERESYNC_ENUM {
adResyncAll = 15,
adResyncAutoIncrement = 1,
adResyncConflicts = 2,
adResyncInserts = 8,
adResyncNone = 0,
adResyncUpdates = 4
}
const enum AffectEnum {
adAffectAll = 3,
adAffectAllChapters = 4,
adAffectCurrent = 1,
adAffectGroup = 2
}
const enum BookmarkEnum {
adBookmarkCurrent = 0,
adBookmarkFirst = 1,
adBookmarkLast = 2
}
const enum CommandTypeEnum {
adCmdFile = 256,
adCmdStoredProc = 4,
adCmdTable = 2,
adCmdTableDirect = 512,
adCmdText = 1,
adCmdUnknown = 8,
adCmdUnspecified = -1
}
const enum CompareEnum {
adCompareEqual = 1,
adCompareGreaterThan = 2,
adCompareLessThan = 0,
adCompareNotComparable = 4,
adCompareNotEqual = 3
}
const enum ConnectModeEnum {
adModeRead = 1,
adModeReadWrite = 3,
adModeRecursive = 4194304,
adModeShareDenyNone = 16,
adModeShareDenyRead = 4,
adModeShareDenyWrite = 8,
adModeShareExclusive = 12,
adModeUnknown = 0,
adModeWrite = 2
}
const enum ConnectOptionEnum {
adAsyncConnect = 16,
adConnectUnspecified = -1
}
const enum ConnectPromptEnum {
adPromptAlways = 1,
adPromptComplete = 2,
adPromptCompleteRequired = 3,
adPromptNever = 4
}
const enum CopyRecordOptionsEnum {
adCopyAllowEmulation = 4,
adCopyNonRecursive = 2,
adCopyOverWrite = 1,
adCopyUnspecified = -1
}
const enum CursorLocationEnum {
adUseClient = 3,
adUseClientBatch = 3,
adUseNone = 1,
adUseServer = 2
}
const enum CursorOptionEnum {
adAddNew = 16778240,
adApproxPosition = 16384,
adBookmark = 8192,
adDelete = 16779264,
adFind = 524288,
adHoldRecords = 256,
adIndex = 8388608,
adMovePrevious = 512,
adNotify = 262144,
adResync = 131072,
adSeek = 4194304,
adUpdate = 16809984,
adUpdateBatch = 65536
}
const enum CursorTypeEnum {
adOpenDynamic = 2,
adOpenForwardOnly = 0,
adOpenKeyset = 1,
adOpenStatic = 3,
adOpenUnspecified = -1
}
const enum DataTypeEnum {
adArray = 8192,
adBigInt = 20,
adBinary = 128,
adBoolean = 11,
adBSTR = 8,
adChapter = 136,
adChar = 129,
adCurrency = 6,
adDate = 7,
adDBDate = 133,
adDBTime = 134,
adDBTimeStamp = 135,
adDecimal = 14,
adDouble = 5,
adEmpty = 0,
adError = 10,
adFileTime = 64,
adGUID = 72,
adIDispatch = 9,
adInteger = 3,
adIUnknown = 13,
adLongVarBinary = 205,
adLongVarChar = 201,
adLongVarWChar = 203,
adNumeric = 131,
adPropVariant = 138,
adSingle = 4,
adSmallInt = 2,
adTinyInt = 16,
adUnsignedBigInt = 21,
adUnsignedInt = 19,
adUnsignedSmallInt = 18,
adUnsignedTinyInt = 17,
adUserDefined = 132,
adVarBinary = 204,
adVarChar = 200,
adVariant = 12,
adVarNumeric = 139,
adVarWChar = 202,
adWChar = 130
}
const enum EditModeEnum {
adEditAdd = 2,
adEditDelete = 4,
adEditInProgress = 1,
adEditNone = 0
}
const enum ErrorValueEnum {
adErrBoundToCommand = 3707,
adErrCannotComplete = 3732,
adErrCantChangeConnection = 3748,
adErrCantChangeProvider = 3220,
adErrCantConvertvalue = 3724,
adErrCantCreate = 3725,
adErrCatalogNotSet = 3747,
adErrColumnNotOnThisRow = 3726,
adErrConnectionStringTooLong = 3754,
adErrDataConversion = 3421,
adErrDataOverflow = 3721,
adErrDelResOutOfScope = 3738,
adErrDenyNotSupported = 3750,
adErrDenyTypeNotSupported = 3751,
adErrFeatureNotAvailable = 3251,
adErrFieldsUpdateFailed = 3749,
adErrIllegalOperation = 3219,
adErrIntegrityViolation = 3719,
adErrInTransaction = 3246,
adErrInvalidArgument = 3001,
adErrInvalidConnection = 3709,
adErrInvalidParamInfo = 3708,
adErrInvalidTransaction = 3714,
adErrInvalidURL = 3729,
adErrItemNotFound = 3265,
adErrNoCurrentRecord = 3021,
adErrNotExecuting = 3715,
adErrNotReentrant = 3710,
adErrObjectClosed = 3704,
adErrObjectInCollection = 3367,
adErrObjectNotSet = 3420,
adErrObjectOpen = 3705,
adErrOpeningFile = 3002,
adErrOperationCancelled = 3712,
adErrOutOfSpace = 3734,
adErrPermissionDenied = 3720,
adErrPropConflicting = 3742,
adErrPropInvalidColumn = 3739,
adErrPropInvalidOption = 3740,
adErrPropInvalidValue = 3741,
adErrPropNotAllSettable = 3743,
adErrPropNotSet = 3744,
adErrPropNotSettable = 3745,
adErrPropNotSupported = 3746,
adErrProviderFailed = 3000,
adErrProviderNotFound = 3706,
adErrProviderNotSpecified = 3753,
adErrReadFile = 3003,
adErrResourceExists = 3731,
adErrResourceLocked = 3730,
adErrResourceOutOfScope = 3735,
adErrSchemaViolation = 3722,
adErrSignMismatch = 3723,
adErrStillConnecting = 3713,
adErrStillExecuting = 3711,
adErrTreePermissionDenied = 3728,
adErrUnavailable = 3736,
adErrUnsafeOperation = 3716,
adErrURLDoesNotExist = 3727,
adErrURLNamedRowDoesNotExist = 3737,
adErrVolumeNotFound = 3733,
adErrWriteFile = 3004,
adwrnSecurityDialog = 3717,
adwrnSecurityDialogHeader = 3718
}
const enum EventReasonEnum {
adRsnAddNew = 1,
adRsnClose = 9,
adRsnDelete = 2,
adRsnFirstChange = 11,
adRsnMove = 10,
adRsnMoveFirst = 12,
adRsnMoveLast = 15,
adRsnMoveNext = 13,
adRsnMovePrevious = 14,
adRsnRequery = 7,
adRsnResynch = 8,
adRsnUndoAddNew = 5,
adRsnUndoDelete = 6,
adRsnUndoUpdate = 4,
adRsnUpdate = 3
}
const enum EventStatusEnum {
adStatusCancel = 4,
adStatusCantDeny = 3,
adStatusErrorsOccurred = 2,
adStatusOK = 1,
adStatusUnwantedEvent = 5
}
const enum ExecuteOptionEnum {
adAsyncExecute = 16,
adAsyncFetch = 32,
adAsyncFetchNonBlocking = 64,
adExecuteNoRecords = 128,
adExecuteRecord = 2048,
adExecuteStream = 1024,
adOptionUnspecified = -1
}
const enum FieldAttributeEnum {
adFldCacheDeferred = 4096,
adFldFixed = 16,
adFldIsChapter = 8192,
adFldIsCollection = 262144,
adFldIsDefaultStream = 131072,
adFldIsNullable = 32,
adFldIsRowURL = 65536,
adFldKeyColumn = 32768,
adFldLong = 128,
adFldMayBeNull = 64,
adFldMayDefer = 2,
adFldNegativeScale = 16384,
adFldRowID = 256,
adFldRowVersion = 512,
adFldUnknownUpdatable = 8,
adFldUnspecified = -1,
adFldUpdatable = 4
}
const enum FieldEnum {
adDefaultStream = -1,
adRecordURL = -2
}
const enum FieldStatusEnum {
adFieldAlreadyExists = 26,
adFieldBadStatus = 12,
adFieldCannotComplete = 20,
adFieldCannotDeleteSource = 23,
adFieldCantConvertValue = 2,
adFieldCantCreate = 7,
adFieldDataOverflow = 6,
adFieldDefault = 13,
adFieldDoesNotExist = 16,
adFieldIgnore = 15,
adFieldIntegrityViolation = 10,
adFieldInvalidURL = 17,
adFieldIsNull = 3,
adFieldOK = 0,
adFieldOutOfSpace = 22,
adFieldPendingChange = 262144,
adFieldPendingDelete = 131072,
adFieldPendingInsert = 65536,
adFieldPendingUnknown = 524288,
adFieldPendingUnknownDelete = 1048576,
adFieldPermissionDenied = 9,
adFieldReadOnly = 24,
adFieldResourceExists = 19,
adFieldResourceLocked = 18,
adFieldResourceOutOfScope = 25,
adFieldSchemaViolation = 11,
adFieldSignMismatch = 5,
adFieldTruncated = 4,
adFieldUnavailable = 8,
adFieldVolumeNotFound = 21
}
const enum FilterGroupEnum {
adFilterAffectedRecords = 2,
adFilterConflictingRecords = 5,
adFilterFetchedRecords = 3,
adFilterNone = 0,
adFilterPendingRecords = 1,
adFilterPredicate = 4
}
const enum GetRowsOptionEnum {
adGetRowsRest = -1
}
const enum IsolationLevelEnum {
adXactBrowse = 256,
adXactChaos = 16,
adXactCursorStability = 4096,
adXactIsolated = 1048576,
adXactReadCommitted = 4096,
adXactReadUncommitted = 256,
adXactRepeatableRead = 65536,
adXactSerializable = 1048576,
adXactUnspecified = -1
}
const enum LineSeparatorEnum {
adCR = 13,
adCRLF = -1,
adLF = 10
}
const enum LockTypeEnum {
adLockBatchOptimistic = 4,
adLockOptimistic = 3,
adLockPessimistic = 2,
adLockReadOnly = 1,
adLockUnspecified = -1
}
const enum MarshalOptionsEnum {
adMarshalAll = 0,
adMarshalModifiedOnly = 1
}
const enum MoveRecordOptionsEnum {
adMoveAllowEmulation = 4,
adMoveDontUpdateLinks = 2,
adMoveOverWrite = 1,
adMoveUnspecified = -1
}
const enum ObjectStateEnum {
adStateClosed = 0,
adStateConnecting = 2,
adStateExecuting = 4,
adStateFetching = 8,
adStateOpen = 1
}
const enum ParameterAttributesEnum {
adParamLong = 128,
adParamNullable = 64,
adParamSigned = 16
}
const enum ParameterDirectionEnum {
adParamInput = 1,
adParamInputOutput = 3,
adParamOutput = 2,
adParamReturnValue = 4,
adParamUnknown = 0
}
const enum PersistFormatEnum {
adPersistADTG = 0,
adPersistXML = 1
}
const enum PositionEnum {
adPosBOF = -2,
adPosEOF = -3,
adPosUnknown = -1
}
const enum PositionEnum_Param {
adPosBOF = -2,
adPosEOF = -3,
adPosUnknown = -1
}
const enum PropertyAttributesEnum {
adPropNotSupported = 0,
adPropOptional = 2,
adPropRead = 512,
adPropRequired = 1,
adPropWrite = 1024
}
const enum RecordCreateOptionsEnum {
adCreateCollection = 8192,
adCreateNonCollection = 0,
adCreateOverwrite = 67108864,
adCreateStructDoc = -2147483648,
adFailIfNotExists = -1,
adOpenIfExists = 33554432
}
const enum RecordOpenOptionsEnum {
adDelayFetchFields = 32768,
adDelayFetchStream = 16384,
adOpenAsync = 4096,
adOpenExecuteCommand = 65536,
adOpenOutput = 8388608,
adOpenRecordUnspecified = -1,
adOpenSource = 8388608
}
const enum RecordStatusEnum {
adRecCanceled = 256,
adRecCantRelease = 1024,
adRecConcurrencyViolation = 2048,
adRecDBDeleted = 262144,
adRecDeleted = 4,
adRecIntegrityViolation = 4096,
adRecInvalid = 16,
adRecMaxChangesExceeded = 8192,
adRecModified = 2,
adRecMultipleChanges = 64,
adRecNew = 1,
adRecObjectOpen = 16384,
adRecOK = 0,
adRecOutOfMemory = 32768,
adRecPendingChanges = 128,
adRecPermissionDenied = 65536,
adRecSchemaViolation = 131072,
adRecUnmodified = 8
}
const enum RecordTypeEnum {
adCollectionRecord = 1,
adSimpleRecord = 0,
adStructDoc = 2
}
const enum ResyncEnum {
adResyncAllValues = 2,
adResyncUnderlyingValues = 1
}
const enum SaveOptionsEnum {
adSaveCreateNotExist = 1,
adSaveCreateOverWrite = 2
}
const enum SchemaEnum {
adSchemaActions = 41,
adSchemaAsserts = 0,
adSchemaCatalogs = 1,
adSchemaCharacterSets = 2,
adSchemaCheckConstraints = 5,
adSchemaCollations = 3,
adSchemaColumnPrivileges = 13,
adSchemaColumns = 4,
adSchemaColumnsDomainUsage = 11,
adSchemaCommands = 42,
adSchemaConstraintColumnUsage = 6,
adSchemaConstraintTableUsage = 7,
adSchemaCubes = 32,
adSchemaDBInfoKeywords = 30,
adSchemaDBInfoLiterals = 31,
adSchemaDimensions = 33,
adSchemaForeignKeys = 27,
adSchemaFunctions = 40,
adSchemaHierarchies = 34,
adSchemaIndexes = 12,
adSchemaKeyColumnUsage = 8,
adSchemaLevels = 35,
adSchemaMeasures = 36,
adSchemaMembers = 38,
adSchemaPrimaryKeys = 28,
adSchemaProcedureColumns = 29,
adSchemaProcedureParameters = 26,
adSchemaProcedures = 16,
adSchemaProperties = 37,
adSchemaProviderSpecific = -1,
adSchemaProviderTypes = 22,
adSchemaReferentialConstraints = 9,
adSchemaReferentialContraints = 9,
adSchemaSchemata = 17,
adSchemaSets = 43,
adSchemaSQLLanguages = 18,
adSchemaStatistics = 19,
adSchemaTableConstraints = 10,
adSchemaTablePrivileges = 14,
adSchemaTables = 20,
adSchemaTranslations = 21,
adSchemaTrustees = 39,
adSchemaUsagePrivileges = 15,
adSchemaViewColumnUsage = 24,
adSchemaViews = 23,
adSchemaViewTableUsage = 25
}
const enum SearchDirection {
adSearchBackward = -1,
adSearchForward = 1
}
const enum SearchDirectionEnum {
adSearchBackward = -1,
adSearchForward = 1
}
const enum SeekEnum {
adSeekAfter = 8,
adSeekAfterEQ = 4,
adSeekBefore = 32,
adSeekBeforeEQ = 16,
adSeekFirstEQ = 1,
adSeekLastEQ = 2
}
const enum StreamOpenOptionsEnum {
adOpenStreamAsync = 1,
adOpenStreamFromRecord = 4,
adOpenStreamUnspecified = -1
}
const enum StreamReadEnum {
adReadAll = -1,
adReadLine = -2
}
const enum StreamTypeEnum {
adTypeBinary = 1,
adTypeText = 2
}
const enum StreamWriteEnum {
adWriteChar = 0,
adWriteLine = 1,
stWriteChar = 0,
stWriteLine = 1
}
const enum StringFormatEnum {
adClipString = 2
}
const enum XactAttributeEnum {
adXactAbortRetaining = 262144,
adXactAsyncPhaseOne = 524288,
adXactCommitRetaining = 131072,
adXactSyncPhaseOne = 1048576
}
//Interfaces
interface Command {
ActiveConnection: Connection;
Cancel: () => void;
CommandStream: any /*VT_UNKNOWN*/;
CommandText: string;
CommandTimeout: number;
CommandType: CommandTypeEnum;
CreateParameter: (Name?: string, Type?: DataTypeEnum, Direction?: ParameterDirectionEnum, Size?: number, Value?: any) => Parameter;
Dialect: string;
Execute: (RecordsAffected?: any, Parameters?: any, Options?: number) => Recordset;
Name: string;
NamedParameters: boolean;
Parameters: Parameters;
Prepared: boolean;
Properties: Properties;
State: number;
}
interface Connection {
Attributes: number;
BeginTrans: () => number;
Cancel: () => void;
Close: () => void;
CommandTimeout: number;
CommitTrans: () => void;
ConnectionString: string;
ConnectionTimeout: number;
CursorLocation: CursorLocationEnum;
DefaultDatabase: string;
Errors: Errors;
Execute: (CommandText: string, RecordsAffected: any, Options?: number) => Recordset;
IsolationLevel: IsolationLevelEnum;
Mode: ConnectModeEnum;
Open: (ConnectionString?: string, UserID?: string, Password?: string, Options?: number) => void;
OpenSchema: (Schema: SchemaEnum, Restrictions?: any, SchemaID?: any) => Recordset;
Properties: Properties;
Provider: string;
RollbackTrans: () => void;
State: number;
Version: string;
}
interface Error {
Description: string;
HelpContext: number;
HelpFile: string;
NativeError: number;
Number: number;
Source: string;
SQLState: string;
}
interface Errors {
Clear: () => void;
Count: number;
Item: (Index: any) => Error;
Refresh: () => void;
}
interface Field {
ActualSize: number;
AppendChunk: (Data: any) => void;
Attributes: number;
DataFormat: any /*VT_UNKNOWN*/;
DefinedSize: number;
GetChunk: (Length: number) => any;
Name: string;
NumericScale: number;
OriginalValue: any;
Precision: number;
Properties: Properties;
Status: number;
Type: DataTypeEnum;
UnderlyingValue: any;
Value: any;
}
interface Fields {
_Append: (Name: string, Type: DataTypeEnum, DefinedSize?: number, Attrib?: FieldAttributeEnum) => void;
Append: (Name: string, Type: DataTypeEnum, DefinedSize?: number, Attrib?: FieldAttributeEnum, FieldValue?: any) => void;
CancelUpdate: () => void;
Count: number;
Delete: (Index: any) => void;
Item: (Index: any) => Field;
Refresh: () => void;
Resync: (ResyncValues?: ResyncEnum) => void;
Update: () => void;
}
interface Parameter {
AppendChunk: (Val: any) => void;
Attributes: number;
Direction: ParameterDirectionEnum;
Name: string;
NumericScale: number;
Precision: number;
Properties: Properties;
Size: number;
Type: DataTypeEnum;
Value: any;
}
interface Parameters {
Append: (Object: any /*VT_DISPATCH*/) => void;
Count: number;
Delete: (Index: any) => void;
Item: (Index: any) => Parameter;
Refresh: () => void;
}
interface Properties {
Count: number;
Item: (Index: any) => Property;
Refresh: () => void;
}
interface Property {
Attributes: number;
Name: string;
Type: DataTypeEnum;
Value: any;
}
interface Record {
ActiveConnection: any;
Cancel: () => void;
Close: () => void;
CopyRecord: (Source?: string, Destination?: string, UserName?: string, Password?: string, Options?: CopyRecordOptionsEnum, Async?: boolean) => string;
DeleteRecord: (Source?: string, Async?: boolean) => void;
Fields: Fields;
GetChildren: () => Recordset;
Mode: ConnectModeEnum;
MoveRecord: (Source?: string, Destination?: string, UserName?: string, Password?: string, Options?: MoveRecordOptionsEnum, Async?: boolean) => string;
Open: (Source: any, ActiveConnection: any, Mode?: ConnectModeEnum, CreateOptions?: RecordCreateOptionsEnum, Options?: RecordOpenOptionsEnum, UserName?: string, Password?: string) => void;
ParentURL: string;
Properties: Properties;
RecordType: RecordTypeEnum;
Source: any;
State: ObjectStateEnum;
}
interface Recordset {
_xClone: () => Recordset;
_xResync: (AffectRecords?: AffectEnum) => void;
_xSave: (FileName?: string, PersistFormat?: PersistFormatEnum) => void;
AbsolutePage: PositionEnum;
AbsolutePosition: PositionEnum;
ActiveCommand: any /*VT_DISPATCH*/;
ActiveConnection: any /*VT_DISPATCH*/;
AddNew: (FieldList?: any, Values?: any) => void;
BOF: boolean;
Bookmark: any;
CacheSize: number;
Cancel: () => void;
CancelBatch: (AffectRecords?: AffectEnum) => void;
CancelUpdate: () => void;
Clone: (LockType?: LockTypeEnum) => Recordset;
Close: () => void;
Collect: (Index: any) => any; //Also has setter with parameters
CompareBookmarks: (Bookmark1: any, Bookmark2: any) => CompareEnum;
CursorLocation: CursorLocationEnum;
CursorType: CursorTypeEnum;
DataMember: string;
DataSource: any /*VT_UNKNOWN*/;
Delete: (AffectRecords?: AffectEnum) => void;
EditMode: EditModeEnum;
EOF: boolean;
Fields: Fields;
Filter: any;
Find: (Criteria: string, SkipRecords?: number, SearchDirection?: SearchDirectionEnum, Start?: any) => void;
GetRows: (Rows?: number, Start?: any, Fields?: any) => any;
GetString: (StringFormat?: StringFormatEnum, NumRows?: number, ColumnDelimeter?: string, RowDelimeter?: string, NullExpr?: string) => string;
Index: string;
LockType: LockTypeEnum;
MarshalOptions: MarshalOptionsEnum;
MaxRecords: number;
Move: (NumRecords: number, Start?: any) => void;
MoveFirst: () => void;
MoveLast: () => void;
MoveNext: () => void;
MovePrevious: () => void;
NextRecordset: (RecordsAffected?: any) => Recordset;
Open: (Source: any, ActiveConnection: any, CursorType?: CursorTypeEnum, LockType?: LockTypeEnum, Options?: number) => void;
PageCount: number;
PageSize: number;
Properties: Properties;
RecordCount: number;
Requery: (Options?: number) => void;
Resync: (AffectRecords?: AffectEnum, ResyncValues?: ResyncEnum) => void;
Save: (Destination: any, PersistFormat?: PersistFormatEnum) => void;
Seek: (KeyValues: any, SeekOption?: SeekEnum) => void;
Sort: string;
Source: any /*VT_DISPATCH*/;
State: number;
Status: number;
StayInSync: boolean;
Supports: (CursorOptions: CursorOptionEnum) => boolean;
Update: (Fields?: any, Values?: any) => void;
UpdateBatch: (AffectRecords?: AffectEnum) => void;
}
interface Stream {
Cancel: () => void;
Charset: string;
Close: () => void;
CopyTo: (DestStream: Stream, CharNumber?: number) => void;
EOS: boolean;
Flush: () => void;
LineSeparator: LineSeparatorEnum;
LoadFromFile: (FileName: string) => void;
Mode: ConnectModeEnum;
Open: (Source: any, Mode?: ConnectModeEnum, Options?: StreamOpenOptionsEnum, UserName?: string, Password?: string) => void;
Position: number;
Read: (NumBytes?: number) => any;
ReadText: (NumChars?: number) => string;
SaveToFile: (FileName: string, Options?: SaveOptionsEnum) => void;
SetEOS: () => void;
Size: number;
SkipLine: () => void;
State: ObjectStateEnum;
Type: StreamTypeEnum;
Write: (Buffer: any) => void;
WriteText: (Data: string, Options?: StreamWriteEnum) => void;
}
}
interface ActiveXObject {
new (progID: 'ADODB.Connection'): ADODB.Connection;
new (progID: 'ADODB.Record'): ADODB.Record;
new (progID: 'ADODB.Stream'): ADODB.Stream;
new (progID: 'ADODB.Command'): ADODB.Command;
new (progID: 'ADODB.Recordset'): ADODB.Recordset;
new (progID: 'ADODB.Parameter'): ADODB.Parameter;
}
-24
View File
@@ -1,24 +0,0 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6",
"dom",
"scripthost"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": false,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.d.ts",
"activex-data-objects-tests.ts"
]
}
@@ -0,0 +1,44 @@
const collectionToArray = <T>(col: any) => { // tslint:disable-line no-unnecessary-generics
const results: T[] = [];
const enumerator = new Enumerator<T>(col);
enumerator.moveFirst();
while (!enumerator.atEnd()) {
results.push(enumerator.item());
enumerator.moveNext();
}
return results;
};
// https://msdn.microsoft.com/en-us/library/windows/desktop/bb787925(v=vs.85).aspx
(() => {
const enumUsers = (label: string) => {
const volume = new ActiveXObject('Microsoft.DiskQuota');
volume.Initialize(label, true);
collectionToArray<DiskQuotaTypeLibrary.DIDiskQuotaUser>(volume).forEach(x => {
// Use the QuotaUser object to retrieve or set one or more of the user's disk quota properties
});
};
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/bb787916(v=vs.85).aspx
(() => {
const volume = new ActiveXObject('Microsoft.DiskQuota');
volume.Initialize('MYDISK', true);
ActiveXObject.on(volume, 'OnUserNameChanged', ['pUser'], p => {
// Code to handle the event.
});
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/bb787904(v=vs.85).aspx
(() => {
const dqc = new ActiveXObject('Microsoft.DiskQuota');
dqc.Initialize('MYDISK', true);
const findName = (name: string) => {
try {
return dqc.FindUser(name);
} catch { }
try {
return dqc.FindUser(dqc.TranslateLogonNameToSID(name));
} catch { }
};
})();
+152
View File
@@ -0,0 +1,152 @@
// Type definitions for DiskQuotaTypeLibrary 1.0
// Project: https://msdn.microsoft.com/en-us/library/windows/desktop/bb773938(v=vs.85).aspx
// Definitions by: Zev Spitz <https://github.com/zspitz>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.5
declare namespace DiskQuotaTypeLibrary {
// tslint:disable-next-line no-const-enum
const enum AccountStatusConstants {
dqAcctDeleted = 2,
dqAcctInvalid = 3,
dqAcctResolved = 0,
dqAcctUnavailable = 1,
dqAcctUnknown = 4,
dqAcctUnresolved = 5,
}
// tslint:disable-next-line no-const-enum
const enum QuotaStateConstants {
dqStateDisable = 0,
dqStateEnforce = 2,
dqStateTrack = 1,
}
// tslint:disable-next-line no-const-enum
const enum UserNameResolutionConstants {
dqResolveAsync = 2,
dqResolveNone = 0,
dqResolveSync = 1,
}
/** Automation interface for DiskQuotaUser */
class DIDiskQuotaUser {
private 'DiskQuotaTypeLibrary.DIDiskQuotaUser_typekey': DIDiskQuotaUser;
private constructor();
/** Name of user's account container */
readonly AccountContainerName: string;
/** Status of user's account */
readonly AccountStatus: AccountStatusConstants;
/** User's display name */
readonly DisplayName: string;
/** Unique ID number */
readonly ID: number;
/** Invalidate data cached in user object */
Invalidate(): void;
/** User's logon account name */
readonly LogonName: string;
/** User's quota limit (bytes) */
QuotaLimit: number;
/** User's quota limit (text) */
readonly QuotaLimitText: string;
/** User's quota warning threshold (bytes) */
QuotaThreshold: number;
/** User's quota warning threshold (text) */
readonly QuotaThresholdText: string;
/** Quota charged to user (bytes) */
readonly QuotaUsed: number;
/** Quota charged to user (text) */
readonly QuotaUsedText: string;
}
/** Microsoft Disk Quota */
class DiskQuotaControl {
private 'DiskQuotaTypeLibrary.DiskQuotaControl_typekey': DiskQuotaControl;
private constructor();
/** Add a user quota entry by Name */
AddUser(LogonName: string): DIDiskQuotaUser;
/** Default quota limit applied to new volume users (byte value) */
DefaultQuotaLimit: number;
/** Default quota limit applied to new volume users (text string) */
readonly DefaultQuotaLimitText: string;
/** Default warning threshold applied to new volume users (byte value) */
DefaultQuotaThreshold: number;
/** Default warning threshold applied to new volume users (text string) */
readonly DefaultQuotaThresholdText: string;
/** Delete a user quota entry */
DeleteUser(pUser: DIDiskQuotaUser): void;
/** Find a user quota entry by Name */
FindUser(LogonName: string): DIDiskQuotaUser;
/** Promote a user quota entry to the head of the name resolution queue */
GiveUserNameResolutionPriority(pUser: DIDiskQuotaUser): void;
/** Initialize the quota control object for a specified volume */
Initialize(path: string, bReadWrite: boolean): void;
/** Invalidate the cache of user name information */
InvalidateSidNameCache(): void;
/** Write event log entry when user exceeds quota limit */
LogQuotaLimit: boolean;
/** Write event log entry when user exceeds quota warning threshold */
LogQuotaThreshold: boolean;
/** Indicates if quota information is out of date */
readonly QuotaFileIncomplete: boolean;
/** Indicates if quota information is being rebuilt */
readonly QuotaFileRebuilding: boolean;
/** State of the volume's disk quota system */
QuotaState: QuotaStateConstants;
/** Terminate the user name resolution thread */
ShutdownNameResolution(): void;
/** Translates a user logon name to a security ID */
TranslateLogonNameToSID(LogonName: string): string;
/** Control the resolution of user Security IDs to user Names */
UserNameResolution: UserNameResolutionConstants;
}
}
interface ActiveXObject {
on(
obj: DiskQuotaTypeLibrary.DiskQuotaControl, event: 'OnUserNameChanged', argNames: ['pUser'], handler: (
this: DiskQuotaTypeLibrary.DiskQuotaControl, parameter: {readonly pUser: DiskQuotaTypeLibrary.DIDiskQuotaUser}) => void): void;
new<K extends keyof ActiveXObjectNameMap = any>(progid: K): ActiveXObjectNameMap[K];
}
interface ActiveXObjectNameMap {
'Microsoft.DiskQuota': DiskQuotaTypeLibrary.DiskQuotaControl;
}
interface EnumeratorConstructor {
new(col: DiskQuotaTypeLibrary.DiskQuotaControl): Enumerator<DiskQuotaTypeLibrary.DIDiskQuotaUser>;
}
interface SafeArray<T = any> {
_brand: SafeArray<T>;
}
+6
View File
@@ -0,0 +1,6 @@
{
"private": true,
"dependencies": {
"activex-helpers": "*"
}
}
+25
View File
@@ -0,0 +1,25 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es5",
"scripthost"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
"activex-diskquota-tests.ts"
]
}
+3
View File
@@ -0,0 +1,3 @@
{
"extends": "dtslint/dt.json"
}
+320
View File
@@ -0,0 +1,320 @@
/// <reference types="activex-msforms" />
/// <reference types="activex-scripting" />
// some helpers
const toSafeArray = <T>(...items: T[]): SafeArray<T> => {
const dict = new ActiveXObject('Scripting.Dictionary');
items.forEach((x, index) => dict.Add(index, x));
return dict.Items() as SafeArray<T>;
};
const inCollection = <T = any>(collection: { Item(index: any): T }, index: string | number): T | undefined => {
let item: T | undefined;
try {
item = collection.Item(index);
} catch (error) { }
return item;
};
const app = new ActiveXObject('Excel.Application');
// create a workbook -- https://msdn.microsoft.com/en-us/vba/excel-vba/articles/create-a-workbook
const newBook = app.Workbooks.Add();
newBook.Title = 'All Sales';
newBook.Subject = 'Sales';
newBook.SaveAs('allsales.xls');
// create or replace a worksheet -- https://msdn.microsoft.com/en-us/vba/excel-vba/articles/create-or-replace-a-worksheet
const newOrExistingWorksheet = () => {
const mySheetName = 'Sheet4';
let mySheet = inCollection(newBook.Worksheets, mySheetName) as Excel.Worksheet | undefined;
if (!mySheet) {
WScript.Echo(`The sheet named "${mySheetName} doesn't exist, but will be created.`);
mySheet = app.Worksheets.Add() as Excel.Worksheet;
mySheet.Name = mySheetName;
}
};
const replaceWorksheet = () => {
const mySheetName = 'Sheet4';
app.DisplayAlerts = false;
let mySheet = inCollection<Excel.Worksheet | Excel.Chart | Excel.DialogSheet>(app.Worksheets, mySheetName);
if (mySheet) { mySheet.Delete(); }
app.DisplayAlerts = true;
mySheet = app.Worksheets.Add() as Excel.Worksheet;
mySheet.Name = mySheetName;
WScript.Echo(`The sheet named "${mySheetName} has been replaced.`);
};
// referencing multiple sheets -- https://msdn.microsoft.com/VBA/Excel-VBA/articles/sheets-object-excel
const moveMultipleSheets = () => {
app.Worksheets.Item(toSafeArray<string | number>(1, 'Sheet2')).Move(4);
};
// sort worksheets alphanumerically by name -- https://msdn.microsoft.com/en-us/vba/excel-vba/articles/sort-worksheets-alphanumerically-by-name
const sortSheetsTabName = () => {
app.ScreenUpdating = false;
const sheets = app.ActiveWorkbook.Sheets;
const sheetCount = sheets.Count;
for (let i = 0; i < sheetCount; i += 1) {
const sheetI = sheets.Item(i);
for (let j = i; j < sheetCount; j += 1) {
const sheetJ = sheets.Item(j);
if (sheetJ.Name < sheetI.Name) { sheetJ.Move(sheetI); }
}
}
app.ScreenUpdating = true;
};
// fill a value down into blank cells in a column -- https://msdn.microsoft.com/en-us/vba/excel-vba/articles/fill-a-value-down-into-blank-cells-in-a-column
const fillCellsFromAbove = () => {
app.ScreenUpdating = false;
const columnA = app.Columns.Item(1);
try {
columnA.SpecialCells(Excel.XlCellType.xlCellTypeBlanks).Formula = '=R[-1]C';
columnA.Value = columnA.Value;
} catch (error) { }
app.ScreenUpdating = true;
};
// hide and unhide columns -- https://msdn.microsoft.com/en-us/vba/excel-vba/articles/hide-and-unhide-columns
const setColumnVisibility = (visible: boolean) => {
const book = app.Workbooks.Item(1);
const sheet = inCollection<Excel.Worksheet | Excel.Chart | Excel.DialogSheet>(book.Worksheets, 'Sheet1');
if (!sheet) { return; }
// search the four columns for any constants
const checkWithin = (sheet as Excel.Worksheet).Range('A1:D1').SpecialCells(Excel.XlCellType.xlCellTypeConstants);
let find = checkWithin.Find('X');
if (!find) { return; }
const address = find.Address();
// hide the column, and then find the next X
do {
find.EntireColumn.Hidden = visible;
find = checkWithin.FindNext(find);
} while (find && find.Address() !== address);
};
// highlighting the active cell, row, or column -- https://msdn.microsoft.com/en-us/vba/excel-vba/articles/highlight-the-active-cell-row-or-column
(() => {
const wks = app.ActiveSheet as Excel.Worksheet;
// highlight active cell
ActiveXObject.on(wks, 'SelectionChange', ['Target'], function(this: Excel.Worksheet, prm) {
app.ScreenUpdating = false;
// clear the color of all the cells
this.Cells.Interior.ColorIndex = 0;
// highlight the actie cell
prm.Target.Interior.ColorIndex = 8;
app.ScreenUpdating = true;
});
// highlight entire row and column that contain active cell
ActiveXObject.on(wks, 'SelectionChange', ['Target'], function(this: Excel.Worksheet, prm) {
if (prm.Target.Cells.Count > 1) { return; }
app.ScreenUpdating = false;
// clear the color of all the cells in the row and column of the active cell
this.Cells.Interior.ColorIndex = 0;
prm.Target.EntireRow.Interior.ColorIndex = 8;
prm.Target.EntireColumn.Interior.ColorIndex = 8;
app.ScreenUpdating = true;
});
})();
// referencing cells -- https://msdn.microsoft.com/en-us/vba/excel-vba/articles/reference-cells-and-ranges
(() => {
const wks = app.ActiveSheet as Excel.Worksheet;
// all the cells on a worksheet
wks.Cells.ClearContents();
// using A1 notation
wks.Range('A1').Font.Bold = true;
wks.Range('A1:D5').Font.Bold = true;
wks.Range('C5:D9,G9:H16').Font.Bold = true;
wks.Range('A:A').Font.Bold = true;
wks.Range('1:1').Font.Bold = true;
wks.Range('A:C').Font.Bold = true;
wks.Range('1:5').Font.Bold = true;
wks.Range('1:1,3:3,8:8').Font.Bold = true;
wks.Range('A:A,C:C,F:F').Font.Bold = true;
// using index numbers
wks.Cells.Item(6, 1).Value2 = 10;
// Value is also a property with parameters
ActiveXObject.set(wks.Cells.Item(6, 1), 'Value', 10);
// iterating through cells using index numbers
for (let counter = 1; counter < 20; counter += 1) {
ActiveXObject.set(wks.Cells.Item(counter, 1), 'Value', 10);
}
// relative to other cells
wks.Cells.Item(1, 1).Font.Underline = Excel.XlUnderlineStyle.xlUnderlineStyleDouble;
// using a Range object
const rng = wks.Cells.Item('A1:D5');
rng.Formula = '=RAND()';
rng.Font.Bold = true;
// refer to multiple ranges, using Union
const r1 = wks.Range('A1:A10');
const r2 = wks.Range('B4:B20');
const union = app.Union(r1, r2);
union.Font.Bold = true;
// refer to multiple ranges using Areas
WScript.Echo(union.Areas.Count);
})();
// looping through a range of cells -- https://msdn.microsoft.com/en-us/vba/excel-vba/articles/looping-through-a-range-of-cells
(() => {
const wks = app.ActiveSheet as Excel.Worksheet;
// using for
for (let x = 1; x < 20; x++) {
const currentCell = wks.Cells.Item(x, 1);
if (Math.abs(currentCell.Value()) < 0.01) {
// because Value is typed as a method on the Excel.Range class, we have to treat it as a setter with parameters
ActiveXObject.set(currentCell, 'Value', 0);
}
}
// using Enumerator
let enumerator = new Enumerator(wks.Cells.Item('A1:D10'));
enumerator.moveFirst();
while (!enumerator.atEnd()) {
const currentCell = enumerator.item();
if (Math.abs(currentCell.Value) < 0.01) {
currentCell.Value = 0;
}
enumerator.moveNext();
}
// using CurrentRegion
enumerator = new Enumerator(app.ActiveCell.CurrentRegion);
enumerator.moveFirst();
while (!enumerator.atEnd()) {
const cell = enumerator.item();
if (Math.abs(cell.Value) < 0.01) {
cell.Value = 0;
}
enumerator.moveNext();
}
})();
// using selection -- https://msdn.microsoft.com/en-us/vba/excel-vba/articles/selecting-and-activating-cells
(() => {
const wks = app.ActiveWorkbook.Worksheets.Item(1) as Excel.Worksheet;
// make a worksheet the active worksheet; otherwise code which uses the selection will fail
wks.Select();
// select a cell
wks.Range("A1").Select();
app.ActiveCell.Font.Bold = true;
// activate a cell; only a single cell can be active at any given time
wks.Range("B1").Activate();
// working with 3-D ranges -- https://msdn.microsoft.com/en-us/vba/excel-vba/articles/working-with-3-d-ranges
app.Sheets.Item(toSafeArray("Sheet2", "Sheet3", "Sheet4")).Select();
app.Range("A1:H1").Select();
(app.Selection as Excel.Range).Borders.Item(Excel.XlBordersIndex.xlEdgeBottom).LineStyle = Excel.XlLineStyle.xlDouble;
// alternatively, use FillAcrossSheets to fill formatting and data across sheets
const book = app.ActiveWorkbook;
const wks2 = book.Sheets.Item("Sheet2") as Excel.Worksheet;
const rng = wks2.Range("A1:H1");
rng.Borders.Item(Excel.XlBordersIndex.xlEdgeBottom).LineStyle = Excel.XlLineStyle.xlDouble;
book.Sheets.FillAcrossSheets(rng);
})();
// prevent duplicate entry -- https://msdn.microsoft.com/en-us/vba/excel-vba/articles/prevent-duplicate-entries-in-a-range
(() => {
const book = app.Workbooks.Item(1);
ActiveXObject.on(book, 'SheetChange', ['Sh', 'Target'], function(this, prm) {
const EvalRange = this.ActiveSheet.Range("A1:B20");
// If the cell where the value was entered is not in the defined range, if the value pasted is larger than a single cell, or if no value was entered in the cell, then exit the macro
if (
(app.Intersect(prm.Target, EvalRange) == null) ||
(prm.Target.Cells.Count > 1)
// VBA has a function called IsEmpty; not sure what the equivalent is in Javascript
) { return; }
// If the value entered already exists in the defined range on the current worksheet, undo and exit
if (app.WorksheetFunction.CountIf(EvalRange, prm.Target.Value()) > 1) {
app.EnableEvents = false;
app.Undo();
app.EnableEvents = true;
return;
}
const enumerator = new Enumerator(book.Worksheets);
enumerator.moveFirst();
while (!enumerator.atEnd()) {
const wks = enumerator.item() as Excel.Worksheet;
if (wks.Name === prm.Target.Name) { continue; }
// If the value entered already exists in the defined range on the current worksheet, undo the entry.
if (app.WorksheetFunction.CountIf(wks.Range('A1:B20'), prm.Target.Value()) === 0) { continue; }
app.EnableEvents = false;
app.Undo();
app.EnableEvents = true;
}
});
})();
// add a unique list of values to a combobox -- https://msdn.microsoft.com/en-us/vba/excel-vba/articles/add-a-unique-list-of-values-to-a-combo-box
(() => {
(() => {
// using the AdvancedFilter property
const book = app.ThisWorkbook;
const sheet = book.Worksheets.Item("Sheet1") as Excel.Worksheet;
const dataRange = sheet.Range('A1', sheet.Range("A100").End(Excel.XlDirection.xlUp));
dataRange.AdvancedFilter(Excel.XlFilterAction.xlFilterCopy, undefined, sheet.Range('L1'), true);
const data = sheet.Range("L2", sheet.Range('L100').End(Excel.XlDirection.xlUp)).Value() as SafeArray;
sheet.Range('L1', sheet.Range('L100').End(Excel.XlDirection.xlUp)).ClearContents();
const combobox = sheet.OLEObjects('ComboBox1').Object as MSForms.ComboBox2;
combobox.Clear();
ActiveXObject.set(combobox, 'List', [], data);
combobox.ListIndex = -1;
})();
(() => {
// using a Dictionary
const sheet = app.ThisWorkbook.Sheets.Item('Sheet2') as Excel.Worksheet;
const data = sheet.Range('A2', sheet.Range('A100').End(Excel.XlDirection.xlUp)).Value2 as SafeArray;
const arr = new VBArray(data).toArray();
const dict = new ActiveXObject('Scripting.Dictionary');
arr.forEach(x => ActiveXObject.set(dict, 'Item', [x], true));
const combobox = sheet.OLEObjects('ComboBox1').Object as MSForms.ComboBox2;
combobox.Clear();
const enumerator = new Enumerator(dict.Items());
enumerator.moveFirst();
while (!enumerator.atEnd()) {
combobox.AddItem(enumerator.item());
}
})();
})();
// animating a sparkline -- https://msdn.microsoft.com/en-us/vba/excel-vba/articles/animate-a-sparkline
(() => {
const wks = app.ActiveSheet as Excel.Worksheet;
const oSparkGroup = wks.Cells.SparklineGroups.Item(1);
// Set the data source to the first year of data
oSparkGroup.ModifySourceData('B2:M4');
// Loop through the data points for the subsequent two years
for (let i = 1; i <= 24; i++) {
// Move the reference for the sparkline group over one cell
oSparkGroup.ModifySourceData(wks.Range(oSparkGroup.SourceData).Offset(0, 1).Address());
WScript.Sleep(1000);
}
})();
+9550
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -0,0 +1,6 @@
{
"private": true,
"dependencies": {
"activex-helpers": "*"
}
}
+25
View File
@@ -0,0 +1,25 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es5",
"scripthost"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
"activex-excel-tests.ts"
]
}
+6
View File
@@ -0,0 +1,6 @@
{
"extends": "dtslint/dt.json",
"rules": {
"no-const-enum": false
}
}
@@ -0,0 +1,730 @@
/// <reference types="activex-iwshruntimelibrary" />
const collectionToArray = <T>(col: { Item(index: any): T } | SafeArray<T>) => {
const results: T[] = [];
const enumerator = new Enumerator<T>(col);
enumerator.moveFirst();
while (!enumerator.atEnd()) {
results.push(enumerator.item());
enumerator.moveNext();
}
return results;
};
const toSafeArray = <T>(...items: T[]): SafeArray<T> => {
const dict = new ActiveXObject('Scripting.Dictionary');
items.forEach((x, index) => dict.Add(index, x));
return dict.Items() as SafeArray<T>;
};
const VB = {
InputBox: (prompt: string): string => ''
};
const getServer = () => {
const server = new ActiveXObject('FaxComEx.FaxServer');
server.Connect('');
return server;
};
(() => {
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693376(v=vs.85).aspx
const server = new ActiveXObject('FaxComEx.FaxServer');
const document = new ActiveXObject('FaxComEx.FaxDocument');
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms692919(v=vs.85).aspx
server.Connect('');
server.Connect('computername');
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693502(v=vs.85).aspx
(() => {
const getInitializedDevice = () => {
const ret = getServer().GetDevices().ItemById(1);
ret.ReceiveMode = FAXCOMEXLib.FAX_DEVICE_RECEIVE_MODE_ENUM.fdrmAUTO_ANSWER;
ret.RingsBeforeAnswer = 5;
ret.SendEnabled = true;
return ret;
};
// saving configuration
let device = getInitializedDevice();
device.Save();
// abandoning changes to configuration, using the Refresh method
device = getInitializedDevice();
device.Refresh();
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693502(v=vs.85).aspx
(() => {
const incomingJob = getServer().Folders.IncomingQueue.GetJobs().Item(1);
incomingJob.Refresh();
const currentPage = incomingJob.CurrentPage;
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms692922(v=vs.85).aspx
(() => {
const server = getServer();
WScript.Echo(`Server information:
API Version: ${server.APIVersion}
Debug: ${server.Debug}
Build and version: ${server.MajorBuild}.${server.MinorBuild}.${server.MajorVersion}.${server.MinorVersion}
Server name: ${server.ServerName}`);
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693455(v=vs.85).aspx
(() => {
const activity = getServer().Activity;
activity.Refresh();
WScript.Echo(`
${activity.IncomingMessages} incoming messages
${activity.OutgoingMessages} outgoing messages
${activity.RoutingMessages} routing messages
${activity.QueuedMessages} queued messages`);
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693400(v=vs.85).aspx
(() => {
const device = getServer().GetDevices().Item(1);
device.CSID = 'Accounts payable';
device.Description = 'Primary fax device';
device.ReceiveMode = FAXCOMEXLib.FAX_DEVICE_RECEIVE_MODE_ENUM.fdrmAUTO_ANSWER;
device.RingsBeforeAnswer = 5;
device.SendEnabled = true;
device.TSID = 'Accounts payable';
device.Save();
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms692985(v=vs.85).aspx
(() => {
const devices = getServer().GetDevices();
WScript.Echo(`This server has ${devices.Count} fax devices`);
for (let i = 1; i <= devices.Count; i++) {
WScript.Echo(`Device ID for device number ${i} is ${devices.Item(i).Id}`);
}
collectionToArray(devices).forEach(device => {
device.Refresh();
WScript.Echo(`
Device name: ${device.DeviceName}
Provider unique name: ${device.ProviderUniqueName}
Powered off: ${device.PoweredOff}
Receiving now: ${device.ReceivingNow}
Ringing now: ${device.RingingNow}
Sending now: ${device.SendingNow}`);
const routingMethods = new VBArray(device.UsedRoutingMethods).toArray();
routingMethods.forEach((guid, index) => {
WScript.Echo(`Method number ${index} = ${guid}`);
});
device.UseRoutingMethod(routingMethods[0], false);
device.Save();
});
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693486(v=vs.85).aspx
(() => {
const outputRuleInfo = (rule: FAXCOMEXLib.FaxOutboundRoutingRule, index?: number) => {
WScript.Echo(`
Outbound routing rule number: ${index || 'unknown'}
Area code: ${rule.AreaCode}
Country/region code: ${rule.CountryCode}
Device ID: ${rule.DeviceId}
Group name: ${rule.GroupName}
Status: ${rule.Status}
Is device used: ${rule.UseDevice}`
.trim());
};
const server = getServer();
const device = server.GetDevices().Item(1);
const id = device.Id;
const rules = server.OutboundRouting.GetRules();
const outboundRoutingRules = server.OutboundRouting.GetRules();
WScript.Echo(`There are ${outboundRoutingRules.Count} outbound routing rules on this server.`);
collectionToArray(outboundRoutingRules).forEach((rule, index) => {
rule.Refresh();
outputRuleInfo(rule, index);
if (!rule.UseDevice) { return; }
if (VB.InputBox('Do you want to change the device for this rule (Y/N)?') === 'Y') {
const newDeviceID = parseInt(VB.InputBox('Enter new device ID'), 10);
rule.DeviceId = newDeviceID;
rule.Save();
}
});
const msg = `
Do you want to:
1) display an item based on its country/region and area code,
2) remove an item based on its country/region and area code,
3) remove an item based on its item number, or
4) add a rule?
Input 1, 2, 3, 4, or 0 to exit
`.trim();
const result = parseInt(VB.InputBox(msg), 10);
let countryCode: number;
let areaCode: number;
let itemNumber: number;
let rule: FAXCOMEXLib.FaxOutboundRoutingRule;
switch (result) {
case 1:
countryCode = parseInt(VB.InputBox('Enter the country/region code'), 10);
areaCode = parseInt(VB.InputBox('Enter the area code'), 10);
rule = outboundRoutingRules.ItemByCountryAndArea(countryCode, areaCode);
outputRuleInfo(rule);
break;
case 2:
countryCode = parseInt(VB.InputBox('Enter the country/region code'), 10);
areaCode = parseInt(VB.InputBox('Enter the area code'), 10);
outboundRoutingRules.RemoveByCountryAndArea(countryCode, areaCode);
break;
case 3:
itemNumber = parseInt(VB.InputBox('Enter the item number'), 10);
outboundRoutingRules.Remove(itemNumber);
break;
case 4:
countryCode = parseInt(VB.InputBox('Enter the country/region code'), 10);
areaCode = parseInt(VB.InputBox('Enter the area code'), 10);
rule = outboundRoutingRules.Add(countryCode, areaCode, true, '', id);
break;
default:
return;
}
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693408(v=vs.85).aspx
(() => {
const server = getServer();
const outboundRouting = server.OutboundRouting;
const outboundRoutingGroups = outboundRouting.GetGroups();
const groupName = VB.InputBox('Provide a name for the outbound routing group');
const outboundRoutingGroup = outboundRoutingGroups.Add(groupName);
const devices = collectionToArray(server.GetDevices());
// add the devices to the routing group
devices.forEach(device => outboundRoutingGroup.DeviceIds.Add(device.Id));
// move the last device to the top of the order
outboundRoutingGroup.DeviceIds.SetOrder(devices[devices.length - 1].Id, 1);
// display the number of devices, and the device ID of the first device,to confirm its location in the order
const msg = `
Number of devices: ${outboundRoutingGroup.DeviceIds.Count}
ID of first device: ${outboundRoutingGroup.DeviceIds.Item(1)}
`.trim();
WScript.Echo(msg);
// remove the first device
outboundRoutingGroup.DeviceIds.Remove(1);
WScript.Echo(`There are now ${outboundRoutingGroups.Count} routing groups on the server`);
collectionToArray(outboundRoutingGroups).forEach((routingGroup, index) => {
const msg = `
Routing group number: ${index}
Outbound routing group name: ${routingGroup.Name}
Device status: ${routingGroup.Status}
`.trim();
});
// allow user to remove a routing group
if (VB.InputBox('Do you want to remove a routing group (Y/N)?') === 'N') { return; }
const itemNumber = VB.InputBox('Enter the item number for the group you want to remove');
outboundRoutingGroups.Remove(itemNumber);
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa964960(v=vs.85).aspx
(() => {
const accountSet = getServer().FaxAccountSet;
const accounts = collectionToArray(accountSet.GetAccounts());
WScript.Echo(`Number of accounts: ${accounts.length}`);
accounts.forEach(account => WScript.Echo(account.AccountName));
const accountName = VB.InputBox('Enter an account name');
accountSet.AddAccount(accountName);
accountSet.RemoveAccount(accountName);
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms692952(v=vs.85).aspx
(() => {
const incomingJobs = collectionToArray(getServer().Folders.IncomingQueue.GetJobs());
WScript.Echo(`There are ${incomingJobs.length} jobs in the incoming queue.`);
const n = parseInt(VB.InputBox('Input the number of a job for which you want information'), 10);
const job = incomingJobs[n - 1];
WScript.Echo(`
Available operations: ${job.AvailableOperations}
Caller ID: ${job.CallerId}
CSID: ${job.CSID}
Current page: ${job.CurrentPage}
Device ID: ${job.DeviceId}
Extended status: ${job.ExtendedStatus}
Extended status code: ${job.ExtendedStatusCode}
Job ID: ${job.Id}
Job type: ${job.JobType}
Retries: ${job.Retries}
Routing information: ${job.RoutingInformation}
Size: ${job.Size}
Status: ${job.Status}
Transmission start: ${new Date(job.TransmissionStart)}
Transmission end: ${new Date(job.TransmissionEnd)}
TSID: ${job.TSID}
`.trim());
if (VB.InputBox('Cancel this fax (Y/N)?') === 'Y') {
job.Cancel();
}
if (VB.InputBox('Open this fax (Y/N)?') === 'Y') {
const fileName = VB.InputBox('Enter path to save');
job.CopyTiff(fileName);
new ActiveXObject('WScript.Shell').Run(fileName);
}
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms692914(v=vs.85).aspx
(() => {
const server = new ActiveXObject('FaxComEx.FaxServer');
server.Connect('');
const outgoingQueue = server.Folders.OutgoingQueue;
outgoingQueue.AgeLimit = 2;
outgoingQueue.AllowPersonalCoverPages = true;
outgoingQueue.Blocked = false;
outgoingQueue.Paused = false;
outgoingQueue.Branding = true;
outgoingQueue.DiscountRateStart = new Date(0, 0, 0, 0).getVarDate();
outgoingQueue.DiscountRateStart = new Date(0, 0, 0, 1).getVarDate();
outgoingQueue.UseDeviceTSID = true;
outgoingQueue.Save();
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693393(v=vs.85).aspx
(() => {
const outgoingQueue = getServer().Folders.OutgoingQueue;
outgoingQueue.Refresh();
WScript.Echo(`There are ${outgoingQueue.GetJobs().Count} faxes in the outgoing queue`);
const inputResult = VB.InputBox('Which fax should be displayed (item number or job name)?');
const itemNumber = parseInt(inputResult, 10);
const job =
isNaN(itemNumber) ?
outgoingQueue.GetJob(inputResult) :
outgoingQueue.GetJobs().Item(itemNumber);
WScript.Echo(`
Available operations: ${job.AvailableOperations}
Broadcast receipts grouped? ${job.GroupBroadcastReceipts}
CSID: ${job.CSID}
Current page: ${job.CurrentPage}
Device ID: ${job.DeviceId}
Document name: ${job.DocumentName}
Extended status: ${job.ExtendedStatus}
Extended status code: ${job.ExtendedStatusCode}
Job ID: ${job.Id}
Original scheduled time: ${new Date(job.OriginalScheduledTime)}
Pages: ${job.Pages}
Priority: ${job.Priority}
Receipt type: ${job.ReceiptType}
`.trim());
const fileName = VB.InputBox('Enter path to save');
job.CopyTiff(fileName);
new ActiveXObject('WScript.Shell').Run(fileName);
const answer = VB.InputBox(`
Do you want to:
(C) cancel
(P) pause
(R) restart
(E) resume
the job?
`.trim());
switch (answer) {
case 'C':
job.Cancel();
break;
case 'P':
job.Pause();
break;
case 'R':
job.Restart();
break;
case 'E':
job.Resume();
break;
}
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms692936(v=vs.85).aspx
(() => {
const document = new ActiveXObject('FaxComEx.FaxDocument');
document.Body = 'C:\\docs\\body.txt';
document.DocumentName = 'My First Fax';
document.Priority = FAXCOMEXLib.FAX_PRIORITY_TYPE_ENUM.fptHIGH;
document.Recipients.Add('12225550100', 'Bud');
document.AttachFaxToReceipt = true;
document.CoverPageType = FAXCOMEXLib.FAX_COVERPAGE_TYPE_ENUM.fcptSERVER;
document.Note = 'Here is the info you requested';
document.ReceiptAddress = 'someone@example.com';
document.ReceiptType = FAXCOMEXLib.FAX_RECEIPT_TYPE_ENUM.frtMAIL;
document.ScheduleType = FAXCOMEXLib.FAX_SCHEDULE_TYPE_ENUM.fstSPECIFIC_TIME;
document.ScheduleTime = new Date(0, 0, 0, 16, 35, 47).getVarDate();
document.Subject = 'Today\'s fax';
// set sender properties
const sender = document.Sender;
sender.Title = 'Mr.';
sender.Name = 'Bob';
sender.City = 'Cleveland Heights';
sender.State = 'Ohio';
sender.Company = 'Microsoft';
sender.Country = 'USA';
sender.Email = 'someone@microsoft.com';
sender.FaxNumber = '12165555554';
sender.HomePhone = '12165555555';
sender.OfficeLocation = 'Downtown';
sender.OfficePhone = '12165555553';
sender.StreetAddress = '123 Main Street';
sender.TSID = 'Office fax machine';
sender.ZipCode = '44118';
sender.BillingCode = '23A54';
sender.Department = 'Accts Payable';
sender.SaveDefaultSender();
const server = getServer();
const jobID = document.ConnectedSubmit(server);
WScript.Echo(`The job ID is ${jobID}`);
server.Disconnect();
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693479(v=vs.85).aspx
(() => {
const document = new ActiveXObject('FaxComEx.FaxDocument');
document.Body = 'C:\\docs\\body.txt';
document.DocumentName = 'My First Fax';
const recipients = document.Recipients;
recipients.Add('12225550105', 'H');
recipients.Add('12225550104', 'N');
recipients.Add('12225550103', 'G');
WScript.Echo(`Number of recipients: ${recipients.Count}`);
collectionToArray(recipients).forEach((recipient, index) =>
WScript.Echo(`Recipient number ${index}: ${recipient.Name}, ${recipient.FaxNumber}`)
);
document.Sender.LoadDefaultSender();
document.GroupBroadcastReceipts = true;
const jobIDs = document.Submit('');
collectionToArray(jobIDs).forEach(jobID => WScript.Echo(`The job ID is ${jobID}`));
while (recipients.Count > 0) {
recipients.Remove(1);
}
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa964962(v=vs.85).aspx
(() => {
const server = getServer();
const prefetchCount = parseInt(VB.InputBox('How many messages should be prefetched?'), 10);
server.CurrentAccount.Folders.IncomingArchive.Refresh();
const messageIterator = server.Folders.IncomingArchive.GetMessages(prefetchCount);
messageIterator.MoveFirst();
for (let i = 1; i <= prefetchCount; i++) {
if (i > 1 && VB.InputBox('View next message? (Y/N)') !== 'Y') { break; }
const message = messageIterator.Message as FAXCOMEXLib.FaxIncomingMessage;
if (messageIterator.AtEOF) {
WScript.Echo(`End of file reached`);
return;
}
if (!message.WasReAssigned) {
if (VB.InputBox('Message not reassigned. Reassign (Y/N)?') === 'Y') {
message.Subject = 'Reassigning message';
message.SenderName = 'Test user';
message.Recipients = VB.InputBox('Enter username, e.g. Domain\\UserName');
message.SenderFaxNumber = '1234';
message.ReAssign();
}
}
messageIterator.MoveNext();
}
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693402(v=vs.85).aspx
(() => {
const server = getServer();
const prefetchCount = parseInt(VB.InputBox('How many messages should be prefetched?'), 10);
server.Folders.OutgoingArchive.Refresh();
const messageIterator = server.Folders.OutgoingArchive.GetMessages(prefetchCount);
messageIterator.MoveFirst();
for (let i = 1; i <= prefetchCount; i++) {
if (i > 1 && VB.InputBox('View next message? (Y/N)') !== 'Y') { break; }
if (messageIterator.AtEOF) {
WScript.Echo(`End of file reached`);
return;
}
const message = messageIterator.Message as FAXCOMEXLib.FaxOutgoingMessage;
const fileName = VB.InputBox('Enter path to save');
message.CopyTiff(fileName);
new ActiveXObject('WScript.Shell').Run(fileName);
WScript.Echo(`Message information:
CSID: ${message.CSID}
Device name: ${message.DeviceName}
Document name: ${message.DocumentName}
Message ID: ${message.Id}
Original scheduled time: ${new Date(message.OriginalScheduledTime)}
Pages: ${message.Pages}
Recipient fax number: ${message.Recipient.FaxNumber}
Retries: ${message.Retries}
Sender name: ${message.Sender.Name}
Size: ${message.Size}
Subject: ${message.Subject}
Submission ID: ${message.SubmissionId}
Submission time: ${new Date(message.SubmissionTime)}
Transmission end time: ${new Date(message.TransmissionEnd)}
Transmission start time: ${new Date(message.TransmissionStart)}
TSID: ${message.TSID}`);
if (VB.InputBox('Delete this fax from the archive (Y/N)?') === 'Y') {
message.Delete();
}
}
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693472(v=vs.85).aspx
(() => {
const server = getServer();
const outgoingArchive = server.Folders.OutgoingArchive;
WScript.Echo(`
Age limit: ${outgoingArchive.AgeLimit}
Archive folder: ${outgoingArchive.ArchiveFolder}
High quota mark: ${outgoingArchive.HighQuotaWaterMark}
Low quota water mark: ${outgoingArchive.LowQuotaWaterMark}
Size high: ${outgoingArchive.SizeHigh}
Size low: ${outgoingArchive.SizeLow}
Size quota warning: ${outgoingArchive.SizeQuotaWarning}
Is archive used? ${outgoingArchive.UseArchive}`.trim()
);
const newLimit = VB.InputBox('Set new age limit (enter empty value or Cancel to leave unchanged');
if (newLimit) {
outgoingArchive.AgeLimit = parseInt(newLimit, 10);
}
const messageID = VB.InputBox('Retrieve a message by ID (enter an empty value or press Cancel to exit');
if (messageID) {
const fileName = VB.InputBox('Enter path to save');
outgoingArchive.GetMessage(messageID).CopyTiff(fileName);
new ActiveXObject('WScript.Shell').Run(fileName);
}
})();
(() => {
const server = getServer();
const messageIterator = server.Folders.OutgoingArchive.GetMessages();
if (messageIterator.AtEOF) { return; }
messageIterator.MoveFirst();
while (!messageIterator.AtEOF) {
const message = messageIterator.Message;
WScript.Echo(`
Document name: ${message.DocumentName}
ID: ${message.Id}
Transmission end: ${new Date(message.TransmissionEnd)}
Transmission start: ${new Date(message.TransmissionStart)}
`.trim());
messageIterator.MoveNext();
}
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms692976(v=vs.85).aspx
(() => {
const server = getServer();
const prefetchCount = parseInt(VB.InputBox('How many messages should be prefetched?'), 10);
server.Folders.IncomingArchive.Refresh();
const messageIterator = server.Folders.IncomingArchive.GetMessages(prefetchCount);
messageIterator.MoveFirst();
for (let i = 1; i <= prefetchCount; i++) {
if (i > 1 && VB.InputBox('View next message? (Y/N)') !== 'Y') { break; }
const message = messageIterator.Message as FAXCOMEXLib.FaxIncomingMessage;
if (messageIterator.AtEOF) {
WScript.Echo(`End of file reached`);
return;
}
const fileName = VB.InputBox('Enter path to save TIFF file');
message.CopyTiff(fileName);
new ActiveXObject('WScript.Shell').Run(fileName);
messageIterator.MoveNext();
}
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693406(v=vs.85).aspx
(() => {
const server = getServer();
const incomingArchive = server.Folders.IncomingArchive;
incomingArchive.Refresh();
WScript.Echo(`
High quota water mark: ${incomingArchive.HighQuotaWaterMark}
Low quota water mark: ${incomingArchive.LowQuotaWaterMark}
Archive folder: ${incomingArchive.ArchiveFolder}
Age limit: ${incomingArchive.AgeLimit}
Size high: ${incomingArchive.SizeHigh}
Size low: ${incomingArchive.SizeLow}
Is size quota warning on? ${incomingArchive.SizeQuotaWarning}
Is archive used? ${incomingArchive.UseArchive}
`.trim());
incomingArchive.AgeLimit = 4;
incomingArchive.Save();
const messageID = VB.InputBox('Message ID to retrieve information? (Leave empty, or Cancel, to exit)');
if (messageID === '') { return; }
const message = incomingArchive.GetMessage(messageID);
WScript.Echo(`
Caller ID: ${message.CallerId}
CSID: ${message.CSID}
Device name: ${message.DeviceName}
Message ID: ${message.Id}
Number of pages: ${message.Pages}
Retries: ${message.Retries}
Routing information: ${message.RoutingInformation}
Size: ${message.Size}
Transmission start: ${new Date(message.TransmissionStart)}
Transmission end: ${new Date(message.TransmissionEnd)}
TSID: ${message.TSID}
`.trim());
if (VB.InputBox('Delete this message from the archive (Y/N)?') === 'Y') {
message.Delete();
}
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693401(v=vs.85).aspx
(() => {
const server = getServer();
const loggingOptions = server.LoggingOptions;
const activityLogging = loggingOptions.ActivityLogging;
const eventLogging = loggingOptions.EventLogging;
activityLogging.Refresh();
activityLogging.LogIncoming = true;
activityLogging.LogOutgoing = true;
activityLogging.Save();
eventLogging.Refresh();
eventLogging.GeneralEventsLevel = FAXCOMEXLib.FAX_LOG_LEVEL_ENUM.fllMED;
eventLogging.InboundEventsLevel = FAXCOMEXLib.FAX_LOG_LEVEL_ENUM.fllMAX;
eventLogging.InitEventsLevel = FAXCOMEXLib.FAX_LOG_LEVEL_ENUM.fllMAX;
eventLogging.OutboundEventsLevel = FAXCOMEXLib.FAX_LOG_LEVEL_ENUM.fllNONE;
eventLogging.Save();
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693387(v=vs.85).aspx
(() => {
const server = getServer();
const receiptOptions = server.ReceiptOptions;
receiptOptions.Refresh();
WScript.Echo(`
Allowed receipt types: ${receiptOptions.AllowedReceipts}
Authentication types: ${receiptOptions.AuthenticationType}
SMTP port: ${receiptOptions.SMTPPort}
SMTP sender: ${receiptOptions.SMTPSender}
SMTP server: ${receiptOptions.SMTPSender}
Use for inbound routing? ${receiptOptions.UseForInboundRouting}
`.trim());
receiptOptions.AllowedReceipts = FAXCOMEXLib.FAX_RECEIPT_TYPE_ENUM.frtMAIL;
receiptOptions.AuthenticationType = FAXCOMEXLib.FAX_SMTP_AUTHENTICATION_TYPE_ENUM.fsatBASIC;
receiptOptions.SMTPPort = 25;
receiptOptions.SMTPSender = 'someone@example.com';
receiptOptions.SMTPServer = 'My SMTP Server';
receiptOptions.UseForInboundRouting = true;
receiptOptions.Save();
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693462(v=vs.85).aspx
(() => {
const server = getServer();
collectionToArray(server.GetDeviceProviders()).forEach((provider, index) => {
WScript.Echo(`
Debug: ${provider.Debug}
Name: ${provider.FriendlyName}
Image name: ${provider.ImageName}
Init error code: ${provider.InitErrorCode}
Build and version: ${provider.MajorBuild}.${provider.MajorVersion}.${provider.MinorBuild}.${provider.MinorVersion}
Status: ${provider.Status}
TAPI provider: ${provider.TapiProviderName}
Unique name: ${provider.UniqueName}
`.trim());
new VBArray(provider.DeviceIds).toArray().forEach(id => WScript.Echo(id));
});
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693437(v=vs.85).aspx -- for a fax device
(() => {
const server = getServer();
const device = server.GetDevices().Item(1);
const deviceProperty = toSafeArray(1, 2, 3);
const propertyName = '{B1F944B9-9A16-45d1-933A-4060A4871AB0}';
device.SetExtensionProperty(propertyName, deviceProperty);
new VBArray(device.GetExtensionProperty(propertyName)).toArray().forEach(x => WScript.Echo(x));
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693437(v=vs.85).aspx -- for a fax device
(() => {
const server = getServer();
const serverProperty = toSafeArray(4, 2, 3);
const propertyName = `{AC7D0DEE-B6E5-4a44-AF45-835C58CB44D2}`;
server.SetExtensionProperty(propertyName, serverProperty);
new VBArray(server.GetExtensionProperty(propertyName)).toArray().forEach(x => WScript.Echo(x));
})();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms693013(v=vs.85).aspx
(() => {
const server = getServer();
ActiveXObject.on(server, 'OnOutgoingJobAdded', ['pFaxServer', 'bstrJobId'], prm => WScript.Echo('New job added to queue'));
ActiveXObject.on(server, 'OnOutgoingJobChanged', ['pFaxServer', 'bstrJobId', 'pJobStatus'], prm => {
const status = prm.pJobStatus;
WScript.Echo(`
Available operations: ${status.AvailableOperations}
Caller ID: ${status.CallerId}
CSID: ${status.CSID}
Current page: ${status.CurrentPage}
Device ID: ${status.DeviceId}
Extended status: ${status.ExtendedStatus}
Extended status code: ${status.ExtendedStatusCode}
Job type: ${status.JobType}
Pages: ${status.Pages}
Retries: ${status.Retries}
Routing information: ${status.RoutingInformation}
Scheduled time: ${new Date(status.ScheduledTime)}
Size: ${status.Size}
Status: ${status.Status}
Transmission start: ${new Date(status.TransmissionStart)}
TSID: ${status.TSID}
`.trim());
try {
WScript.Echo(`Transmission end: ${new Date(status.TransmissionEnd)}`);
} catch {}
});
ActiveXObject.on(server, 'OnServerShutDown', ['pFaxServer'], prm => WScript.Echo('The local fax server has been shut down'));
server.ListenToServerEvents(
FAXCOMEXLib.FAX_SERVER_EVENTS_TYPE_ENUM.fsetFXSSVC_ENDED +
FAXCOMEXLib.FAX_SERVER_EVENTS_TYPE_ENUM.fsetOUT_QUEUE
);
})();
File diff suppressed because it is too large Load Diff
+6
View File
@@ -0,0 +1,6 @@
{
"private": true,
"dependencies": {
"activex-helpers": "*"
}
}
+25
View File
@@ -0,0 +1,25 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es5",
"scripthost"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
"activex-faxcomexlib-tests.ts"
]
}
+3
View File
@@ -0,0 +1,3 @@
{
"extends": "dtslint/dt.json"
}
@@ -0,0 +1,5 @@
let obj0 = new ActiveXObject('InfoPath.Application');
let obj1 = new ActiveXObject('InfoPath.ExternalApplication');
let obj2 = new ActiveXObject('InfoPath.Editor');
+1198
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -0,0 +1,6 @@
{
"private": true,
"dependencies": {
"activex-helpers": "*"
}
}
+25
View File
@@ -0,0 +1,25 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es5",
"scripthost"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
"activex-infopath-tests.ts"
]
}
+6
View File
@@ -0,0 +1,6 @@
{
"extends": "dtslint/dt.json",
"rules": {
"no-const-enum": false
}
}
@@ -0,0 +1,49 @@
const wshn = new ActiveXObject('WScript.Network');
// https://msdn.microsoft.com/en-us/library/s6wt333f(v=vs.84).aspx
// https://msdn.microsoft.com/en-us/library/wck0hkd7(v=vs.84).aspx
// https://msdn.microsoft.com/en-us/library/tte130y1(v=vs.84).aspx
// https://msdn.microsoft.com/en-us/library/3fxhka75(v=vs.84).aspx
(() => {
WScript.Echo('Domain = ' + wshn.UserDomain);
WScript.Echo('Computer Name = ' + wshn.ComputerName);
WScript.Echo('User Name = ' + wshn.UserName);
})();
// https://msdn.microsoft.com/en-us/library/zsdh7hkb(v=vs.84).aspx
wshn.AddWindowsPrinterConnection('\\\\printserv\\DefaultPrinter');
// https://msdn.microsoft.com/en-us/library/kxsdca3c(v=vs.84).aspx
wshn.AddPrinterConnection("LPT1", "\\\\Server\\Print1");
// https://msdn.microsoft.com/en-us/library/t9zt39at(v=vs.84).aspx
// https://msdn.microsoft.com/en-us/library/zhds6k80(v=vs.84).aspx
(() => {
const drives = wshn.EnumNetworkDrives();
const printers = wshn.EnumPrinterConnections();
WScript.Echo("Network drive mappings:");
for (let i = 0; i < drives.length; i += 2) {
WScript.Echo(`Drive ${drives.Item(i)} = ${drives.Item(i + 1)}`);
}
WScript.Echo('');
WScript.Echo("Network printer mappings:");
for (let i = 0; i < printers.length; i += 2) {
WScript.Echo(`Port ${printers.Item(i)} = ${printers.Item(i + 1)}`);
}
})();
// https://msdn.microsoft.com/en-us/library/8kst88h6(v=vs.84).aspx
wshn.MapNetworkDrive('E:', '\\\\Server\\Public');
// https://msdn.microsoft.com/en-us/library/d16d7wbf(v=vs.84).aspx
wshn.RemoveNetworkDrive('E:');
// https://msdn.microsoft.com/en-us/library/tsbh2yy7(v=vs.84).aspx
wshn.RemovePrinterConnection('\\\\PRN-CORP1\\B41-4523-A', true, true);
// https://msdn.microsoft.com/en-us/library/2ccwwdct(v=vs.84).aspx
(() => {
const printerPath = "\\\\research\\library1";
wshn.AddWindowsPrinterConnection(printerPath);
wshn.SetDefaultPrinter(printerPath);
})();
+247
View File
@@ -0,0 +1,247 @@
// Type definitions for Windows Script Host Object Model - IWshRuntimeLibrary 1.0
// Project: https://msdn.microsoft.com/en-us/library/9bbdkx3k(v=vs.84).aspx
// Definitions by: Zev Spitz <https://github.com/zspitz>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.6
declare namespace IWshRuntimeLibrary {
// tslint:disable-next-line no-const-enum
const enum ButtonType {
OK,
OKCancel,
AbortRetryIgnore,
YesNoCancel,
YesNo,
RetryCancel,
CancelTryagainContinue
}
// tslint:disable-next-line no-const-enum
const enum IconType {
Stop = 16,
QuestionMark = 32,
ExclamationMakr = 48,
InformationMark = 64,
}
// tslint:disable-next-line no-const-enum
const enum PopupType {
SecondButtonDefault = 256,
ThirdButtonDefault = 512,
Modal = 4096,
RightJustified = 524288,
RTL = 1048576,
}
// tslint:disable-next-line no-const-enum
const enum PopupSelection {
NoButton = -1,
OK = 1,
Cancel = 2,
Abort = 3,
Retry = 4,
Ignore = 5,
Yes = 6,
No = 7,
TryAgain = 10,
Continue = 11,
}
// tslint:disable-next-line no-const-enum
const enum WshExecStatus {
WshFailed = 2,
WshFinished = 1,
WshRunning = 0,
}
// tslint:disable-next-line no-const-enum
const enum WshWindowStyle {
WshHide = 0,
WshMaximizedFocus = 3,
WshMinimizedFocus = 2,
WshMinimizedNoFocus = 6,
WshNormalFocus = 1,
WshNormalNoFocus = 4,
}
class TextStream {
private 'IWshRuntimeLibrary.TextStream_typekey': TextStream;
private constructor();
readonly AtEndOfLine: boolean;
readonly AtEndOfStream: boolean;
Close(): void;
readonly Column: number;
readonly Line: number;
Read(Characters: number): string;
ReadAll(): string;
ReadLine(): string;
Skip(Characters: number): void;
SkipLine(): void;
Write(Text: string): void;
WriteBlankLines(Lines: number): void;
/** @param string [Text=''] */
WriteLine(Text?: string): void;
}
/** Generic Collection Object */
class WshCollection {
private 'IWshRuntimeLibrary.WshCollection_typekey': WshCollection;
private constructor();
Count(): number;
Item(Index: any): any;
readonly length: number;
}
/** Environment Variables Collection Object */
class WshEnvironment {
private 'IWshRuntimeLibrary.WshEnvironment_typekey': WshEnvironment;
private constructor();
Count(): number;
Item(Name: string): string;
readonly length: number;
Remove(Name: string): void;
}
/** WSHExec object */
class WshExec {
private 'IWshRuntimeLibrary.WshExec_typekey': WshExec;
private constructor();
readonly ExitCode: number;
readonly ProcessID: number;
readonly Status: WshExecStatus;
readonly StdErr: TextStream;
readonly StdIn: TextStream;
readonly StdOut: TextStream;
Terminate(): void;
}
/** Network Object */
class WshNetwork {
private 'IWshRuntimeLibrary.WshNetwork_typekey': WshNetwork;
private constructor();
/**
* Adds a remote MS-DOS-based printer connection to your computer system.
* @param LocalName Local name to assign to the connected printer.
* @param RemoteName Name of the remote printer.
* @param UpdateProfile [false] Whether the printer mapping is stored in the current user's profile.
*
* If you are mapping a remote printer using the profile of someone other than current user, you can specify _UserName_ and _Password_.
*/
AddPrinterConnection(LocalName: string, RemoteName: string, UpdateProfile?: boolean, UserName?: string, Password?: string): void;
/**
* @param string Path to printer connection
* @param string [DriverName='']
* @param string [Port='LPT1']
*
* Unlike the **AddPrinterConnection** method, this method allows you to create a printer connection without directing it to a specific port, such as LPT1.
*/
AddWindowsPrinterConnection(PrinterName: string, DriverName?: string, Port?: string): void;
readonly ComputerName: string;
EnumNetworkDrives(): WshCollection;
EnumPrinterConnections(): WshCollection;
/**
* Adds a remote MS-DOS-based printer connection to your computer system.
* @param LocalName Name by which the mapped drive will be known locally
* @param RemoteName Share's UNC name (\\xxx\yyy)
* @param UpdateProfile [false] Whether the printer mapping is stored in the current user's profile.
*
* If you are mapping a network drive using the profile of someone other than current user, you can specify _UserName_ and _Password_.
*/
MapNetworkDrive(LocalName: string, RemoteName: string, UpdateProfile?: boolean, UserName?: string, Password?: string): void;
readonly Organization: string;
/**
* Removes a shared network drive from your computer system
* @param Name Name of the mapped drive you want to remove. This will be the drive letter if the drive has a mapping between a local name (drive letter) and a remote name (UNC name);
* it will be the UNC path if there is no such mapping
* @param Force [false] Remove the connections even if the resource is in use
* @param UpdateProfile [false] Remove the mapping from the user's profile
*/
RemoveNetworkDrive(Name: string, Force?: any, UpdateProfile?: any): void;
/**
* Removes a shared network printer connection from your computer system
* @param Name Name that identifies the printer. Can be a UNC name (in the form `\\xxx\yyy`) or a local name (such as `LPT1`)
* @param Force [false] Remove printer connection even if a user is still connected
* @param UpdateProfile [false] Remove the printer connection from the user's profile
*
* The **RemovePrinterConnection** method removes both Windows and MS-DOS based printer connections. If the printer was connected using the method **AddPrinterConnection**,
* _Name_ must be the printer's local name. If the printer was connected using the **AddWindowsPrinterConnection** method or was added manually (using the Add Printer wizard),
* then _Name_ must be the printer's UNC name.
*/
RemovePrinterConnection(Name: string, Force?: any, UpdateProfile?: any): void;
SetDefaultPrinter(Name: string): void;
readonly Site: string;
readonly UserDomain: string;
readonly UserName: string;
readonly UserProfile: string;
}
/** Shell Object */
class WshShell {
private 'IWshRuntimeLibrary.WshShell_typekey': WshShell;
private constructor();
AppActivate(App: any, Wait?: any): boolean;
CreateShortcut(PathLink: string): any;
CurrentDirectory: string;
Environment(Type?: any): WshEnvironment;
Exec(Command: string): WshExec;
ExpandEnvironmentStrings(Src: string): string;
/** @param string [Target=''] */
LogEvent(Type: any, Message: string, Target?: string): boolean;
Popup(Text: any, SecondsToWait?: number, Title?: string, Type?: ButtonType | IconType | PopupType): PopupSelection;
RegDelete(Name: string): void;
RegRead(Name: string): any;
RegWrite(Name: string, Value: any, Type?: any): void;
Run(Command: string, WindowStyle?: any, WaitOnReturn?: any): number;
SendKeys(Keys: string, Wait?: any): void;
readonly SpecialFolders: WshCollection;
}
/** Shortcut Object */
class WshShortcut {
private 'IWshRuntimeLibrary.WshShortcut_typekey': WshShortcut;
private constructor();
Arguments: string;
Description: string;
readonly FullName: string;
Hotkey: string;
IconLocation: string;
Load(PathLink: string): void;
readonly RelativePath: string;
Save(): void;
TargetPath: string;
WindowStyle: number;
WorkingDirectory: string;
}
/** URLShortcut Object */
class WshURLShortcut {
private 'IWshRuntimeLibrary.WshURLShortcut_typekey': WshURLShortcut;
private constructor();
readonly FullName: string;
Load(PathLink: string): void;
Save(): void;
TargetPath: string;
}
}
interface ActiveXObject {
set(obj: IWshRuntimeLibrary.WshEnvironment, propertyName: 'Item', parameterTypes: [string], newValue: string): void;
new <K extends keyof ActiveXObjectNameMap = any>(progid: K): ActiveXObjectNameMap[K];
}
interface ActiveXObjectNameMap {
'WScript.Network': IWshRuntimeLibrary.WshNetwork;
'WScript.Shell': IWshRuntimeLibrary.WshShell;
}
interface EnumeratorConstructor {
new(col: IWshRuntimeLibrary.WshCollection): Enumerator;
new(col: IWshRuntimeLibrary.WshEnvironment): Enumerator<string>;
}

Some files were not shown because too many files have changed in this diff Show More