github graphql api default branch in repository - api

I have the following query:
{
repository(owner: "org", name: "name") {
name
object(expression: "master:package.json") {
... on Blob {
text
}
}
}
}
but as you can see I have to hardcode master in the object expression. I'm wondering if there's a way to instead use the default branch in that query. Is that possible without having to do 2 queries (1 to get the default branch, then another to get the file content)?

There was a related question (with bounty too) on that, detailed in this thread... but it is the syntax you are using:
The argument passed to expression on the object field is actually a git revision expression suitable for git rev-parse, so I guess you can have fun with it to do advanced querying.
So any way to specify a revision should do, including HEAD, which would reference the default remote branch. But not the "current branch" though.

Related

How can I get and use the properties I need from this GraphQL API using Dart?

Before you start reading: I have looked at the GraphQL documentation, but my usecase is so specific and I only need the data once, and therefore I allow myself to ask the community for help on this one to save some time and frustration (not planning to learn GraphQL in the future)
Intro
I am a CS student developing an app for Flutter on the side, where I need information about the name and location of every bus stop in a specific county in Norway. Luckily, there's an open GraphQL API for this (API URL: https://api.entur.io/stop-places/v1/graphql). The thing is, I don't know how to query a GraphQL API, and I do not want to spend time learning it as I am only going to fetch the data once and be done with it.
Here's the IDE for the API: https://api.entur.io/stop-places/v1/ide
And this is the exact query I want to perform as I want to fetch bus stops located in the county of Trondheim:
{
stopPlace(stopPlaceType: onstreetBus, countyReference: "Trondheim") {
name {
value
}
... on StopPlace {
quays {
geometry {
coordinates
}
}
}
}
}
The problem with this query though, is that I don't get any data when passing "Trondheim" to the countyReference (without countyReference I get the data, but not for Trondheim). I've tried using the official municipal number for the county as well without any luck, and the documentation of the API is rather poor... Maybe this is something I'll have to contact the people responsible for the API to figure out, which shouldn't be a problem.
But now back to the real problem - how can I make this query using the GraphQL package for Dart? Here's the package I'm planning to use: (https://pub.dev/packages/graphql)
I want to create a bus stop object for each bus stop, and I want to put them all in a list. Here is my bus stop model:
class BusStop with ChangeNotifier {
final String id;
final String name;
final LatLng location;
BusStop({
this.id,
this.name,
this.location
});
}
When it comes to authentication, here's what the documentation says:
This API is open under NLOD licence, however, it is required that all consumers identify themselves by using the header ET-Client-Name. Entur will deploy strict rate-limiting policies on API-consumers who do not identify with a header and reserves the right to block unidentified consumers. The structure of ET-Client-Name should be: "company - application"
Header examples: "brakar - journeyplanner" "fosen_utvikling - departureboard" "norway_bussekspress - nwy-app"
Link to API documentation: https://developer.entur.org/pages-nsr-nsr
Would be great to know how I should go about this as well! I'm grateful for every answers to this, I know I am being lazy here as of learning GraphQL, but for my usecase I thought it would take less time and frustration by asking here!
Getting the query right
First of all you seem to have GraphQL quite figured out. There isn't really much more to it than what you are doing. What queries an API supports depends on the API. The problem you seem to have is more related to the specific API that you are using. I might have figured the right query out for you and if not I will quickly explain what I did and maybe you can improve the query yourself:
{
stopPlace(stopPlaceType: onstreetBus, municipalityReference: "KVE:TopographicPlace:5001") {
name {
value
}
... on StopPlace {
quays {
geometry {
coordinates
}
}
}
}
}
So to get to this I started finding out more about "Trondheim" bei using the topographicPlace query.
{
topographicPlace(query: "Trondheim") {
id
name {
value
}
topographicPlaceType
parentTopographicPlace {
id
name {
value
}
}
}
}
If you do that you will see that "Trondheim" is not a county according to the API: "topographicPlaceType": "municipality". I have no idea what municipality is but the is a different filter for this type on the query that you provided. Then putting "Trondheim" there didn't yield any results so I tried the ID of Trondheim. This now gives me a bunch of results.
About the GraphQL client that you are using:
This seems to be an "Apollo Client" clone in Dart. Apollo Client is a heavy piece of software that comes with a lot of awesome features when used in a frontend application. You probably just want to make a single GraphQL request from a backend. I would recommend using a simple HTTP client to send a POST request to the GraphQL API and a JSON body (don't forget content type header) with the following properties: query containing the query string from above and variables a JSON object mapping variable names to values (only needed if you decide to add variables to your query.

How to get all FAL File Objects which are referenced?

I'm trying to make a extbase extension for TYPO3 to get alle file objects with mimetype image/... which referenced by any content, plugin or fluid in typo3.
But i don't know which is the best way to get these data. How should i create a model in my extension and how should i create the correct repository?
If i create a custom query i'm not sure how to return a complete FAL Object which contains any data (like metadata) etc.
hope someone could help me to find the right way, and maybe has a example or something.
thanks a lot
You could do it like this, details are at the bottom:
Get all file references.
Go through them, retrieve the referenced file for each of them and retain only the ones where the field mime_type starts with image/.
There are two things you probably need to watch out for:
The field mime_type needs to be up to date. Check the FAL scheduler indexing task for that.
Performance. Depending on the number of files you have, it could be much faster to do this with a custom SQL statement which makes use of a JOIN. But you should only do that if performance is a problem.
How to get all file references:
First, build your own empty file reference class:
namespace Vendor/Extkey/Domain/Model;
class FileReference extends \TYPO3\CMS\Extbase\Domain\Model\FileReference {}
Make sure to configure it in your TypoScript to be serialized to the table sys_file_reference:
config.tx_extbase.persistence {
classes {
Vendor\Extkey\Domain\Model\FileReference {
mapping {
tableName = sys_file_reference
}
}
}
}
Add a repository for the references:
namespace Vendor/Extkey/Domain/Repository;
class FileReferenceRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
public function initializeObject() {
/** #var \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface */
$defaultQuerySettings = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\QuerySettingsInterface');
$defaultQuerySettings->setRespectStoragePage(FALSE);
$this->setDefaultQuerySettings($defaultQuerySettings);
}
}
The reference class can be empty, but the repository needs it to be there in order to work correctly. Make sure you add the default query settings to ignore the page id, so you get all non-hidden and non-deleted file references by calling $fileReferenceRepository->findAll().
How to check the MIME-type of each referenced file:
You can get the MIME-type of each reference by calling
$fileReference->getOriginalResource()->getMimeType()
This should automatically fetch the original file from storage and read its MIME-type.

GitHub API (v3): Order tags by creation date

I ran into a problem / question while using the GitHub API.
I need a list of all tags created after a single tag. The only way to do this, is to compare the tags by date. However, the results from the API aren't ordered by date:
Result from the API (rails repository example):
Results from the webinterface:
What i did expect is a list ordered by date. However, as you can see in the pictures: the API is returning v4.0.0rc1 & v4.0.0rc2 before the release of v4.0.0, while 4.0.0 is released after the release candidates. There isn't even a creation / commit date to order at server side.
The releases API isn't a solution either. This API is only returning releases created by Github, not the releases created by tags.
Is there any way to order the tags by date?
Thanks in advance!
Ruben
The Repositories API currently returns tags in the order they would be returned by the "git tag" command, which means they are alphabetically sorted.
The problem with sorting tags chronologically in Git is that there are two types of tags, lightweight and annotated), and for the lightweight type Git doesn't store the creation date.
The Releases/Tags UI currently sorts tags chronologically by the date of the commit to which the tag points to. This again isn't the date on which the tag itself was created, but it does establish a chronological order of things.
Adding this alternative sorting option to the API is on our feature request list.
With GraphQL API v4, we can now filter tags by commit date with field: TAG_COMMIT_DATE inside orderBy. The following will perform ascending sort of tags by commit date :
{
repository(owner: "rails", name: "rails") {
refs(refPrefix: "refs/tags/", last: 100, orderBy: {field: TAG_COMMIT_DATE, direction: ASC}) {
edges {
node {
name
target {
oid
... on Tag {
message
commitUrl
tagger {
name
email
date
}
}
}
}
}
}
}
}
Test it in the explorer
Here, the tagger field inside target will only be filled for annotated tag & will be empty for lightweight tags.
As date property in tagger gives the creation date of the tag (for annotated tag only), it's possible to filter by creation date on the client side easily (without having to retrieve all the tags 1 by 1)
Note that available options for orderBy.field at this time are TAG_COMMIT_DATE & ALPHABETICAL (no TAG_CREATION_DATE)
Edit: This is now possible using the GitHub GraphQL API.
As workaround, there is a node module for this,
which basically fetches the commit details of each tag:
github-api-tags-full
> npm install github-api-tags-full github moment
var GitHubApi = require('github'),
moment = require('moment'),
githubTags = require('github-api-tags-full');
var github = new GitHubApi({
version: '3.0.0'
});
githubTags({ user: 'golang', repo: 'go' }, github)
.then(function(tags) {
var tagsSorted = tags.sort(byAuthorDateAsc).reverse(); // descending
console.log(tagsSorted); // prints the array of tags sorted by their creation date
});
var byAuthorDateAsc = function(tagA, tagB) {
return githubCompareDates(
tagA.commit.author.date,
tagB.commit.author.date
);
};
var githubCompareDates = function(dateStrA, dateStrB) {
return moment(dateStrA).diff(dateStrB);
};
With best regards
You can use the Git References API.
This can return also all the tags matching a certain prefix.
In you case, you probably want something like:
https://api.github.com/repos/rails/rails/git/matching-refs/tags/v
Or in the case of a monorepo:
https://api.github.com/repos/grafana/loki/git/matching-refs/tags/helm-loki-
Downsides:
sorting: the results are sorted in increasing semver order and you will get the oldest first.
you don't get much info about each tag and you might have to parse the versions out of the ref name/path
Upside
you get all the ref/tags that match (i.e. no pagination, until GitHub decides to remove/optimise this :) )
you can use it to filter out tags in a monorepo (that most probably tag release components with prefixed tags)

