-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for Deno #13281
Comments
Deno is quite exciting! Anyone using Deno, please feel free to chime in with how you're using it and how you'd use the Azure SDKs with Deno. On our side we're planning on which new platforms to enable next. It seems likely React Native is winning this battle, but probably that effort will teach us many things that will help light up Deno support. If anyone has more concrete ideas for what it would take to light up Deno support (ideally by sharing as much of the existing package as possible), please let us know below. |
Is there already an example build process somewhere that can show us how to easily service the various target platforms?
I guess Nodejs is still the platform to run the build tooling on. Unfortunately it seems that the import semantics of Deno versus the rest is not compatible. Deno expects the ts file extension everywhere. I tried to convert @azure/ms-rest-js manually to Deno which takes a lot of time. |
@cveld we have a template package here that can be useful for testing on and we use rollup for bundling compiled js files for node and browser. The rollup configuration for the template package is here https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/template/template/rollup.config.js which mainly calls into the main configurations found here: https://github.com/Azure/azure-sdk-for-js/blob/master/common/tools/dev-tool/src/config/rollup.base.config.ts. |
+1 for Deno support. Not having the sdk for deno means I have to go with a nodejs base micro service to interact with Azure blob storage and the like? It's a bad feeling, being a paying azure customer, with multiple production apps on the platform, that I can't use the tools I want to interact with and tie into your services. This means I have find another service that has Deno support (like Mongodb and the like, instead of using Azure db), or I'm forced into a toolset I don't want to use. You guys should have the bandwidth to put a team on things like Deno, RN, etc, your backed by MS. Supporting your developers is what makes MS great. And having the hooks to tie into your service, especially something like Deno (that could replace Nodejs one day), is something that ties into your Cloud services bottom line (a differentiator of sorts). |
@cveld did you ever get anything converted over? It would take a small team to keep up with Azure changes I think. |
Fix typo (Azure#13281) Co-authored-by: Vikram Praveen Kumar <vipravee@microsoft.com>
Fix typo (Azure#13281) Co-authored-by: Vikram Praveen Kumar <vipravee@microsoft.com>
What is the status of Deno support, is it on the roadmap somewhere? |
@aadamsx So this exploration of mine was part of assessing the effort it would take to adopt Deno. I found it surprising that Deno currently does not seem to provide a good migration story coming from nodejs. To start with, TypeScript files are completely incompatible due to the way import statements are processed, i.e. Deno requires the ts extension everywhere whereas with Nodejs you need to leave it out. I guess you will need build automation tools to support both architectures. I started working on a sample conversion to only reach the next challenge: the JavaScript Azure SDK has taken dependencies on Nodejs libraries which need to be replaced by Deno equivalents. Is it even possible to set up shared TypeScript code for both domains? |
I’m just going to use MongoDB (or CouchDB or others) via a service or running on a container. Of course there are drivers for this in Deno. As for Azure cloud storage, I’ve resorted to using AWS S3 as again there are Deno drivers. In general I will have to move away from Azure, or at least not be as tightly coupled to it, in order to use my tool of choice, Deno. |
It would be great to use this with something like skypack. For an example, create a new file that looks like: import { CosmosClient } from 'https://cdn.skypack.dev/@azure/cosmos?dts';
console.log(CosmosClient); Running that yields 39 TS errors that all look like:
|
Having a bit of a poke around with the latest Deno (at time of writing), 1.11.0 and it get a bit further with skypack. Here's a sample bit of code: import { CosmosClient } from "https://cdn.skypack.dev/@azure/cosmos?dts";
export async function getData() {
const client = new CosmosClient({
endpoint: "<snip>",
key:
"<snip>",
});
console.log("Got client");
const db = client.database("trivia");
console.log("Got DB");
const container = db.container("game");
console.log("Got Container");
const { resources: items } = await container.items.query(
"SELECT * FROM c WHERE c.modelType = 'Question'",
).fetchAll();
return items;
} This will blow up with:
I'd say this is related to the partial implementation of Web Crypto in Deno (see denoland/deno#1891). I'll retest on Deno 1.12 when it comes out (tried a nightly but it was no better). |
You can always use REST API Reference for Azure Cosmos DB. Example: https://github.com/zoran-milosevic/deno-microservice |
It took about a day to figure out how to get azure blob storage working in Deno, so I should save other folks the effort. For auth, it only works with shared access tokens because they skip One of the key concepts is that you'll need to create a file which sets up all the globals before you import the current main file. Mine looks like this: // Fake DOM APIs which cover enough of the API usage by Azure's SDK
import { DOMParser, Document, Node } from "https://deno.land/x/deno_dom/deno-dom-wasm.ts";
window.document = new Document()
window.document.implementation.createDocument = () => {}
window.DOMParser = DOMParser
window.Node = Node
window.XMLSerializer = class {}
// A reimplementation of XMLHTTPRequest
import "https://deno.land/x/xhr@0.1.2/mod.ts";
// Expected by the user agent
window.navigator.oscpu = "deno"
// Start up the main import
const index = await import("./index.ts")
// For me, start up my app, as it has a watch mode - the async promise does not
// finish otherwise
index.app.listen({ port: 8080 }); This is enough so that later you add: import * as azure from "https://cdn.skypack.dev/@azure/storage-blob?dts";
import { azure } from "./deps.ts";
import { Env } from "./index.ts";
export const createAzureAPI = (env: Env) => {
const accountName = "my-account";
const blobServiceClient = new azure.BlobServiceClient(`https://${accountName}.blob.core.windows.net${env.azureSASToken}`);
return {
fileExists: (container: string, fileName: string) => {
const url = `https://${accountName}.blob.core.windows.net/${container}/${fileName}`;
return fetch(url, { method: "HEAD" }).then((r) => r.ok);
},
uploadFile: async (fileName: string, _content: Uint8Array) => {
const file = await Deno.readFile("./example-file.png");
const containerClient = blobServiceClient.getContainerClient("thumbs");
const blockBlobClient = containerClient.getBlockBlobClient(fileName);
await blockBlobClient.uploadData(file);
},
};
}; If a request fails, things will throw in unexpected places - but when it works, it works. Update months later, this API client replaces the whole dep
import { Env } from "./index.ts"
export const createAzureAPI = (env: Env) => {
const accountName = "puzmo"
return {
fileExists: (container: string, fileName: string) => {
const url = `https://${accountName}.blob.core.windows.net/${container}/${fileName}`
return fetch(url, { method: "HEAD" }).then((r) => r.ok)
},
uploadFile: (container: string, fileName: string, content: Uint8Array) => {
return fetch(`https://${accountName}.blob.core.windows.net/${container}/${fileName}${env.azureSASToken}`, {
credentials: "omit",
headers: {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0",
Accept: "*/*",
"Accept-Language": "en-US,en;q=0.5",
"x-ms-blob-content-type": "image/png",
"x-ms-blob-type": "BlockBlob",
"x-ms-command-name": "StorageClient.PutBlob",
},
body: content,
method: "PUT",
})
},
}
} |
It might be easier to refactor the JS libraries to build fist with Deno.. then it's easy enough to duplicate the source directory, replacing the Just a thought on this one. |
Deno support through NPM broke. When I try to use the {
"name": "RestError",
"code": "MissingRequiredHeader",
"statusCode": 400,
"request": {
"streamResponseStatusCodes": {},
"url": "REDACTED/documents?restype=REDACTED",
"method": "PUT",
"headers": {
"_headersMap": {
"x-ms-version": "REDACTED",
"accept": "application/xml",
"user-agent": "azsdk-js-storageblob/12.14.0 (NODE-VERSION v18.12.1; Linux 5.15.0-73-generic)",
"x-ms-client-request-id": "9883ead7-6384-4faa-bd8c-832e12cece06",
"x-ms-date": "REDACTED",
"authorization": "REDACTED"
}
},
"withCredentials": false,
"timeout": 0,
"keepAlive": true,
"decompressResponse": false,
"requestId": "9883ead7-6384-4faa-bd8c-832e12cece06"
},
"details": {
"errorCode": "MissingRequiredHeader",
"content-length": "301",
"content-type": "application/xml",
"date": "Wed, 07 Jun 2023 12:54:03 GMT",
"server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
"x-ms-client-request-id": "9883ead7-6384-4faa-bd8c-832e12cece06",
"x-ms-request-id": "40f896ca-401e-00a3-383f-9945d8000000",
"x-ms-version": "2022-11-02",
"message": "An HTTP header that's mandatory for this request is not specified.\nRequestId:40f896ca-401e-00a3-383f-9945d8000000\nTime:2023-06-07T12:54:03.9752068Z",
"code": "MissingRequiredHeader",
"HeaderName": "x-ms-blob-type"
},
"message": "An HTTP header that's mandatory for this request is not specified.\nRequestId:40f896ca-401e-00a3-383f-9945d8000000\nTime:2023-06-07T12:54:03.9752068Z"
} I've never incleded any |
@eikooc Looks like a regression in Deno v1.34.0? The package is working fine with v1.33.3 |
@jeremymeng I've just tried downgrading to I've made a really small reproducible example here: import * as AzureBlob from "npm:@azure/storage-blob@12.14.0";
const main = async () => {
const blobServiceClient = AzureBlob.BlobServiceClient.fromConnectionString(
"REDACTED",
);
const containerClient = blobServiceClient.getContainerClient(
"documents",
);
await containerClient.createIfNotExists();
const blobCursor = await containerClient.listBlobsByHierarchy("/", {
prefix: "foo",
});
const blobs: AzureBlob.BlobItem[] = [];
for await (const blob of blobCursor) {
blobs.push(blob as AzureBlob.BlobItem);
}
return blobs;
};
console.log(await main()); And for completeness here is my {
"version": "2",
"remote": {},
"npm": {
"specifiers": {
"@azure/storage-blob@12.14.0": "@azure/storage-blob@12.14.0"
},
"packages": {
"@azure/abort-controller@1.1.0": {
"integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==",
"dependencies": {
"tslib": "tslib@2.5.3"
}
},
"@azure/core-auth@1.4.0": {
"integrity": "sha512-HFrcTgmuSuukRf/EdPmqBrc5l6Q5Uu+2TbuhaKbgaCpP2TfAeiNaQPAadxO+CYBRHGUzIDteMAjFspFLDLnKVQ==",
"dependencies": {
"@azure/abort-controller": "@azure/abort-controller@1.1.0",
"tslib": "tslib@2.5.3"
}
},
"@azure/core-http@3.0.2": {
"integrity": "sha512-o1wR9JrmoM0xEAa0Ue7Sp8j+uJvmqYaGoHOCT5qaVYmvgmnZDC0OvQimPA/JR3u77Sz6D1y3Xmk1y69cDU9q9A==",
"dependencies": {
"@azure/abort-controller": "@azure/abort-controller@1.1.0",
"@azure/core-auth": "@azure/core-auth@1.4.0",
"@azure/core-tracing": "@azure/core-tracing@1.0.0-preview.13",
"@azure/core-util": "@azure/core-util@1.3.2",
"@azure/logger": "@azure/logger@1.0.4",
"@types/node-fetch": "@types/node-fetch@2.6.4",
"@types/tunnel": "@types/tunnel@0.0.3",
"form-data": "form-data@4.0.0",
"node-fetch": "node-fetch@2.6.11",
"process": "process@0.11.10",
"tslib": "tslib@2.5.3",
"tunnel": "tunnel@0.0.6",
"uuid": "uuid@8.3.2",
"xml2js": "xml2js@0.5.0"
}
},
"@azure/core-lro@2.5.3": {
"integrity": "sha512-ubkOf2YCnVtq7KqEJQqAI8dDD5rH1M6OP5kW0KO/JQyTaxLA0N0pjFWvvaysCj9eHMNBcuuoZXhhl0ypjod2DA==",
"dependencies": {
"@azure/abort-controller": "@azure/abort-controller@1.1.0",
"@azure/core-util": "@azure/core-util@1.3.2",
"@azure/logger": "@azure/logger@1.0.4",
"tslib": "tslib@2.5.3"
}
},
"@azure/core-paging@1.5.0": {
"integrity": "sha512-zqWdVIt+2Z+3wqxEOGzR5hXFZ8MGKK52x4vFLw8n58pR6ZfKRx3EXYTxTaYxYHc/PexPUTyimcTWFJbji9Z6Iw==",
"dependencies": {
"tslib": "tslib@2.5.3"
}
},
"@azure/core-tracing@1.0.0-preview.13": {
"integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==",
"dependencies": {
"@opentelemetry/api": "@opentelemetry/api@1.4.1",
"tslib": "tslib@2.5.3"
}
},
"@azure/core-util@1.3.2": {
"integrity": "sha512-2bECOUh88RvL1pMZTcc6OzfobBeWDBf5oBbhjIhT1MV9otMVWCzpOJkkiKtrnO88y5GGBelgY8At73KGAdbkeQ==",
"dependencies": {
"@azure/abort-controller": "@azure/abort-controller@1.1.0",
"tslib": "tslib@2.5.3"
}
},
"@azure/logger@1.0.4": {
"integrity": "sha512-ustrPY8MryhloQj7OWGe+HrYx+aoiOxzbXTtgblbV3xwCqpzUK36phH3XNHQKj3EPonyFUuDTfR3qFhTEAuZEg==",
"dependencies": {
"tslib": "tslib@2.5.3"
}
},
"@azure/storage-blob@12.14.0": {
"integrity": "sha512-g8GNUDpMisGXzBeD+sKphhH5yLwesB4JkHr1U6be/X3F+cAMcyGLPD1P89g2M7wbEtUJWoikry1rlr83nNRBzg==",
"dependencies": {
"@azure/abort-controller": "@azure/abort-controller@1.1.0",
"@azure/core-http": "@azure/core-http@3.0.2",
"@azure/core-lro": "@azure/core-lro@2.5.3",
"@azure/core-paging": "@azure/core-paging@1.5.0",
"@azure/core-tracing": "@azure/core-tracing@1.0.0-preview.13",
"@azure/logger": "@azure/logger@1.0.4",
"events": "events@3.3.0",
"tslib": "tslib@2.5.3"
}
},
"@opentelemetry/api@1.4.1": {
"integrity": "sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA==",
"dependencies": {}
},
"@types/node-fetch@2.6.4": {
"integrity": "sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==",
"dependencies": {
"@types/node": "@types/node@20.2.5",
"form-data": "form-data@3.0.1"
}
},
"@types/node@20.2.5": {
"integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==",
"dependencies": {}
},
"@types/tunnel@0.0.3": {
"integrity": "sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==",
"dependencies": {
"@types/node": "@types/node@20.2.5"
}
},
"asynckit@0.4.0": {
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"dependencies": {}
},
"combined-stream@1.0.8": {
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "delayed-stream@1.0.0"
}
},
"delayed-stream@1.0.0": {
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"dependencies": {}
},
"events@3.3.0": {
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
"dependencies": {}
},
"form-data@3.0.1": {
"integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
"dependencies": {
"asynckit": "asynckit@0.4.0",
"combined-stream": "combined-stream@1.0.8",
"mime-types": "mime-types@2.1.35"
}
},
"form-data@4.0.0": {
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "asynckit@0.4.0",
"combined-stream": "combined-stream@1.0.8",
"mime-types": "mime-types@2.1.35"
}
},
"mime-db@1.52.0": {
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dependencies": {}
},
"mime-types@2.1.35": {
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dependencies": {
"mime-db": "mime-db@1.52.0"
}
},
"node-fetch@2.6.11": {
"integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==",
"dependencies": {
"whatwg-url": "whatwg-url@5.0.0"
}
},
"process@0.11.10": {
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"dependencies": {}
},
"sax@1.2.4": {
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"dependencies": {}
},
"tr46@0.0.3": {
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"dependencies": {}
},
"tslib@2.5.3": {
"integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==",
"dependencies": {}
},
"tunnel@0.0.6": {
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
"dependencies": {}
},
"uuid@8.3.2": {
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"dependencies": {}
},
"webidl-conversions@3.0.1": {
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"dependencies": {}
},
"whatwg-url@5.0.0": {
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dependencies": {
"tr46": "tr46@0.0.3",
"webidl-conversions": "webidl-conversions@3.0.1"
}
},
"xml2js@0.5.0": {
"integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
"dependencies": {
"sax": "sax@1.2.4",
"xmlbuilder": "xmlbuilder@11.0.1"
}
},
"xmlbuilder@11.0.1": {
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
"dependencies": {}
}
}
}
} |
@eikooc I believe it's this issue denoland/deno#19413. Have you given the latest deno 1.34.2 a try? You could also use a proxy or fiddler to verify that the requests going out to the wire are correct. |
@jeremymeng I've tried that version as well. Does my above example work for you? |
@eikooc Thanks! I just tried the code snippet. It does give an error but after listing one blob, and the error looks a different one.
Since the code is working fine on NodeJS but not deno, I suggest opening an issue in the deno repo |
Support for Deno broke in the 1.6.0 update to the @azure/core-util package. Several places in the code only allow node to be used.
This propagates to the @azure/storage-blob@12.14.0 library where I can't login with a connection string anymore (
It worked fine when the SDK thought Deno was just Node, so it broke at this commit it looks like bee878f |
@eikooc can you open a new issue for the storage issue? |
Hi @cveld, we deeply appreciate your input into this project. Regrettably, this issue has remained inactive for over 2 years, leading us to the decision to close it. We've implemented this policy to maintain the relevance of our issue queue and facilitate easier navigation for new contributors. If you still believe this topic requires attention, please feel free to create a new issue, referencing this one. Thank you for your understanding and ongoing support. |
Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust, currently at version 1.6.3.
It makes sense that the Azure SDK for JavaScript also would provide support for Deno.
More info on Deno can be found here:
https://deno.land/
The text was updated successfully, but these errors were encountered: