Node interface for the Lokalise APIv2.
View the Project on GitHub lokalise/node-lokalise-api
const client = new LokaliseApi({
apiKey: "API_KEY",
requestTimeout: 5e3, // the value is in milliseconds
});
try {
await client.projects().list();
} catch (e) {
console.error(e);
console.log(e.message); // "Request timed out after 5000ms"
console.log(e.code); // 408
console.log(e.details); // { reason: "timeout" }
}
PermissionTemplates
endpoint:const roles = await lokaliseApi.permissionTemplates().list({
team_id: teamId,
});
const roleDetails = roles.items[0];
roleDetails.id // => 1
roleDetails.role // => "Manager"
roleDetails.tag // => "Full access"
role_id
attribute to the user group object. For example:const user_group = await lokaliseApi.userGroups().get(groupId, {
team_id: teamId,
});
user_group.role_id; // => 5
role_id
attribute to the contributor object. For example:const contributor = await lokaliseApi.contributors().get(userId, {
project_id: projectId,
});
contributor.role_id; // => 5
tm_leverage
field for the languages
of the Task
object:const task = await lokaliseApi.tasks().get(taskId, {
project_id: projectId,
});
const language = task.languages[0];
language.tm_leverage.status; // => "completed"
language.tm_leverage.value["50%+"]; // => 31
tm_leverage
are “0%+”, “50%+”, “75%+”, “85%+”, “95%+”, and “100%”. Please note that the usage of initial_tm_leverage
is deprecated.ai_words
parameter under the quota_usage
and quota_allowed
field of the Team
object:const teams = await lokaliseApi.teams().list();
const team = teams.items[0];
team.quota_allowed.ai_words // => 4000
team.quota_usage.ai_words // => 1234
// This approach is also applicable for `lokaliseApi.translations().list()`
const keys = await lokaliseApi.keys().list({
project_id: projectId,
limit: 2, // The number of items to fetch. Optional, default is 100
pagination: "cursor",
cursor: "eyIxIjo1MjcyNjU2MTd9", // The starting cursor. Optional, string
});
const key = keys.items[0]; // Accessing items as with regular pagination
const hasNext = keys.hasNextCursor(); // Returns a boolean
const nextCursor = keys.nextCursor; // Returns the next cursor as a string, empty if unavailable
const keysNextPortion = await lokaliseApi.keys().list({
project_id: projectId,
limit: 2,
pagination: "cursor",
cursor: nextCursor,
});
WebhookProjectTranslationsProofread
webhook event type according to the documentationclose_language
attribute to languages
of UpdateTaskParams
(thanks, @FelixGraf)close_language
attribute to languages
of UpdateTaskParams
(thanks, @FelixGraf)compact
attribute to FileDownloadParams
interfacecompact
attribute to FileDownloadParams
interfaceDownloadFileParams
and UploadFileParams
) are stricter now and accept only the values that are actually supported by the API.DownloadFileParams
and UploadFileParams
) are stricter now and accept only the values that are actually supported by the API.jwt().get()
with jwt().create()
. The create()
method accepts a mandatory project_id
parameter:const response = await lokaliseApi.jwt().create("1234.abcd");
response.jwt // => "eyJ0eXAiOiJKV1QiLCJhbG..."
const response = await lokaliseApi.jwt().get();
response.jwt // => "eyJ0eXAiOiJKV1QiLCJhbG"
upvoting
attribute from the settings
object was removed from the response body of the following endpoints:
KeyParamsWithPagination
, CreateKeyData
, and others.require
anymore). What can you do about it?
upvoting
attribute from the settings
object was removed from the response body of the following endpoints:
KeyParamsWithPagination
interfacesApiError
, Comment
, File
, and so on. For example, now you can say:// We can import the Contributor interface easily:
import { LokaliseApi, Contributor } from '@lokalise/node-api';
const lokaliseApi = new LokaliseApi({ apiKey: '123xyz' });
const contributors = await lokaliseApi.contributors().create([
{
// ...
}
], { project_id: '123.abc' });
const contributor: Contributor = contributors[0];
console.log(contributor.email, contributor.user_id);
RequestTokenResponse
and RefreshTokenResponse
interfaces:import {
RequestTokenResponse,
RefreshTokenResponse,
LokaliseAuth
} from '@lokalise/node-api';
const lokaliseAuth = new LokaliseAuth("123abc", "456zyx");
const token_resp: RequestTokenResponse = await lokaliseAuth.token("secret_code");
const refresh_resp: RefreshTokenResponse = await lokaliseAuth.refresh("refresh_token");
keys().create()
when use_automations
param was ignored. Please note that now keys have to be created in a slightly different way:const keys = await lokaliseApi.keys().create(
{
keys: [
{
key_name: "welcome_web",
description: "Index app welcome",
platforms: ["web"],
filenames: {
web: "my_filename.json",
},
translations: [
{
language_iso: "en",
translation: "Welcome",
},
],
},
{
key_name: "welcome_ios",
description: "Welcome apple",
platforms: ["ios"],
is_plural: true,
translations: [
{
language_iso: "en",
translation: {
one: "I have one apple",
other: "I have a lot of apples",
},
},
],
},
],
},
{ project_id: project_id }
);
// Per-platform key names:
const keys = await lokaliseApi.keys().create(
{
keys: [
{
key_name: {
ios: "name_for_ios",
web: "name_for_web",
android: "android_name",
other: "other_name",
},
platforms: ["web", "ios"],
translations: [
{
language_iso: "en",
translation: "Per-platform key names",
},
],
},
],
},
{ project_id: project_id }
);
const keys = await lokaliseApi.keys().bulk_update(
{
keys: [
{
key_id: key_id,
description: "Bulk node",
platforms: ["web"],
},
{
key_id: second_key_id,
description: "Second bulk",
},
],
},
{ project_id: project_id }
);
"https://api.lokalise.com/api2/"
(for API endpoints) and "https://app.lokalise.com/oauth2/"
(for OAauth 2 flow) but you can override these by providing an optional host
param:const client = new LokaliseApi({
apiKey: "123abc",
host: "https://custom.example.com/api2/",
});
const { LokaliseAuth } = require('@lokalise/node-api');
// Provide your client id and client secret
const lokaliseAuth = new LokaliseAuth("client id", "client secret");
// Generate an authentication url
const url = lokaliseAuth.auth(
["read_projects", "write_team_groups"],
"http://example.com/redirect",
"random123"
);
// Generate an authentication and refresh tokens
const response = await lokaliseAuth.token("secret code");
const token = response["access_token"];
const refresh_token = response["refresh_token"];
// Refresh an access token once it expires
const new_token = await lokaliseAuth.refresh(refresh_token)["access_token"];
// Perform requests on the user's behalf
const { LokaliseApiOAuth } = require('@lokalise/node-api');
const lokaliseApi = new LokaliseApiOAuth({ apiKey: new_token });
const projects = lokaliseApi.projects().list();
TeamUserBillingDetails
endpointSegments
endpointlanguage_mapping
for DownloadFileParams
(thanks, @dhensby)lokaliseApi.comments.list_project_comments()
lokaliseApi.files.upload()
lokaliseApi.comments().list_project_comments() // .comments(), not .comments
lokaliseApi.files().upload() // .files(), not .files
LokaliseApiOAuth
class:const lokaliseApi = new LokaliseApiOAuth({ apiKey: '<apiKeyObtainedViaOauth2>' });
const projects = lokaliseApi.projects().list();
enableCompression
option: new LokaliseApi({ apiKey: "123abc", enableCompression: true })
. The default value for this option is false
. When set to true
, it will add an Accept-Encoding=gzip,deflate
header to the request. It can be very useful when requesting a large amount of data.UploadFileParams
interface to comply with the API paramstypescript
to devDependencies
(thanks, @omonk)task_id
for Translation
payment_method
field (string
) for the Order
ApiRequest
(thanks, @Tenga)This is a major release that contains quite a lot of changes mostly aimed towards pagination and typings system. Also the docs were updated, and various fixes were introduced.
Breaking change: pagination data is now attached directly to the collection returned by the request. Previously the following code was not working because pagination was stored in a separate object unrelated to the collection:
const projects = lokaliseApi.projects.list({team_id: team_id, page: 2, limit: 10});
projects.totalResults; // => undefined
Therefore, you had to do the following inconvenient trick (for example, see #53):
lokaliseApi.projects.list().totalResults;
This is not the case anymore! Paginated collections now have the following attributes and functions:
projects.totalResults; // => 30
projects.totalPages; // => 3
projects.resultsPerPage; // => 10
projects.currentPage; // => 2
projects.hasNextPage(); // => true
projects.hasPrevPage(); // => true
projects.isLastPage(); // => false
projects.isFirstPage(); // => false
projects.nextPage(); // => 3
projects.prevPage(); // => 1
However to get the actual data from the paginated response, you must use the .items
attribute now:
const projects = lokaliseApi.projects.list({team_id: team_id, page: 2, limit: 10});
// CORRECT:
const project = projects.items[0]; // .items will fetch all projects data and [0] will get the first project
project.name
// INCORRECT:
const project = projects[0]; // this will not work anymore!
project.name
// And pagination can be fetched in the following way:
projects.totalResults; // => 30
projects.hasNextPage(); // => true
Breaking change: potential errors returned by the API when performing bulk create or bulk update operations are not swallowed anymore. For example, Lokalise APIv2 allows to create translation keys in bulk. If one of the key names is already taken, it won’t be created and the corresponding error message will be added to the errors
response attribute. However, the whole operation will not fail and all other valid keys will still be created. The response has the following structure:
{
"project_id": "300abc.877xyz",
"keys": [
// keys that were successfully created
],
"errors": [
{
"message": "This key name is already taken",
"code": 400,
"key": {
"key_name": "button.ok" // this key name cannot be created because of the duplicating name
}
}
]
}
Previously such errors were silently swallowed, however that’s not the case anymore. Specifically, changes were made to the following methods:
keys.create
keys.bulk_update
(note that keys.update
is unaffected by this change)languages.create
screenshots.create
To fetch the actual data returned by these methods you now have to use the .items
attribute. To fetch the errors, use .errors
:
const keys = await lokaliseApi.keys.create(
[
{
key_name: "valid.key.name",
platforms: ["web"],
filenames: { web: "%LANG_ISO%.yml", },
translations: [
{
language_iso: "en",
translation: "Valid key",
},
],
},
{
key_name: "duplicate.key",
platforms: ["web"],
translations: [
{
language_iso: "en",
translation: "Duplicate!",
},
],
},
],
{ project_id: '123.abc' }
);
keys.errors[0].message // => "This key name is already taken" -- this key was not created
keys.items[0].key_name.ios // => "valid.key.name" -- this key was created
Update: added auto_close_items
boolean attribute for Task
.
use_automations
flag to UploadFileParams
(default is true
)source_language_iso
for the Task
Key
and File
.queue
parameter doesn’t have any effect anymore. Therefore, removed all code and docs related to sync uploading.merge
method for the Branches
endpoint. It now accepts the branch ID to merge, the project ID and the optional list of additional parameters:lokaliseApi.branches.merge(34567,
{project_id: '123.abc'},
{"force_conflict_resolve_using": "master"}
)
QueuedProcess
with the job status will be returned as a result. Synchronous uploading is still supported by the API but will be removed in the near future (use version 3 to upload synchronously).QueuedProcess
endpointwebhook_id
type for Webhooks
endpointUploadFileParams
lokaliseApi.webhooks.regenerate_secret(webhook_id, {project_id: project_id});
totalResults
, totalPages
, resultsPerPage
, currentPage
noImplicitAny
and strictNullChecks
to true
in tsconfig.json
merge
method for the branches endpoint allowing to perform mergesBranch
endpointWebhook
endpointTranslationStatus
endpointNote that this version is a major re-write and has API breaking changes! Check documentation for the specific endpoint to learn more.
TranslationProvider
, Order
, PaymentCard