TYPO3 / How to make repository from existing table fe_users?

I am creating a special BE module with Extbase and Fluid and I need a domain object which would be representing standard FE user. When I create new domain object called e.g. Feuser and save it, the extension builder creates special repository and also wants to create special table tx_myextkey_feuser in database. But this table already exists as fe_users.
Is possible to tell typo3 that the repository for Feuser objects already exists (as fe_users table) and that typo3 should use the existing one? How can I do that?
I need it because the extension (including this BE module) needs to have every logic and controls on the same place (this BE module).
Generally speaking I need the same insert dialog for new FE users on two places if possible. If not, I can create my own New/Edit/Show actions, but I need tell TYPO3 that it should use the existing repository with FE users.
I am using typo 4.7.3.
ExtBase already comes with a domain model for the existing table fe_user. This domain model is:
Tx_Extbase_Domain_Model_FrontendUser
It contains all default fe_users fields that come with TYPO3.
If you have extended fe_users with your own fields, you also have to extend the Tx_Extbase_Domain_Model_FrontendUser domain model and the associated repository so it knows the new fields you have added to fe_users.
The associated repository is:
Tx_Extbase_Domain_Repository_FrontendUserRepository
You have to set the storage PID(s) for the repository, so it can find your fe_users.
For controller actions used in frontend plugins use:
plugin.your_plugin {
persistence {
storagePid = somePid, anotherPid
}
}
If controller actions used in backend modules use:
module.your_module {
persistence {
storagePid = somePid, anotherPid
}
}
As far as I know it is not possible to use the same dialogs which come with TYPO3 for your own extension, so you have to create your own actions (new/edit/show) and forms in your backend module.
[Edit]
By default, ExtBase assumes, that all fe_users have assigned a record type. When you open one of your frontend users, you will see the tab "extended" contains a dropdown field, which is labeled "record type". If this field is not set, ExtBase will not be able to find the fe_user by using one of the find-methods from the repository.
You should set the record type for all fe_users (recommended way) or you can disable the mapping to the field by using the following TS in your setup
config.tx_extbase.persistence.classes {
Tx_Extbase_Domain_Model_FrontendUser {
mapping.recordType >
}
}
For newly created fe_users or fe_groups, you can set the default value for the field "record type" by adding the following TS to your root pageTS
TCAdefaults.fe_users.tx_extbase_type = Tx_Extbase_Domain_Model_FrontendUser
TCAdefaults.fe_groups.tx_extbase_type = Tx_Extbase_Domain_Model_FrontendUserGroup
For Extbase 6.X
You need to give class like \TYPO3\CMS\Extbase\Domain\Model\FrontendUser
instead of Tx_Extbase_Domain_Repository_FrontendUserRepository in
Extend existing model class field inside extension builder
After that you can have control of fe_users inside your model....
Also add file ext_typoscript_setup.txt in root of your extension(added automatically if generated via extension_builder)
config.tx_extbase{
persistence{
classes{
TYPO3\CMS\Extbase\Domain\Model\FrontendUser {
subclasses {
Tx_Extendfeuser_Extended = Model_class_with_namespace
}
}
Vendor\EXt\Domain\Model\Extended {
mapping {
tableName = fe_users
recordType = Tx_Extendfeuser_Extended
}
}
}
}
}
Thanks!!!
Works with TYPO3 7.6.X as well

