gt 2.13.3 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # gtx-cli
2
2
 
3
+ ## 2.14.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1153](https://github.com/generaltranslation/gt/pull/1153) [`df6bea8`](https://github.com/generaltranslation/gt/commit/df6bea819a4274018d6d99c7d3e00e7c5372ccbc) Thanks [@moss-bryophyta](https://github.com/moss-bryophyta)! - Add `<RelativeTime>` component for localized relative time formatting
8
+ - New `<RelativeTime>` component with two usage modes:
9
+ - Auto-select unit from a Date: `<RelativeTime>{someDate}</RelativeTime>` → "2 hours ago"
10
+ - Explicit value + unit: `<RelativeTime value={-1} unit="day" />` → "yesterday"
11
+ - Core: `_selectRelativeTimeUnit()` auto-selects the best unit (seconds → minutes → hours → days → weeks → months → years)
12
+ - Core: `formatRelativeTimeFromDate()` standalone function and `GT.formatRelativeTimeFromDate()` class method
13
+ - Week unit included in auto-selection thresholds (7-27 days)
14
+ - CLI, compiler, and SWC plugin updated to recognize `RelativeTime` as a variable component
15
+
16
+ ### Patch Changes
17
+
18
+ - [#1160](https://github.com/generaltranslation/gt/pull/1160) [`9d2349c`](https://github.com/generaltranslation/gt/commit/9d2349cfc41862d9e3d8364659b678055b9fa290) Thanks [@fernando-aviles](https://github.com/fernando-aviles)! - Adding translation tagging
19
+
20
+ - Updated dependencies [[`9d2349c`](https://github.com/generaltranslation/gt/commit/9d2349cfc41862d9e3d8364659b678055b9fa290), [`df6bea8`](https://github.com/generaltranslation/gt/commit/df6bea819a4274018d6d99c7d3e00e7c5372ccbc)]:
21
+ - generaltranslation@8.2.0
22
+ - @generaltranslation/python-extractor@0.2.4
23
+
3
24
  ## 2.13.3
4
25
 
5
26
  ### Patch Changes
package/dist/cli/flags.js CHANGED
@@ -37,7 +37,9 @@ export function attachTranslateFlags(command) {
37
37
  .option('--branch <branch>', 'Specify a custom branch to use for translations')
38
38
  .option('--disable-branch-detection', 'Disable additional branch detection and optimizations and use the manually specified branch', false)
39
39
  .option('--enable-branching', 'Enable branching for the project')
40
- .option('--remote-name <name>', 'Specify a custom remote name to use for branch detection', DEFAULT_GIT_REMOTE_NAME);
40
+ .option('--remote-name <name>', 'Specify a custom remote name to use for branch detection', DEFAULT_GIT_REMOTE_NAME)
41
+ .option('--tag <value>', 'Tag ID for this translation run (use "git" to auto-resolve from current commit)')
42
+ .option('-m, --message <message>', 'Message to attach to the translation tag');
41
43
  return command;
42
44
  }
43
45
  /**
@@ -7,6 +7,8 @@ import { resolveFiles } from '../fs/config/parseFilesConfig.js';
7
7
  import { validateSettings } from './validateSettings.js';
8
8
  import { DEFAULT_GIT_REMOTE_NAME, GT_DASHBOARD_URL, } from '../utils/constants.js';
9
9
  import { resolveProjectId } from '../fs/utils.js';
10
+ import crypto from 'node:crypto';
11
+ import { execSync } from 'node:child_process';
10
12
  import path from 'node:path';
11
13
  import chalk from 'chalk';
12
14
  import { resolveConfig } from './resolveConfig.js';
@@ -225,6 +227,31 @@ export async function generateSettings(flags, cwd = process.cwd()) {
225
227
  gtConfig.branchOptions?.remoteName ??
226
228
  DEFAULT_GIT_REMOTE_NAME;
227
229
  mergedOptions.branchOptions = branchOptions;
230
+ // Map -m/--message flag to tagMessage
231
+ if (flags.message) {
232
+ mergedOptions.tagMessage = flags.message;
233
+ }
234
+ // Resolve tag:
235
+ // --tag git (explicit) or -m without --tag: try git SHA, fall back to random hex
236
+ // --tag <value>: use as-is
237
+ // No flags: no tag
238
+ if (flags.tag === 'git' || (!flags.tag && mergedOptions.tagMessage)) {
239
+ try {
240
+ mergedOptions.tag = execSync('git rev-parse --short HEAD', {
241
+ encoding: 'utf-8',
242
+ }).trim();
243
+ // If no message provided, use git commit message
244
+ if (!mergedOptions.tagMessage) {
245
+ mergedOptions.tagMessage = execSync('git log -1 --format=%s', {
246
+ encoding: 'utf-8',
247
+ }).trim();
248
+ }
249
+ }
250
+ catch {
251
+ // Not in a git repo or git unavailable — fall back to random hex
252
+ mergedOptions.tag = crypto.randomBytes(4).toString('hex');
253
+ }
254
+ }
228
255
  // if there's no existing config file, creates one
229
256
  // does not include the API key to avoid exposing it
230
257
  if (!fs.existsSync(mergedOptions.config)) {
@@ -1 +1 @@
1
- export declare const PACKAGE_VERSION = "2.13.3";
1
+ export declare const PACKAGE_VERSION = "2.14.0";
@@ -1,2 +1,2 @@
1
1
  // This file is auto-generated. Do not edit manually.
2
- export const PACKAGE_VERSION = '2.13.3';
2
+ export const PACKAGE_VERSION = '2.14.0';
@@ -18,6 +18,12 @@ export declare const TRANSLATION_COMPONENT = "T";
18
18
  export declare const STATIC_COMPONENT = "Static";
19
19
  export declare const DERIVE_COMPONENT = "Derive";
20
20
  export declare const BRANCH_COMPONENT = "Branch";
21
+ export declare const VAR_COMPONENT = "Var";
22
+ export declare const DATETIME_COMPONENT = "DateTime";
23
+ export declare const RELATIVE_TIME_COMPONENT = "RelativeTime";
24
+ export declare const CURRENCY_COMPONENT = "Currency";
25
+ export declare const NUM_COMPONENT = "Num";
26
+ export declare const PLURAL_COMPONENT = "Plural";
21
27
  export declare const GT_TRANSLATION_FUNCS: string[];
22
28
  export declare const STRING_REGISTRATION_FUNCS: readonly ["msg", "t"];
23
29
  export declare const GT_DERIVE_STRING_FUNCTIONS: string[];
@@ -6,7 +6,7 @@ export const DECLARE_STATIC_FUNCTION = 'declareStatic';
6
6
  export const DERIVE_FUNCTION = 'derive';
7
7
  export const MSG_REGISTRATION_FUNCTION = 'msg';
8
8
  export const T_REGISTRATION_FUNCTION = 't';
9
- export const T_GLOBAL_REGISTRATION_FUNCTION = 't';
9
+ export const T_GLOBAL_REGISTRATION_FUNCTION = T_REGISTRATION_FUNCTION;
10
10
  export const INLINE_TRANSLATION_HOOK = 'useGT';
11
11
  export const INLINE_TRANSLATION_HOOK_ASYNC = 'getGT';
12
12
  export const INLINE_MESSAGE_HOOK = 'useMessages';
@@ -18,6 +18,13 @@ export const TRANSLATION_COMPONENT = 'T';
18
18
  export const STATIC_COMPONENT = 'Static';
19
19
  export const DERIVE_COMPONENT = 'Derive';
20
20
  export const BRANCH_COMPONENT = 'Branch';
21
+ // Variable components
22
+ export const VAR_COMPONENT = 'Var';
23
+ export const DATETIME_COMPONENT = 'DateTime';
24
+ export const RELATIVE_TIME_COMPONENT = 'RelativeTime';
25
+ export const CURRENCY_COMPONENT = 'Currency';
26
+ export const NUM_COMPONENT = 'Num';
27
+ export const PLURAL_COMPONENT = 'Plural';
21
28
  // GT translation functions
22
29
  export const GT_TRANSLATION_FUNCS = [
23
30
  INLINE_TRANSLATION_HOOK,
@@ -32,12 +39,13 @@ export const GT_TRANSLATION_FUNCS = [
32
39
  TRANSLATION_COMPONENT,
33
40
  STATIC_COMPONENT,
34
41
  DERIVE_COMPONENT,
35
- 'Var',
36
- 'DateTime',
37
- 'Currency',
38
- 'Num',
42
+ VAR_COMPONENT,
43
+ DATETIME_COMPONENT,
44
+ RELATIVE_TIME_COMPONENT,
45
+ CURRENCY_COMPONENT,
46
+ NUM_COMPONENT,
39
47
  BRANCH_COMPONENT,
40
- 'Plural',
48
+ PLURAL_COMPONENT,
41
49
  ];
42
50
  // GT String translation functions
43
51
  export const STRING_REGISTRATION_FUNCS = [
@@ -51,10 +59,11 @@ export const GT_DERIVE_STRING_FUNCTIONS = [
51
59
  ];
52
60
  // Valid variable components
53
61
  export const VARIABLE_COMPONENTS = [
54
- 'Var',
55
- 'DateTime',
56
- 'Currency',
57
- 'Num',
62
+ VAR_COMPONENT,
63
+ DATETIME_COMPONENT,
64
+ RELATIVE_TIME_COMPONENT,
65
+ CURRENCY_COMPONENT,
66
+ NUM_COMPONENT,
58
67
  STATIC_COMPONENT,
59
68
  DERIVE_COMPONENT,
60
69
  ];
@@ -61,6 +61,8 @@ export type TranslateFlags = SharedFlags & {
61
61
  publish?: boolean;
62
62
  force?: boolean;
63
63
  forceDownload?: boolean;
64
+ tag?: string;
65
+ message?: string;
64
66
  experimentalLocalizeStaticUrls?: boolean;
65
67
  experimentalHideDefaultLocale?: boolean;
66
68
  experimentalFlattenJsonFiles?: boolean;
@@ -193,6 +195,8 @@ export type Settings = {
193
195
  framework?: SupportedFrameworks;
194
196
  options?: AdditionalOptions;
195
197
  modelProvider?: string;
198
+ tag?: string;
199
+ tagMessage?: string;
196
200
  parsingOptions: ParsingConfigOptions;
197
201
  branchOptions: BranchOptions;
198
202
  sharedStaticAssets?: SharedStaticAssetsConfig;
@@ -1,9 +1,11 @@
1
1
  import { logCollectedFiles, logErrorAndExit } from '../console/logging.js';
2
+ import { logger } from '../console/logger.js';
2
3
  import { gt } from '../utils/gt.js';
3
4
  import { UploadSourcesStep } from './steps/UploadSourcesStep.js';
4
5
  import { SetupStep } from './steps/SetupStep.js';
5
6
  import { EnqueueStep } from './steps/EnqueueStep.js';
6
7
  import { BranchStep } from './steps/BranchStep.js';
8
+ import { TagStep } from './steps/TagStep.js';
7
9
  import { UserEditDiffsStep } from './steps/UserEditDiffsStep.js';
8
10
  import { calculateTimeoutMs } from '../utils/calculateTimeoutMs.js';
9
11
  /**
@@ -39,6 +41,18 @@ export async function runStageFilesWorkflow({ files, options, settings, }) {
39
41
  await userEditDiffsStep.run(uploadedFiles);
40
42
  await userEditDiffsStep.wait();
41
43
  }
44
+ // then run the tag step (non-fatal — tagging failure should not block translations)
45
+ if (settings.tag) {
46
+ try {
47
+ const userProvidedTag = !!options.tag;
48
+ const tagStep = new TagStep(gt, settings, userProvidedTag);
49
+ await tagStep.run(uploadedFiles);
50
+ await tagStep.wait();
51
+ }
52
+ catch {
53
+ logger.warn('Failed to create translation tag. Continuing...');
54
+ }
55
+ }
42
56
  // then run the setup step
43
57
  await setupStep.run(uploadedFiles);
44
58
  await setupStep.wait();
@@ -0,0 +1,15 @@
1
+ import type { CreateTagResult } from 'generaltranslation/types';
2
+ import { WorkflowStep } from './WorkflowStep.js';
3
+ import { GT } from 'generaltranslation';
4
+ import { Settings } from '../../types/index.js';
5
+ import type { FileReference } from 'generaltranslation/types';
6
+ export declare class TagStep extends WorkflowStep<FileReference[], CreateTagResult> {
7
+ private gt;
8
+ private settings;
9
+ private userProvided;
10
+ private spinner;
11
+ private result;
12
+ constructor(gt: GT, settings: Settings, userProvided: boolean);
13
+ run(files: FileReference[]): Promise<CreateTagResult>;
14
+ wait(): Promise<void>;
15
+ }
@@ -0,0 +1,44 @@
1
+ import { WorkflowStep } from './WorkflowStep.js';
2
+ import { logger } from '../../console/logger.js';
3
+ import chalk from 'chalk';
4
+ export class TagStep extends WorkflowStep {
5
+ gt;
6
+ settings;
7
+ userProvided;
8
+ spinner = logger.createSpinner('dots');
9
+ result = null;
10
+ constructor(gt, settings, userProvided) {
11
+ super();
12
+ this.gt = gt;
13
+ this.settings = settings;
14
+ this.userProvided = userProvided;
15
+ }
16
+ async run(files) {
17
+ if (this.userProvided) {
18
+ this.spinner.start('Creating translation tag...');
19
+ }
20
+ try {
21
+ this.result = await this.gt.createTag({
22
+ tagId: this.settings.tag,
23
+ files: files.map((f) => ({
24
+ fileId: f.fileId,
25
+ versionId: f.versionId,
26
+ branchId: f.branchId,
27
+ })),
28
+ message: this.settings.tagMessage,
29
+ });
30
+ }
31
+ catch (error) {
32
+ if (this.userProvided) {
33
+ this.spinner.stop(chalk.yellow('Failed to create translation tag'));
34
+ }
35
+ throw error;
36
+ }
37
+ return this.result;
38
+ }
39
+ async wait() {
40
+ if (this.result && this.userProvided) {
41
+ this.spinner.stop(chalk.green(`Tagged as ${chalk.bold(this.result.tag.tagId)}`));
42
+ }
43
+ }
44
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gt",
3
- "version": "2.13.3",
3
+ "version": "2.14.0",
4
4
  "main": "dist/index.js",
5
5
  "bin": "dist/main.js",
6
6
  "files": [
@@ -110,8 +110,8 @@
110
110
  "unified": "^11.0.5",
111
111
  "unist-util-visit": "^5.0.0",
112
112
  "yaml": "^2.8.0",
113
- "@generaltranslation/python-extractor": "0.2.3",
114
- "generaltranslation": "8.1.23",
113
+ "@generaltranslation/python-extractor": "0.2.4",
114
+ "generaltranslation": "8.2.0",
115
115
  "gt-remark": "1.0.6"
116
116
  },
117
117
  "devDependencies": {