@things-factory/i18n-base 10.1.145 → 10.1.146
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/config/config.development.js +4 -0
- package/config/config.production.js +4 -0
- package/dist-server/ai-entry/terminology-entry-targets.js +1 -1
- package/dist-server/ai-entry/terminology-entry-targets.js.map +1 -1
- package/dist-server/middlewares/index.js +1 -1
- package/dist-server/middlewares/index.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/tests/preload.test.ts +23 -0
- package/tests/terminology-entry-targets.test.ts +3 -2
- package/translations/es.json +13 -0
|
@@ -53,7 +53,7 @@ exports.I18N_TERMINOLOGY = 'i18n-base.terminology';
|
|
|
53
53
|
/** The categories the terminology screen offers - a term is read as `<category>.<name>`. */
|
|
54
54
|
exports.TERMINOLOGY_CATEGORIES = ['button', 'field', 'label', 'menu', 'text', 'title'];
|
|
55
55
|
/** The languages the application runs - `i18n.languages` of its config, as the terminology screen lists them. */
|
|
56
|
-
const DEFAULT_LOCALES = ['en-US', 'ko-KR', 'zh-CN', 'ja-JP', 'ms-MY'];
|
|
56
|
+
const DEFAULT_LOCALES = ['en-US', 'ko-KR', 'zh-CN', 'ja-JP', 'ms-MY', 'es-ES'];
|
|
57
57
|
function configuredLocales() {
|
|
58
58
|
const languages = env_1.config.get('i18n/languages', null);
|
|
59
59
|
const codes = Array.isArray(languages) ? languages.map(one => one?.code).filter((code) => typeof code === 'string' && !!code) : [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminology-entry-targets.js","sourceRoot":"","sources":["../../server/ai-entry/terminology-entry-targets.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * AI 입력 target of the terminology - the domain's own words for the screens' keys (용어), entered from a\n * glossary or a list the person pastes (operato-application/design/ai/data-entry.md).\n *\n * A plain declaration: this package does not depend on @things-factory/ai-assistant. An application that runs\n * the assistant passes it to `registerEntryTarget` and names its key in a mode. Rows are entered through\n * `createTerminology` and changed through `updateTerminology` (terminology:mutation), run as the person.\n *\n * The read of the update (`terminologies`) carries no @privilege today - anyone signed in to the domain may\n * read the terms. The update's doors are the mutation and that query.\n */\nimport { config } from '@things-factory/env'\n\nimport type { EntryField, EntryRow, EntryTargetDeclaration } from './entry-target-shape'\nimport { changedNames, inputOf, matching, terminologyChangeIssues, terminologyIssues, terminologyLabel } from './terminology-entry-rules'\n\nexport const I18N_TERMINOLOGY = 'i18n-base.terminology'\n\n/** The categories the terminology screen offers - a term is read as `<category>.<name>`. */\nexport const TERMINOLOGY_CATEGORIES = ['button', 'field', 'label', 'menu', 'text', 'title']\n\n/** The languages the application runs - `i18n.languages` of its config, as the terminology screen lists them. */\nconst DEFAULT_LOCALES = ['en-US', 'ko-KR', 'zh-CN', 'ja-JP', 'ms-MY']\n\nfunction configuredLocales(): string[] {\n const languages = config.get('i18n/languages', null) as { code?: string }[] | null\n const codes = Array.isArray(languages) ? languages.map(one => one?.code).filter((code): code is string => typeof code === 'string' && !!code) : []\n return codes.length ? codes : DEFAULT_LOCALES\n}\n\nconst TERMINOLOGIES =\n 'query ($filters: [Filter!], $pagination: Pagination) { terminologies(filters: $filters, pagination: $pagination) { items { id locale category name display description } } }'\n\nconst FIELDS = ['locale', 'category', 'name', 'display', 'description']\n\nexport function terminologyEntryTarget(options: { locales?: string[] } = {}): EntryTargetDeclaration {\n const locales = options.locales?.length ? options.locales : configuredLocales()\n const fields: EntryField[] = [\n { name: 'locale', type: 'enum', required: true, values: locales, labelKey: 'field.locale', description: `the language the display is in - ${locales.join(', ')}` },\n {\n name: 'category',\n type: 'enum',\n required: true,\n values: TERMINOLOGY_CATEGORIES,\n labelKey: 'field.category',\n description: 'the kind of screen word: button, field (a column or input), label, menu, text (a sentence), title'\n },\n { name: 'name', type: 'string', required: true, labelKey: 'field.name', description: 'the key after the category, as the screens use it - \"department\" for label.department' },\n { name: 'display', type: 'string', required: true, labelKey: 'field.display', description: 'what the screen shows in that language' },\n { name: 'description', type: 'string', labelKey: 'field.description' }\n ]\n\n return {\n key: I18N_TERMINOLOGY,\n labelKey: 'label.i18n-entry-terminology',\n description: 'one term of the screens in one language: the language, the category, the key name, and the word to show.',\n mutation: 'mutation ($terminology: NewTerminology!) { createTerminology(terminology: $terminology) { id locale category name display } }',\n fields,\n maxRows: 200,\n variables: (row: EntryRow) => ({ terminology: inputOf(row.values, FIELDS) }),\n appliedOf: (data, row) => ({ id: data?.createTerminology?.id, label: terminologyLabel(data?.createTerminology ?? row.values) }),\n\n /* Read through the repository of the request's domain only, imported when it runs. */\n check: async (rows, { state }) => {\n const domainId = state?.domain?.id\n const names = [...new Set(rows.map(row => row.values.name).filter((v): v is string => typeof v === 'string' && !!v.trim()).map(v => v.trim()))]\n if (!domainId || !names.length) return terminologyIssues(rows, [])\n const [{ getRepository }, { Terminology }, { In }] = await Promise.all([import('@things-factory/shell'), import('../service/terminology/terminology'), import('typeorm')])\n const existing = await getRepository(Terminology).find({ where: { domain: { id: domainId }, name: In(names) } as any, select: ['id', 'locale', 'category', 'name'] as any })\n return terminologyIssues(rows, existing)\n },\n\n update: {\n read: {\n query: TERMINOLOGIES,\n variables: ids => ({ filters: [{ name: 'id', operator: 'in', value: ids }], pagination: { page: 1, limit: ids.length } }),\n recordsOf: data => data?.terminologies?.items ?? []\n },\n find: {\n query: TERMINOLOGIES,\n variables: criteria => ({\n filters: ['name', 'category', 'display'].filter(name => typeof criteria?.[name] === 'string' && criteria[name]).map(name => ({ name, operator: 'search', value: criteria[name] })),\n pagination: { page: 1, limit: 200 }\n }),\n recordsOf: (data, criteria) => matching(data?.terminologies?.items ?? [], criteria),\n criteria: [\n { name: 'name', type: 'string', description: 'a piece of the key name' },\n { name: 'category', type: 'string', description: 'the category' },\n { name: 'display', type: 'string', description: 'a piece of the word shown' }\n ]\n },\n mutation: 'mutation ($id: String!, $patch: TerminologyPatch!) { updateTerminology(id: $id, patch: $patch) { id } }',\n variables: ({ id, values }) => ({ id, patch: inputOf(values, FIELDS) }),\n labelOf: record => terminologyLabel(record),\n fields: FIELDS,\n\n /* A (locale, category, name) another term of the domain already has - the record itself excepted. */\n check: async (rows, { state }) => {\n const domainId = state?.domain?.id\n const names = changedNames(rows)\n if (!domainId || !names.length) return terminologyChangeIssues(rows, [])\n const [{ getRepository }, { Terminology }, { In }] = await Promise.all([import('@things-factory/shell'), import('../service/terminology/terminology'), import('typeorm')])\n const existing = await getRepository(Terminology).find({ where: { domain: { id: domainId }, name: In(names) } as any, select: ['id', 'locale', 'category', 'name'] as any })\n return terminologyChangeIssues(rows, existing as any)\n }\n }\n }\n}\n\n/** The i18n AI 입력 targets - the terminology. An application registers it when a mode names its key. */\nexport function terminologyEntryTargets(options: { locales?: string[] } = {}): EntryTargetDeclaration[] {\n return [terminologyEntryTarget(options)]\n}\n"]}
|
|
1
|
+
{"version":3,"file":"terminology-entry-targets.js","sourceRoot":"","sources":["../../server/ai-entry/terminology-entry-targets.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * AI 입력 target of the terminology - the domain's own words for the screens' keys (용어), entered from a\n * glossary or a list the person pastes (operato-application/design/ai/data-entry.md).\n *\n * A plain declaration: this package does not depend on @things-factory/ai-assistant. An application that runs\n * the assistant passes it to `registerEntryTarget` and names its key in a mode. Rows are entered through\n * `createTerminology` and changed through `updateTerminology` (terminology:mutation), run as the person.\n *\n * The read of the update (`terminologies`) carries no @privilege today - anyone signed in to the domain may\n * read the terms. The update's doors are the mutation and that query.\n */\nimport { config } from '@things-factory/env'\n\nimport type { EntryField, EntryRow, EntryTargetDeclaration } from './entry-target-shape'\nimport { changedNames, inputOf, matching, terminologyChangeIssues, terminologyIssues, terminologyLabel } from './terminology-entry-rules'\n\nexport const I18N_TERMINOLOGY = 'i18n-base.terminology'\n\n/** The categories the terminology screen offers - a term is read as `<category>.<name>`. */\nexport const TERMINOLOGY_CATEGORIES = ['button', 'field', 'label', 'menu', 'text', 'title']\n\n/** The languages the application runs - `i18n.languages` of its config, as the terminology screen lists them. */\nconst DEFAULT_LOCALES = ['en-US', 'ko-KR', 'zh-CN', 'ja-JP', 'ms-MY', 'es-ES']\n\nfunction configuredLocales(): string[] {\n const languages = config.get('i18n/languages', null) as { code?: string }[] | null\n const codes = Array.isArray(languages) ? languages.map(one => one?.code).filter((code): code is string => typeof code === 'string' && !!code) : []\n return codes.length ? codes : DEFAULT_LOCALES\n}\n\nconst TERMINOLOGIES =\n 'query ($filters: [Filter!], $pagination: Pagination) { terminologies(filters: $filters, pagination: $pagination) { items { id locale category name display description } } }'\n\nconst FIELDS = ['locale', 'category', 'name', 'display', 'description']\n\nexport function terminologyEntryTarget(options: { locales?: string[] } = {}): EntryTargetDeclaration {\n const locales = options.locales?.length ? options.locales : configuredLocales()\n const fields: EntryField[] = [\n { name: 'locale', type: 'enum', required: true, values: locales, labelKey: 'field.locale', description: `the language the display is in - ${locales.join(', ')}` },\n {\n name: 'category',\n type: 'enum',\n required: true,\n values: TERMINOLOGY_CATEGORIES,\n labelKey: 'field.category',\n description: 'the kind of screen word: button, field (a column or input), label, menu, text (a sentence), title'\n },\n { name: 'name', type: 'string', required: true, labelKey: 'field.name', description: 'the key after the category, as the screens use it - \"department\" for label.department' },\n { name: 'display', type: 'string', required: true, labelKey: 'field.display', description: 'what the screen shows in that language' },\n { name: 'description', type: 'string', labelKey: 'field.description' }\n ]\n\n return {\n key: I18N_TERMINOLOGY,\n labelKey: 'label.i18n-entry-terminology',\n description: 'one term of the screens in one language: the language, the category, the key name, and the word to show.',\n mutation: 'mutation ($terminology: NewTerminology!) { createTerminology(terminology: $terminology) { id locale category name display } }',\n fields,\n maxRows: 200,\n variables: (row: EntryRow) => ({ terminology: inputOf(row.values, FIELDS) }),\n appliedOf: (data, row) => ({ id: data?.createTerminology?.id, label: terminologyLabel(data?.createTerminology ?? row.values) }),\n\n /* Read through the repository of the request's domain only, imported when it runs. */\n check: async (rows, { state }) => {\n const domainId = state?.domain?.id\n const names = [...new Set(rows.map(row => row.values.name).filter((v): v is string => typeof v === 'string' && !!v.trim()).map(v => v.trim()))]\n if (!domainId || !names.length) return terminologyIssues(rows, [])\n const [{ getRepository }, { Terminology }, { In }] = await Promise.all([import('@things-factory/shell'), import('../service/terminology/terminology'), import('typeorm')])\n const existing = await getRepository(Terminology).find({ where: { domain: { id: domainId }, name: In(names) } as any, select: ['id', 'locale', 'category', 'name'] as any })\n return terminologyIssues(rows, existing)\n },\n\n update: {\n read: {\n query: TERMINOLOGIES,\n variables: ids => ({ filters: [{ name: 'id', operator: 'in', value: ids }], pagination: { page: 1, limit: ids.length } }),\n recordsOf: data => data?.terminologies?.items ?? []\n },\n find: {\n query: TERMINOLOGIES,\n variables: criteria => ({\n filters: ['name', 'category', 'display'].filter(name => typeof criteria?.[name] === 'string' && criteria[name]).map(name => ({ name, operator: 'search', value: criteria[name] })),\n pagination: { page: 1, limit: 200 }\n }),\n recordsOf: (data, criteria) => matching(data?.terminologies?.items ?? [], criteria),\n criteria: [\n { name: 'name', type: 'string', description: 'a piece of the key name' },\n { name: 'category', type: 'string', description: 'the category' },\n { name: 'display', type: 'string', description: 'a piece of the word shown' }\n ]\n },\n mutation: 'mutation ($id: String!, $patch: TerminologyPatch!) { updateTerminology(id: $id, patch: $patch) { id } }',\n variables: ({ id, values }) => ({ id, patch: inputOf(values, FIELDS) }),\n labelOf: record => terminologyLabel(record),\n fields: FIELDS,\n\n /* A (locale, category, name) another term of the domain already has - the record itself excepted. */\n check: async (rows, { state }) => {\n const domainId = state?.domain?.id\n const names = changedNames(rows)\n if (!domainId || !names.length) return terminologyChangeIssues(rows, [])\n const [{ getRepository }, { Terminology }, { In }] = await Promise.all([import('@things-factory/shell'), import('../service/terminology/terminology'), import('typeorm')])\n const existing = await getRepository(Terminology).find({ where: { domain: { id: domainId }, name: In(names) } as any, select: ['id', 'locale', 'category', 'name'] as any })\n return terminologyChangeIssues(rows, existing as any)\n }\n }\n }\n}\n\n/** The i18n AI 입력 targets - the terminology. An application registers it when a mode names its key. */\nexport function terminologyEntryTargets(options: { locales?: string[] } = {}): EntryTargetDeclaration[] {\n return [terminologyEntryTarget(options)]\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/middlewares/index.ts"],"names":[],"mappings":";;AA2BA,0CAQC;;AAnCD,oDAAmB;AACnB,8DAA6B;AAE7B,wEAAsC;AACtC,iDAAsC;AAEtC,iBAAO,CAAC,IAAI,CAAC;IACX,KAAK,EAAE,KAAK;IACZ,EAAE,EAAE,CAAC,cAAc,CAAC;IACpB,SAAS,EAAE,cAAc;IACzB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/middlewares/index.ts"],"names":[],"mappings":";;AA2BA,0CAQC;;AAnCD,oDAAmB;AACnB,8DAA6B;AAE7B,wEAAsC;AACtC,iDAAsC;AAEtC,iBAAO,CAAC,IAAI,CAAC;IACX,KAAK,EAAE,KAAK;IACZ,EAAE,EAAE,CAAC,cAAc,CAAC;IACpB,SAAS,EAAE,cAAc;IACzB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IAC7C,WAAW,EAAE,IAAI;IACjB,aAAa,EAAE;QACb,MAAM,EAAE,GAAG;QACX,MAAM,EAAE,GAAG;KACZ;IACD,IAAI,EAAE,cAAc;IACpB,YAAY,EAAE,KAAK;CACpB,CAAC,CAAA;AAEF,IAAA,oBAAK,EAAC,YAAE,CAAC,CAAA;AAET,OAAO,CAAC,EAAE,CAAC,gBAAuB,EAAE,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE;IAC9C,qEAAqE;IACrE,IAAA,oBAAK,EAAC,EAAE,CAAC,CAAA;AACX,CAAC,CAAC,CAAA;AAEF,SAAgB,eAAe,CAAC,GAAQ;IACtC,GAAG,CAAC,GAAG,CACL,IAAA,qBAAU,EAAC,iBAAO,EAAE;QAClB,YAAY,EAAE,SAAS;QACvB,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAC3B,IAAI,EAAE,IAAI,CAAC,sBAAsB;KAClC,CAAC,CACH,CAAA;AACH,CAAC","sourcesContent":["import fs from 'fs'\nimport i18next from 'i18next'\n\nimport koaI18next from './koa-i18next'\nimport { build } from './translations'\n\ni18next.init({\n debug: false,\n ns: ['translations'],\n defaultNS: 'translations',\n preload: ['ko', 'en', 'ja', 'zh', 'ms', 'es'],\n fallbackLng: 'en',\n interpolation: {\n prefix: '{',\n suffix: '}'\n },\n load: 'languageOnly',\n keySeparator: false\n})\n\nbuild(fs)\n\nprocess.on('client-rebuilt' as any, (app, fs) => {\n /* rebuild once done webpacking assets. only for development mode. */\n build(fs)\n})\n\nexport function initMiddlewares(app: any) {\n app.use(\n koaI18next(i18next, {\n lookupCookie: 'i18next',\n order: ['cookie', 'header'],\n next: true // if koa is version 2\n })\n )\n}\n"]}
|