Asana: Adding a task to a project when you create it

I am trying to use the Asana API to create a task that is assigned to me and added to an existing project.
I have tried by not specifying the workspace as suggested by someone else but the task creation still fails.
The jSon I am using is the following;
{ "data":
{
"name":"Testing Project",
"followers":[10112, 141516],
"workspace":6789,
"assignee":12345,
"project": 1234
}
}
If I create the task and then send another call to the API with the following jSon it works, but this means I need to make 2 API calls every time I create a task.
{
"project": 1234
}
Rather old question but it might help someone. Yes, you can attach a task to a project during creation using the 'projects' (not 'project' as stated above) param, passing its id.
You can also attach the task to many projects stating an array at 'projects' => {22, 33, 44}.
It's all here at https://asana.com/developers/api-reference/tasks
(I work for Asana)
The specification for Tasks can be found here: https://asana.com/developers/api-reference/tasks
Notably, you cannot specify a project during creation - you must go through the addProject call for each project you wish to add.
If there is contradictory information on another SO question, I apologize as that may have been written without first double-checking the implementation.
The actual problem is that you are passing an int instead of an string for "projects". Some attributes work well as string or int (e.g. "assignee" or "workspace") but not "projects".
..so correct your json to the following:
{
"data":
{
"name":"Testing Project",
"followers":[10112, 141516],
"workspace":6789,
"assignee":12345,
"project": "1234"
}
}
I wasted half a day -.-'