@cat-factory/app 0.160.0 → 0.161.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/app/components/environments/EnvironmentStatusPanel.vue +2 -0
- package/app/components/panels/inspector/ServiceTestConfig.vue +9 -0
- package/app/components/settings/CloudflareHandlerSection.vue +319 -0
- package/app/components/settings/InfraHandlersConfigurator.vue +7 -0
- package/app/composables/useWorkspaceStream.ts +5 -2
- package/app/stores/providerConnections.ts +1 -0
- package/app/utils/apiOrigin.spec.ts +37 -0
- package/app/utils/apiOrigin.ts +30 -0
- package/i18n/locales/de.json +24 -1
- package/i18n/locales/en.json +24 -1
- package/i18n/locales/es.json +24 -1
- package/i18n/locales/fr.json +24 -1
- package/i18n/locales/he.json +24 -1
- package/i18n/locales/it.json +24 -1
- package/i18n/locales/ja.json +24 -1
- package/i18n/locales/pl.json +24 -1
- package/i18n/locales/tr.json +24 -1
- package/i18n/locales/uk.json +24 -1
- package/package.json +2 -2
|
@@ -16,6 +16,7 @@ const { t, d } = useI18n()
|
|
|
16
16
|
const PROVISION_TYPE_KEYS: Record<ProvisionType, string> = {
|
|
17
17
|
kubernetes: 'environments.provisionType.kubernetes',
|
|
18
18
|
'docker-compose': 'environments.provisionType.docker-compose',
|
|
19
|
+
cloudflare: 'environments.provisionType.cloudflare',
|
|
19
20
|
custom: 'environments.provisionType.custom',
|
|
20
21
|
infraless: 'environments.provisionType.infraless',
|
|
21
22
|
}
|
|
@@ -23,6 +24,7 @@ const ENGINE_KEYS: Record<InfraEngine, string> = {
|
|
|
23
24
|
'local-docker': 'environments.engine.local-docker',
|
|
24
25
|
'local-k3s': 'environments.engine.local-k3s',
|
|
25
26
|
'remote-kubernetes': 'environments.engine.remote-kubernetes',
|
|
27
|
+
cloudflare: 'environments.engine.cloudflare',
|
|
26
28
|
'remote-custom': 'environments.engine.remote-custom',
|
|
27
29
|
none: 'environments.engine.none',
|
|
28
30
|
}
|
|
@@ -104,6 +104,7 @@ const PROVISION_TYPES = computed<{ value: ProvisionType; label: string }[]>(() =
|
|
|
104
104
|
{ value: 'infraless', label: t('inspector.testConfig.provisionTypes.infraless') },
|
|
105
105
|
{ value: 'docker-compose', label: t('inspector.testConfig.provisionTypes.docker-compose') },
|
|
106
106
|
{ value: 'kubernetes', label: t('inspector.testConfig.provisionTypes.kubernetes') },
|
|
107
|
+
{ value: 'cloudflare', label: t('inspector.testConfig.provisionTypes.cloudflare') },
|
|
107
108
|
{ value: 'custom', label: t('inspector.testConfig.provisionTypes.custom') },
|
|
108
109
|
])
|
|
109
110
|
|
|
@@ -869,6 +870,14 @@ function setSize(value: InstanceSize) {
|
|
|
869
870
|
</div>
|
|
870
871
|
</div>
|
|
871
872
|
|
|
873
|
+
<!-- cloudflare: nothing to collect. Unlike compose (a path) or kubernetes (a manifest
|
|
874
|
+
source), the per-PR recipe lives in the target repository's own preview workflow, so
|
|
875
|
+
declaring the type IS the whole service-side configuration. Say so explicitly rather
|
|
876
|
+
than rendering an empty panel that reads like something failed to load. -->
|
|
877
|
+
<p v-if="provisionType === 'cloudflare'" class="text-[11px] text-slate-500">
|
|
878
|
+
{{ t('inspector.testConfig.cloudflareHint') }}
|
|
879
|
+
</p>
|
|
880
|
+
|
|
872
881
|
<!-- custom: pin the custom manifest type this service produces (matched to a remote-custom
|
|
873
882
|
handler the workspace configures). -->
|
|
874
883
|
<div v-if="provisionType === 'custom'" class="space-y-2">
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// The `cloudflare` provision type's infra handler (the workspace "how"): the Cloudflare
|
|
3
|
+
// account's workers.dev subdomain, the VCS API token, and the two name templates that are the
|
|
4
|
+
// contract with the target repository's preview workflow.
|
|
5
|
+
//
|
|
6
|
+
// A SELF-CONTAINED section rather than another branch of InfraHandlersConfigurator: that file
|
|
7
|
+
// already carries three provision types at ~600 lines, and a fourth inline would push it well
|
|
8
|
+
// past the point where any single type is findable. It owns its own save/remove/test so the
|
|
9
|
+
// configurator gains exactly one line.
|
|
10
|
+
//
|
|
11
|
+
// There is deliberately no per-user (local-mode) override here, unlike kubernetes: a Cloudflare
|
|
12
|
+
// preview is built by CI and lives in the cloud, so "this machine only" has no meaning for it.
|
|
13
|
+
import { computed, ref, watch } from 'vue'
|
|
14
|
+
import type { InfraHandlerConfig } from '@cat-factory/contracts'
|
|
15
|
+
|
|
16
|
+
type CloudflareHandlerConfig = Extract<InfraHandlerConfig, { engine: 'cloudflare' }>
|
|
17
|
+
type CloudflareConfig = CloudflareHandlerConfig['cloudflare']
|
|
18
|
+
|
|
19
|
+
const { t } = useI18n()
|
|
20
|
+
const infra = useInfraConfigStore()
|
|
21
|
+
const toast = useToast()
|
|
22
|
+
const { confirmAction } = useConfirmAction()
|
|
23
|
+
|
|
24
|
+
const busy = ref(false)
|
|
25
|
+
const testing = ref(false)
|
|
26
|
+
const testResult = ref<{ ok: boolean; message?: string } | null>(null)
|
|
27
|
+
const editing = ref(false)
|
|
28
|
+
|
|
29
|
+
const handler = computed(() => infra.handlerFor('cloudflare') ?? null)
|
|
30
|
+
|
|
31
|
+
// The form state. `label` is prefilled so an operator who fills in only the subdomain still
|
|
32
|
+
// produces a valid config; the two templates are left EMPTY on purpose — blank means "use the
|
|
33
|
+
// reference workflow's naming", and showing the defaults as placeholders rather than values
|
|
34
|
+
// keeps an untouched handler from pinning a shape it never chose.
|
|
35
|
+
const label = ref('Cloudflare Workers preview')
|
|
36
|
+
const workersSubdomain = ref('')
|
|
37
|
+
const repo = ref('')
|
|
38
|
+
const apiBaseUrl = ref('')
|
|
39
|
+
const workerNameTemplate = ref('')
|
|
40
|
+
const environmentNameTemplate = ref('')
|
|
41
|
+
const token = ref('')
|
|
42
|
+
|
|
43
|
+
// Prefill from the saved handler whenever it (re)loads, so re-opening the form edits the
|
|
44
|
+
// stored config instead of silently starting from blank and overwriting it on save. The token
|
|
45
|
+
// is never echoed back by the API, so it stays empty — see `secretsForSave`.
|
|
46
|
+
watch(
|
|
47
|
+
handler,
|
|
48
|
+
(h) => {
|
|
49
|
+
const cfg = (h?.config as CloudflareHandlerConfig | undefined)?.cloudflare
|
|
50
|
+
if (!cfg) return
|
|
51
|
+
label.value = cfg.label
|
|
52
|
+
workersSubdomain.value = cfg.workersSubdomain
|
|
53
|
+
repo.value = cfg.repo ?? ''
|
|
54
|
+
apiBaseUrl.value = cfg.apiBaseUrl ?? ''
|
|
55
|
+
workerNameTemplate.value = cfg.workerNameTemplate ?? ''
|
|
56
|
+
environmentNameTemplate.value = cfg.environmentNameTemplate ?? ''
|
|
57
|
+
},
|
|
58
|
+
{ immediate: true },
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
const canSave = computed(() => workersSubdomain.value.trim() !== '' && label.value.trim() !== '')
|
|
62
|
+
|
|
63
|
+
function buildConfig(): CloudflareHandlerConfig {
|
|
64
|
+
const trimmed = (value: string) => value.trim()
|
|
65
|
+
const cloudflare: CloudflareConfig = {
|
|
66
|
+
label: trimmed(label.value),
|
|
67
|
+
workersSubdomain: trimmed(workersSubdomain.value),
|
|
68
|
+
// Every optional field is OMITTED when blank rather than sent as an empty string: the
|
|
69
|
+
// contract's optionals mean "fall back to the default", and an empty string would fail
|
|
70
|
+
// the schema's own minLength/regex checks instead.
|
|
71
|
+
...(trimmed(repo.value) ? { repo: trimmed(repo.value) } : {}),
|
|
72
|
+
...(trimmed(apiBaseUrl.value) ? { apiBaseUrl: trimmed(apiBaseUrl.value) } : {}),
|
|
73
|
+
...(trimmed(workerNameTemplate.value)
|
|
74
|
+
? { workerNameTemplate: trimmed(workerNameTemplate.value) }
|
|
75
|
+
: {}),
|
|
76
|
+
...(trimmed(environmentNameTemplate.value)
|
|
77
|
+
? { environmentNameTemplate: trimmed(environmentNameTemplate.value) }
|
|
78
|
+
: {}),
|
|
79
|
+
}
|
|
80
|
+
return { engine: 'cloudflare', cloudflare }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* An UNTOUCHED token field on an already-connected handler sends no secret, so the stored one
|
|
85
|
+
* is kept. Sending `''` would clear it and leave the handler unable to authenticate.
|
|
86
|
+
*/
|
|
87
|
+
function secretsForSave(): Record<string, string> {
|
|
88
|
+
const value = token.value.trim()
|
|
89
|
+
return value ? { githubToken: value } : {}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function save() {
|
|
93
|
+
if (!canSave.value) return
|
|
94
|
+
busy.value = true
|
|
95
|
+
try {
|
|
96
|
+
await infra.registerHandler({
|
|
97
|
+
provisionType: 'cloudflare',
|
|
98
|
+
config: buildConfig(),
|
|
99
|
+
secrets: secretsForSave(),
|
|
100
|
+
})
|
|
101
|
+
token.value = ''
|
|
102
|
+
editing.value = false
|
|
103
|
+
toast.add({
|
|
104
|
+
title: t('settings.infrastructure.handler.saved'),
|
|
105
|
+
icon: 'i-lucide-check',
|
|
106
|
+
color: 'success',
|
|
107
|
+
})
|
|
108
|
+
} catch (e) {
|
|
109
|
+
toast.add({
|
|
110
|
+
title: t('settings.infrastructure.handler.saveFailed'),
|
|
111
|
+
description: e instanceof Error ? e.message : String(e),
|
|
112
|
+
icon: 'i-lucide-triangle-alert',
|
|
113
|
+
color: 'error',
|
|
114
|
+
})
|
|
115
|
+
} finally {
|
|
116
|
+
busy.value = false
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async function test() {
|
|
121
|
+
testing.value = true
|
|
122
|
+
testResult.value = null
|
|
123
|
+
try {
|
|
124
|
+
testResult.value = await infra.testHandler({
|
|
125
|
+
config: buildConfig(),
|
|
126
|
+
secrets: secretsForSave(),
|
|
127
|
+
})
|
|
128
|
+
} catch (e) {
|
|
129
|
+
testResult.value = { ok: false, message: e instanceof Error ? e.message : String(e) }
|
|
130
|
+
} finally {
|
|
131
|
+
testing.value = false
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async function remove() {
|
|
136
|
+
if (!(await confirmAction('remove', t('settings.infrastructure.handler.cloudflareNoun')))) return
|
|
137
|
+
busy.value = true
|
|
138
|
+
try {
|
|
139
|
+
await infra.unregisterHandler('cloudflare')
|
|
140
|
+
toast.add({ title: t('settings.infrastructure.handler.removed'), icon: 'i-lucide-check' })
|
|
141
|
+
} catch (e) {
|
|
142
|
+
toast.add({
|
|
143
|
+
title: t('settings.infrastructure.handler.saveFailed'),
|
|
144
|
+
description: e instanceof Error ? e.message : String(e),
|
|
145
|
+
icon: 'i-lucide-triangle-alert',
|
|
146
|
+
color: 'error',
|
|
147
|
+
})
|
|
148
|
+
} finally {
|
|
149
|
+
busy.value = false
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
</script>
|
|
153
|
+
|
|
154
|
+
<template>
|
|
155
|
+
<section class="space-y-2 rounded-lg border border-slate-700 bg-slate-900/40 p-3">
|
|
156
|
+
<h3 class="text-sm font-semibold text-slate-200">
|
|
157
|
+
{{ t('inspector.testConfig.provisionTypes.cloudflare') }}
|
|
158
|
+
</h3>
|
|
159
|
+
<p class="text-[11px] text-slate-400">
|
|
160
|
+
{{ t('settings.infrastructure.cloudflare.intro') }}
|
|
161
|
+
</p>
|
|
162
|
+
|
|
163
|
+
<div
|
|
164
|
+
v-if="handler && !editing"
|
|
165
|
+
class="space-y-2 rounded-md border border-emerald-500/30 bg-emerald-500/5 p-2.5"
|
|
166
|
+
data-testid="cloudflare-handler-connected"
|
|
167
|
+
>
|
|
168
|
+
<div class="flex items-start justify-between gap-2">
|
|
169
|
+
<UCheckbox
|
|
170
|
+
:model-value="true"
|
|
171
|
+
disabled
|
|
172
|
+
size="lg"
|
|
173
|
+
:label="t('settings.infrastructure.handler.connectionEstablished')"
|
|
174
|
+
:ui="{ label: 'text-[13px] font-semibold text-emerald-300' }"
|
|
175
|
+
/>
|
|
176
|
+
<div class="flex items-center gap-1">
|
|
177
|
+
<UButton
|
|
178
|
+
icon="i-lucide-pencil"
|
|
179
|
+
color="neutral"
|
|
180
|
+
variant="ghost"
|
|
181
|
+
size="xs"
|
|
182
|
+
:disabled="busy"
|
|
183
|
+
:aria-label="t('common.edit')"
|
|
184
|
+
@click="editing = true"
|
|
185
|
+
/>
|
|
186
|
+
<UButton
|
|
187
|
+
icon="i-lucide-trash-2"
|
|
188
|
+
color="error"
|
|
189
|
+
variant="ghost"
|
|
190
|
+
size="xs"
|
|
191
|
+
:disabled="busy"
|
|
192
|
+
:aria-label="t('settings.infrastructure.handler.disconnect')"
|
|
193
|
+
@click="remove"
|
|
194
|
+
/>
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
<p class="pl-7 text-[11px] text-slate-300">
|
|
198
|
+
{{ t('settings.infrastructure.cloudflare.connectedAs', { subdomain: workersSubdomain }) }}
|
|
199
|
+
</p>
|
|
200
|
+
</div>
|
|
201
|
+
|
|
202
|
+
<div v-else class="space-y-2" data-testid="cloudflare-handler-form">
|
|
203
|
+
<div class="space-y-1">
|
|
204
|
+
<label class="text-[11px] text-slate-400">{{
|
|
205
|
+
t('settings.infrastructure.cloudflare.label')
|
|
206
|
+
}}</label>
|
|
207
|
+
<UInput v-model="label" size="xs" />
|
|
208
|
+
</div>
|
|
209
|
+
|
|
210
|
+
<div class="space-y-1">
|
|
211
|
+
<label class="text-[11px] text-slate-400">{{
|
|
212
|
+
t('settings.infrastructure.cloudflare.subdomain')
|
|
213
|
+
}}</label>
|
|
214
|
+
<UInput v-model="workersSubdomain" size="xs" placeholder="my-account" />
|
|
215
|
+
<p class="text-[11px] text-slate-500">
|
|
216
|
+
{{ t('settings.infrastructure.cloudflare.subdomainHint') }}
|
|
217
|
+
</p>
|
|
218
|
+
</div>
|
|
219
|
+
|
|
220
|
+
<div class="space-y-1">
|
|
221
|
+
<label class="text-[11px] text-slate-400">{{
|
|
222
|
+
t('settings.infrastructure.cloudflare.token')
|
|
223
|
+
}}</label>
|
|
224
|
+
<UInput
|
|
225
|
+
v-model="token"
|
|
226
|
+
type="password"
|
|
227
|
+
size="xs"
|
|
228
|
+
:placeholder="
|
|
229
|
+
handler
|
|
230
|
+
? t('settings.infrastructure.cloudflare.tokenKeep')
|
|
231
|
+
: t('settings.infrastructure.cloudflare.tokenPlaceholder')
|
|
232
|
+
"
|
|
233
|
+
/>
|
|
234
|
+
<p class="text-[11px] text-slate-500">
|
|
235
|
+
{{ t('settings.infrastructure.cloudflare.tokenHint') }}
|
|
236
|
+
</p>
|
|
237
|
+
</div>
|
|
238
|
+
|
|
239
|
+
<div class="space-y-1">
|
|
240
|
+
<label class="text-[11px] text-slate-400">{{
|
|
241
|
+
t('settings.infrastructure.cloudflare.repo')
|
|
242
|
+
}}</label>
|
|
243
|
+
<UInput v-model="repo" size="xs" placeholder="owner/repo" />
|
|
244
|
+
<p class="text-[11px] text-slate-500">
|
|
245
|
+
{{ t('settings.infrastructure.cloudflare.repoHint') }}
|
|
246
|
+
</p>
|
|
247
|
+
</div>
|
|
248
|
+
|
|
249
|
+
<details class="rounded-md border border-slate-700/70 p-2">
|
|
250
|
+
<summary class="cursor-pointer text-[11px] text-slate-400">
|
|
251
|
+
{{ t('settings.infrastructure.cloudflare.advanced') }}
|
|
252
|
+
</summary>
|
|
253
|
+
<div class="mt-2 space-y-2">
|
|
254
|
+
<div class="space-y-1">
|
|
255
|
+
<label class="text-[11px] text-slate-400">{{
|
|
256
|
+
t('settings.infrastructure.cloudflare.workerTemplate')
|
|
257
|
+
}}</label>
|
|
258
|
+
<!-- The placeholder is a FORMAT EXAMPLE containing vue-i18n metacharacters, so it
|
|
259
|
+
stays inline rather than becoming a catalog key. -->
|
|
260
|
+
<UInput
|
|
261
|
+
v-model="workerNameTemplate"
|
|
262
|
+
size="xs"
|
|
263
|
+
placeholder="cat-factory-pr-{{pullNumber}}"
|
|
264
|
+
/>
|
|
265
|
+
</div>
|
|
266
|
+
<div class="space-y-1">
|
|
267
|
+
<label class="text-[11px] text-slate-400">{{
|
|
268
|
+
t('settings.infrastructure.cloudflare.environmentTemplate')
|
|
269
|
+
}}</label>
|
|
270
|
+
<UInput v-model="environmentNameTemplate" size="xs" placeholder="pr-{{pullNumber}}" />
|
|
271
|
+
</div>
|
|
272
|
+
<p class="text-[11px] text-slate-500">
|
|
273
|
+
{{ t('settings.infrastructure.cloudflare.templateHint') }}
|
|
274
|
+
</p>
|
|
275
|
+
<div class="space-y-1">
|
|
276
|
+
<label class="text-[11px] text-slate-400">{{
|
|
277
|
+
t('settings.infrastructure.cloudflare.apiBaseUrl')
|
|
278
|
+
}}</label>
|
|
279
|
+
<UInput v-model="apiBaseUrl" size="xs" placeholder="https://api.github.com" />
|
|
280
|
+
</div>
|
|
281
|
+
</div>
|
|
282
|
+
</details>
|
|
283
|
+
|
|
284
|
+
<div class="flex items-center gap-2">
|
|
285
|
+
<UButton size="xs" :disabled="!canSave || busy" @click="save">
|
|
286
|
+
{{ t('common.save') }}
|
|
287
|
+
</UButton>
|
|
288
|
+
<UButton
|
|
289
|
+
size="xs"
|
|
290
|
+
color="neutral"
|
|
291
|
+
variant="subtle"
|
|
292
|
+
:disabled="!canSave || testing"
|
|
293
|
+
:loading="testing"
|
|
294
|
+
@click="test"
|
|
295
|
+
>
|
|
296
|
+
{{ t('settings.providerConnection.test.button') }}
|
|
297
|
+
</UButton>
|
|
298
|
+
<UButton
|
|
299
|
+
v-if="handler"
|
|
300
|
+
size="xs"
|
|
301
|
+
color="neutral"
|
|
302
|
+
variant="ghost"
|
|
303
|
+
:disabled="busy"
|
|
304
|
+
@click="editing = false"
|
|
305
|
+
>
|
|
306
|
+
{{ t('common.cancel') }}
|
|
307
|
+
</UButton>
|
|
308
|
+
</div>
|
|
309
|
+
|
|
310
|
+
<p
|
|
311
|
+
v-if="testResult"
|
|
312
|
+
class="text-[11px]"
|
|
313
|
+
:class="testResult.ok ? 'text-emerald-300' : 'text-rose-300'"
|
|
314
|
+
>
|
|
315
|
+
{{ testResult.message }}
|
|
316
|
+
</p>
|
|
317
|
+
</div>
|
|
318
|
+
</section>
|
|
319
|
+
</template>
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
// service-owned, configured on the service).
|
|
7
7
|
// - docker-compose → handled by the runtime's local Docker capability — informational, no
|
|
8
8
|
// connection (a DinD-capable runner stands the service's compose stack up).
|
|
9
|
+
// - cloudflare → the built-in per-PR Cloudflare Workers preview, driven over the VCS
|
|
10
|
+
// deployments API. Its whole section lives in CloudflareHandlerSection.vue.
|
|
9
11
|
// - custom → the custom-manifest-type catalog editor + a `remote-custom` HTTP handler
|
|
10
12
|
// per custom type (matched to a service's pinned `manifestId`).
|
|
11
13
|
// In LOCAL mode each handler additionally offers a per-USER override (this-machine only),
|
|
@@ -25,6 +27,7 @@ type RemoteCustomConfig = Extract<InfraHandlerConfig, { engine: 'remote-custom'
|
|
|
25
27
|
import KubernetesEngineForm from '~/components/settings/KubernetesEngineForm.vue'
|
|
26
28
|
import ProviderManifestEditor from '~/components/settings/ProviderManifestEditor.vue'
|
|
27
29
|
import CustomManifestTypeEditor from '~/components/settings/CustomManifestTypeEditor.vue'
|
|
30
|
+
import CloudflareHandlerSection from '~/components/settings/CloudflareHandlerSection.vue'
|
|
28
31
|
|
|
29
32
|
const { t } = useI18n()
|
|
30
33
|
const infra = useInfraConfigStore()
|
|
@@ -542,6 +545,10 @@ function notifyError(e: unknown) {
|
|
|
542
545
|
<p class="text-[12px] text-slate-400">{{ t('settings.infrastructure.dockerComposeInfo') }}</p>
|
|
543
546
|
</section>
|
|
544
547
|
|
|
548
|
+
<!-- cloudflare: a self-contained section (see the component's own note on why it is not
|
|
549
|
+
another branch here). -->
|
|
550
|
+
<CloudflareHandlerSection />
|
|
551
|
+
|
|
545
552
|
<!-- custom: the catalog editor + a remote-custom HTTP handler per custom type. -->
|
|
546
553
|
<section class="space-y-3 rounded-lg border border-slate-700 bg-slate-900/40 p-3">
|
|
547
554
|
<h3 class="text-sm font-semibold text-slate-200">
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ref, onScopeDispose } from 'vue'
|
|
2
2
|
import type { WorkspaceEvent } from '~/types/domain'
|
|
3
|
+
import { wsOriginFor } from '~/utils/apiOrigin'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Subscribes to the backend's per-workspace WebSocket event stream and keeps the
|
|
@@ -50,8 +51,10 @@ export function useWorkspaceStream() {
|
|
|
50
51
|
let reconnectTimer: ReturnType<typeof setTimeout> | null = null
|
|
51
52
|
let boardDebounce: ReturnType<typeof setTimeout> | null = null
|
|
52
53
|
|
|
53
|
-
// http→ws, https→wss
|
|
54
|
-
|
|
54
|
+
// http→ws, https→wss. `apiBase` is an absolute origin on a split-origin deployment (see
|
|
55
|
+
// nuxt.config.ts) and EMPTY on a same-origin one (one proxy in front of the SPA + the API —
|
|
56
|
+
// the compose preview stack), where the socket origin comes from the page instead.
|
|
57
|
+
const wsBase = wsOriginFor(String(apiBase), import.meta.client ? window.location.origin : '')
|
|
55
58
|
|
|
56
59
|
// A coarse board refresh (the resync on reconnect, and the `board` event fan-out) must not be
|
|
57
60
|
// left silently stale by ONE transient failure: retry a few times with backoff so a blip
|
|
@@ -20,6 +20,7 @@ const BUILTIN_BACKEND_KINDS: Record<ProviderConnectionKind, BackendKindOption[]>
|
|
|
20
20
|
environment: [
|
|
21
21
|
{ kind: 'manifest', label: 'HTTP manifest', engines: ['remote-custom'] },
|
|
22
22
|
{ kind: 'kubernetes', label: 'Kubernetes', engines: ['local-k3s', 'remote-kubernetes'] },
|
|
23
|
+
{ kind: 'cloudflare', label: 'Cloudflare Workers', engines: ['cloudflare'] },
|
|
23
24
|
],
|
|
24
25
|
'runner-pool': [
|
|
25
26
|
{ kind: 'manifest', label: 'HTTP manifest pool' },
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { apiOriginFor, wsOriginFor } from '~/utils/apiOrigin'
|
|
3
|
+
|
|
4
|
+
// The split-origin deployment (an absolute apiBase) and the same-origin one (empty apiBase, one
|
|
5
|
+
// reverse proxy in front of both halves — the compose preview stack) must both produce a usable
|
|
6
|
+
// socket origin. An empty apiBase used to yield a RELATIVE WebSocket URL, which is exactly the
|
|
7
|
+
// case a preview stack hits: its host port is assigned at `up` time, so no absolute origin can be
|
|
8
|
+
// baked into the build.
|
|
9
|
+
|
|
10
|
+
describe('apiOriginFor', () => {
|
|
11
|
+
it('keeps an absolute apiBase (split origins)', () => {
|
|
12
|
+
expect(apiOriginFor('https://api.example.com', 'https://app.example.com')).toBe(
|
|
13
|
+
'https://api.example.com',
|
|
14
|
+
)
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it('falls back to the page origin when apiBase is empty or blank (same origin)', () => {
|
|
18
|
+
expect(apiOriginFor('', 'http://localhost:49153')).toBe('http://localhost:49153')
|
|
19
|
+
expect(apiOriginFor(' ', 'http://localhost:49153')).toBe('http://localhost:49153')
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('is empty when neither is known (SSR — no socket is opened there)', () => {
|
|
23
|
+
expect(apiOriginFor('', '')).toBe('')
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
describe('wsOriginFor', () => {
|
|
28
|
+
it('maps http→ws and https→wss', () => {
|
|
29
|
+
expect(wsOriginFor('http://localhost:8787', '')).toBe('ws://localhost:8787')
|
|
30
|
+
expect(wsOriginFor('https://api.example.com', '')).toBe('wss://api.example.com')
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('derives the socket origin from the page for a same-origin deployment', () => {
|
|
34
|
+
expect(wsOriginFor('', 'https://preview.example.com')).toBe('wss://preview.example.com')
|
|
35
|
+
expect(wsOriginFor('', 'http://localhost:49153')).toBe('ws://localhost:49153')
|
|
36
|
+
})
|
|
37
|
+
})
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where the SPA's API lives, resolved from the build-time `runtimeConfig.public.apiBase`.
|
|
3
|
+
*
|
|
4
|
+
* Two deployment topologies are supported and they differ ONLY here:
|
|
5
|
+
*
|
|
6
|
+
* - **Split origins** (the production Cloudflare/Node deployments): `apiBase` is an absolute
|
|
7
|
+
* origin (`https://api.example.com`), the SPA is served from a different one, and the backend
|
|
8
|
+
* allow-lists the SPA via `CORS_ALLOWED_ORIGINS`.
|
|
9
|
+
* - **Same origin**: `apiBase` is EMPTY and one reverse proxy serves both the static SPA and the
|
|
10
|
+
* API (the compose preview stack in `deploy/preview/compose`). REST calls are then relative and
|
|
11
|
+
* need nothing extra — but the WebSocket URL does, because the socket origin cannot be derived
|
|
12
|
+
* from an empty string. That is what this module exists for: it substitutes the PAGE's origin,
|
|
13
|
+
* so the stream connects to whatever host/port the stack happens to be published on. A preview
|
|
14
|
+
* stack's host port is assigned at `up` time, so it is not knowable when the SPA is built —
|
|
15
|
+
* same-origin is the only topology that works there.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/** The API origin the SPA should talk to: `apiBase` when set, else the page's own origin. */
|
|
19
|
+
export function apiOriginFor(apiBase: string, pageOrigin: string): string {
|
|
20
|
+
return apiBase.trim() || pageOrigin
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The WebSocket origin (`http`→`ws`, `https`→`wss`) for the API. Falls back to `pageOrigin` for
|
|
25
|
+
* the same-origin topology; returns `''` only when neither is known (SSR, where no socket is
|
|
26
|
+
* opened anyway).
|
|
27
|
+
*/
|
|
28
|
+
export function wsOriginFor(apiBase: string, pageOrigin: string): string {
|
|
29
|
+
return apiOriginFor(apiBase, pageOrigin).replace(/^http/, 'ws')
|
|
30
|
+
}
|
package/i18n/locales/de.json
CHANGED
|
@@ -173,7 +173,26 @@
|
|
|
173
173
|
"loading": "Infrastruktureinstellungen werden geladen…",
|
|
174
174
|
"kubeNoun": "der Kubernetes-Handler",
|
|
175
175
|
"kubeOverrideNoun": "der Kubernetes-Override",
|
|
176
|
-
"customNoun": "dieser Handler"
|
|
176
|
+
"customNoun": "dieser Handler",
|
|
177
|
+
"cloudflareNoun": "den Cloudflare-Handler"
|
|
178
|
+
},
|
|
179
|
+
"cloudflare": {
|
|
180
|
+
"intro": "Startet pro Pull Request einen Cloudflare Worker, indem der Preview-Workflow des Ziel-Repositorys angestoßen wird. cat-factory spricht nie direkt mit Cloudflare: Es legt ein Deployment an, liest dessen Status und setzt zum Abbau einen inactive-Status.",
|
|
181
|
+
"label": "Anzeigename",
|
|
182
|
+
"subdomain": "workers.dev-Subdomain",
|
|
183
|
+
"subdomainHint": "Die Preview-URL lautet https://WORKER.SUBDOMAIN.workers.dev — gib nur das Subdomain-Label ein, ohne \".workers.dev\".",
|
|
184
|
+
"token": "VCS-API-Token",
|
|
185
|
+
"tokenPlaceholder": "Fein granuliertes Token einfügen",
|
|
186
|
+
"tokenKeep": "Leer lassen, um das gespeicherte Token zu behalten",
|
|
187
|
+
"tokenHint": "Benötigt \"Deployments: read & write\" für das Repository und sonst nichts.",
|
|
188
|
+
"repo": "Workflow-Repository (optional)",
|
|
189
|
+
"repoHint": "Leer lassen, um das jeweilige Repository des Service-Frames zu verwenden. Nur festlegen, wenn ein Repository den Preview-Workflow für mehrere Services enthält.",
|
|
190
|
+
"advanced": "Erweitert",
|
|
191
|
+
"workerTemplate": "Vorlage für den Worker-Namen",
|
|
192
|
+
"environmentTemplate": "Vorlage für den Deployment-Umgebungsnamen",
|
|
193
|
+
"templateHint": "Diese Werte sind der Vertrag mit dem Preview-Workflow: cat-factory leitet daraus die URL ab, und der Workflow benennt seine Ressourcen genauso. Leer lassen, um die Benennung des Referenz-Workflows zu verwenden. Verfügbare Platzhalter: pullNumber, branch, blockId.",
|
|
194
|
+
"apiBaseUrl": "Basis-URL der VCS-API",
|
|
195
|
+
"connectedAs": "Previews werden auf {subdomain}.workers.dev bereitgestellt."
|
|
177
196
|
}
|
|
178
197
|
},
|
|
179
198
|
"providerConnection": {
|
|
@@ -1100,6 +1119,7 @@
|
|
|
1100
1119
|
"infraless": "Keine Infrastruktur",
|
|
1101
1120
|
"docker-compose": "Docker Compose",
|
|
1102
1121
|
"kubernetes": "Kubernetes",
|
|
1122
|
+
"cloudflare": "Cloudflare Workers-Preview",
|
|
1103
1123
|
"custom": "Benutzerdefiniert"
|
|
1104
1124
|
},
|
|
1105
1125
|
"composePath": "docker-compose-Pfad",
|
|
@@ -1142,6 +1162,7 @@
|
|
|
1142
1162
|
"rendererHint": "Raw wendet die Manifeste unverändert an. Kustomize baut zuerst ein Overlay (benötigt den Container-Deploy-Adapter).",
|
|
1143
1163
|
"customManifestId": "Benutzerdefinierter Manifesttyp",
|
|
1144
1164
|
"customManifestIdPlaceholder": "Wähle einen Manifesttyp",
|
|
1165
|
+
"cloudflareHint": "Hier gibt es nichts zu konfigurieren: Das Rezept pro Pull Request liegt im Preview-Workflow dieses Repositorys. Verbinde unter Infrastruktur einen Cloudflare Workers-Handler, um Konto und Benennung festzulegen.",
|
|
1145
1166
|
"customNoTypes": "Es sind noch keine benutzerdefinierten Manifesttypen definiert. Füge einen im Infrastruktur-Fenster hinzu.",
|
|
1146
1167
|
"customManifestIdHint": "Der benutzerdefinierte Typ, den dieser Service erzeugt, zugeordnet zu einem Remote-Custom-Handler, den der Workspace konfiguriert.",
|
|
1147
1168
|
"customManifestPath": "Manifest-Pfad (optional)",
|
|
@@ -4756,6 +4777,7 @@
|
|
|
4756
4777
|
"provisionType": {
|
|
4757
4778
|
"kubernetes": "Kubernetes",
|
|
4758
4779
|
"docker-compose": "Docker Compose",
|
|
4780
|
+
"cloudflare": "Cloudflare Workers",
|
|
4759
4781
|
"custom": "Benutzerdefiniert",
|
|
4760
4782
|
"infraless": "Keine Infrastruktur"
|
|
4761
4783
|
},
|
|
@@ -4763,6 +4785,7 @@
|
|
|
4763
4785
|
"local-docker": "Lokales Docker",
|
|
4764
4786
|
"local-k3s": "Lokales k3s",
|
|
4765
4787
|
"remote-kubernetes": "Remote-Kubernetes",
|
|
4788
|
+
"cloudflare": "Cloudflare-Preview",
|
|
4766
4789
|
"remote-custom": "Remote benutzerdefiniert (HTTP)",
|
|
4767
4790
|
"none": "Keine"
|
|
4768
4791
|
}
|
package/i18n/locales/en.json
CHANGED
|
@@ -860,6 +860,7 @@
|
|
|
860
860
|
"infraless": "No infrastructure",
|
|
861
861
|
"docker-compose": "Docker Compose",
|
|
862
862
|
"kubernetes": "Kubernetes",
|
|
863
|
+
"cloudflare": "Cloudflare Workers preview",
|
|
863
864
|
"custom": "Custom"
|
|
864
865
|
},
|
|
865
866
|
"composePath": "docker-compose path",
|
|
@@ -902,6 +903,7 @@
|
|
|
902
903
|
"rendererHint": "Raw applies the manifests as-is. Kustomize builds an overlay first (needs the container deploy adapter).",
|
|
903
904
|
"customManifestId": "Custom manifest type",
|
|
904
905
|
"customManifestIdPlaceholder": "Pick a manifest type",
|
|
906
|
+
"cloudflareHint": "Nothing to configure here: the per-pull-request recipe lives in this repository’s own preview workflow. Connect a Cloudflare Workers handler under Infrastructure to choose the account and the naming.",
|
|
905
907
|
"customNoTypes": "No custom manifest types are defined yet. Add one in the Infrastructure window.",
|
|
906
908
|
"customManifestIdHint": "The custom type this service produces, matched to a remote-custom handler the workspace configures.",
|
|
907
909
|
"customManifestPath": "Manifest path (optional)",
|
|
@@ -2256,7 +2258,26 @@
|
|
|
2256
2258
|
"loading": "Loading infrastructure settings…",
|
|
2257
2259
|
"kubeNoun": "the Kubernetes handler",
|
|
2258
2260
|
"kubeOverrideNoun": "the Kubernetes override",
|
|
2259
|
-
"customNoun": "this handler"
|
|
2261
|
+
"customNoun": "this handler",
|
|
2262
|
+
"cloudflareNoun": "the Cloudflare handler"
|
|
2263
|
+
},
|
|
2264
|
+
"cloudflare": {
|
|
2265
|
+
"intro": "Stands up a per-pull-request Cloudflare Worker by driving the target repository's own preview workflow. cat-factory never talks to Cloudflare directly: it creates a deployment, reads its status, and posts an inactive status to tear down.",
|
|
2266
|
+
"label": "Display name",
|
|
2267
|
+
"subdomain": "workers.dev subdomain",
|
|
2268
|
+
"subdomainHint": "The preview URL becomes https://WORKER.SUBDOMAIN.workers.dev — enter just the subdomain label, without \".workers.dev\".",
|
|
2269
|
+
"token": "VCS API token",
|
|
2270
|
+
"tokenPlaceholder": "Paste a fine-grained token",
|
|
2271
|
+
"tokenKeep": "Leave blank to keep the stored token",
|
|
2272
|
+
"tokenHint": "Needs Deployments: read & write on the repository, and nothing else.",
|
|
2273
|
+
"repo": "Workflow repository (optional)",
|
|
2274
|
+
"repoHint": "Leave blank to use each service frame's own repository. Pin it only when one repository holds the preview workflow for several services.",
|
|
2275
|
+
"advanced": "Advanced",
|
|
2276
|
+
"workerTemplate": "Worker name template",
|
|
2277
|
+
"environmentTemplate": "Deployment environment template",
|
|
2278
|
+
"templateHint": "These are the contract with the preview workflow: cat-factory derives the URL from them and the workflow names its resources the same way. Leave blank to use the reference workflow's naming. Available placeholders: pullNumber, branch, blockId.",
|
|
2279
|
+
"apiBaseUrl": "VCS API base URL",
|
|
2280
|
+
"connectedAs": "Previews deploy to {subdomain}.workers.dev."
|
|
2260
2281
|
}
|
|
2261
2282
|
},
|
|
2262
2283
|
"providerConnection": {
|
|
@@ -4599,6 +4620,7 @@
|
|
|
4599
4620
|
"provisionType": {
|
|
4600
4621
|
"kubernetes": "Kubernetes",
|
|
4601
4622
|
"docker-compose": "Docker Compose",
|
|
4623
|
+
"cloudflare": "Cloudflare Workers",
|
|
4602
4624
|
"custom": "Custom",
|
|
4603
4625
|
"infraless": "No infrastructure"
|
|
4604
4626
|
},
|
|
@@ -4606,6 +4628,7 @@
|
|
|
4606
4628
|
"local-docker": "Local Docker",
|
|
4607
4629
|
"local-k3s": "Local k3s",
|
|
4608
4630
|
"remote-kubernetes": "Remote Kubernetes",
|
|
4631
|
+
"cloudflare": "Cloudflare preview",
|
|
4609
4632
|
"remote-custom": "Remote custom (HTTP)",
|
|
4610
4633
|
"none": "None"
|
|
4611
4634
|
}
|
package/i18n/locales/es.json
CHANGED
|
@@ -800,6 +800,7 @@
|
|
|
800
800
|
"infraless": "Sin infraestructura",
|
|
801
801
|
"docker-compose": "Docker Compose",
|
|
802
802
|
"kubernetes": "Kubernetes",
|
|
803
|
+
"cloudflare": "Vista previa de Cloudflare Workers",
|
|
803
804
|
"custom": "Personalizado"
|
|
804
805
|
},
|
|
805
806
|
"composePath": "Ruta de docker-compose",
|
|
@@ -842,6 +843,7 @@
|
|
|
842
843
|
"rendererHint": "Raw aplica los manifiestos tal cual. Kustomize construye primero un overlay (requiere el adaptador de despliegue en contenedor).",
|
|
843
844
|
"customManifestId": "Tipo de manifiesto personalizado",
|
|
844
845
|
"customManifestIdPlaceholder": "Elige un tipo de manifiesto",
|
|
846
|
+
"cloudflareHint": "Aquí no hay nada que configurar: la receta por pull request vive en el flujo de trabajo de vista previa de este repositorio. Conecta un controlador de Cloudflare Workers en Infraestructura para elegir la cuenta y los nombres.",
|
|
845
847
|
"customNoTypes": "Aún no hay tipos de manifiesto personalizados. Añade uno en la ventana de Infraestructura.",
|
|
846
848
|
"customManifestIdHint": "El tipo personalizado que produce este servicio, emparejado con un gestor remote-custom que configura el espacio de trabajo.",
|
|
847
849
|
"customManifestPath": "Ruta del manifiesto (opcional)",
|
|
@@ -2854,7 +2856,26 @@
|
|
|
2854
2856
|
"loading": "Cargando la configuración de infraestructura…",
|
|
2855
2857
|
"kubeNoun": "el controlador de Kubernetes",
|
|
2856
2858
|
"kubeOverrideNoun": "la anulación de Kubernetes",
|
|
2857
|
-
"customNoun": "este controlador"
|
|
2859
|
+
"customNoun": "este controlador",
|
|
2860
|
+
"cloudflareNoun": "el controlador de Cloudflare"
|
|
2861
|
+
},
|
|
2862
|
+
"cloudflare": {
|
|
2863
|
+
"intro": "Levanta un Worker de Cloudflare por cada pull request activando el flujo de trabajo de vista previa del repositorio de destino. cat-factory nunca habla directamente con Cloudflare: crea un despliegue, lee su estado y publica un estado inactive para desmontarlo.",
|
|
2864
|
+
"label": "Nombre visible",
|
|
2865
|
+
"subdomain": "Subdominio de workers.dev",
|
|
2866
|
+
"subdomainHint": "La URL de vista previa será https://WORKER.SUBDOMAIN.workers.dev: introduce solo la etiqueta del subdominio, sin \".workers.dev\".",
|
|
2867
|
+
"token": "Token de la API del VCS",
|
|
2868
|
+
"tokenPlaceholder": "Pega un token de permisos detallados",
|
|
2869
|
+
"tokenKeep": "Déjalo en blanco para conservar el token guardado",
|
|
2870
|
+
"tokenHint": "Necesita \"Deployments: read & write\" en el repositorio, y nada más.",
|
|
2871
|
+
"repo": "Repositorio del flujo de trabajo (opcional)",
|
|
2872
|
+
"repoHint": "Déjalo en blanco para usar el repositorio propio de cada frame de servicio. Fíjalo solo cuando un repositorio contenga el flujo de vista previa de varios servicios.",
|
|
2873
|
+
"advanced": "Avanzado",
|
|
2874
|
+
"workerTemplate": "Plantilla del nombre del Worker",
|
|
2875
|
+
"environmentTemplate": "Plantilla del nombre del entorno de despliegue",
|
|
2876
|
+
"templateHint": "Son el contrato con el flujo de vista previa: cat-factory deriva la URL de ellas y el flujo nombra sus recursos igual. Déjalas en blanco para usar la nomenclatura del flujo de referencia. Marcadores disponibles: pullNumber, branch, blockId.",
|
|
2877
|
+
"apiBaseUrl": "URL base de la API del VCS",
|
|
2878
|
+
"connectedAs": "Las vistas previas se despliegan en {subdomain}.workers.dev."
|
|
2858
2879
|
}
|
|
2859
2880
|
},
|
|
2860
2881
|
"modelPolicy": {
|
|
@@ -4414,6 +4435,7 @@
|
|
|
4414
4435
|
"provisionType": {
|
|
4415
4436
|
"kubernetes": "Kubernetes",
|
|
4416
4437
|
"docker-compose": "Docker Compose",
|
|
4438
|
+
"cloudflare": "Cloudflare Workers",
|
|
4417
4439
|
"custom": "Personalizado",
|
|
4418
4440
|
"infraless": "Sin infraestructura"
|
|
4419
4441
|
},
|
|
@@ -4421,6 +4443,7 @@
|
|
|
4421
4443
|
"local-docker": "Docker local",
|
|
4422
4444
|
"local-k3s": "k3s local",
|
|
4423
4445
|
"remote-kubernetes": "Kubernetes remoto",
|
|
4446
|
+
"cloudflare": "Vista previa de Cloudflare",
|
|
4424
4447
|
"remote-custom": "Personalizado remoto (HTTP)",
|
|
4425
4448
|
"none": "Ninguno"
|
|
4426
4449
|
}
|
package/i18n/locales/fr.json
CHANGED
|
@@ -800,6 +800,7 @@
|
|
|
800
800
|
"infraless": "Aucune infrastructure",
|
|
801
801
|
"docker-compose": "Docker Compose",
|
|
802
802
|
"kubernetes": "Kubernetes",
|
|
803
|
+
"cloudflare": "Aperçu Cloudflare Workers",
|
|
803
804
|
"custom": "Personnalisé"
|
|
804
805
|
},
|
|
805
806
|
"composePath": "Chemin docker-compose",
|
|
@@ -842,6 +843,7 @@
|
|
|
842
843
|
"rendererHint": "Raw applique les manifestes tels quels. Kustomize construit d'abord un overlay (nécessite l'adaptateur de déploiement en conteneur).",
|
|
843
844
|
"customManifestId": "Type de manifeste personnalisé",
|
|
844
845
|
"customManifestIdPlaceholder": "Choisir un type de manifeste",
|
|
846
|
+
"cloudflareHint": "Rien à configurer ici : la recette par pull request se trouve dans le workflow d’aperçu de ce dépôt. Connectez un gestionnaire Cloudflare Workers dans Infrastructure pour choisir le compte et le nommage.",
|
|
845
847
|
"customNoTypes": "Aucun type de manifeste personnalisé n'est encore défini. Ajoutez-en un dans la fenêtre Infrastructure.",
|
|
846
848
|
"customManifestIdHint": "Le type personnalisé que ce service produit, associé à un gestionnaire remote-custom configuré par l'espace de travail.",
|
|
847
849
|
"customManifestPath": "Chemin du manifeste (facultatif)",
|
|
@@ -2854,7 +2856,26 @@
|
|
|
2854
2856
|
"loading": "Chargement de la configuration de l'infrastructure…",
|
|
2855
2857
|
"kubeNoun": "le gestionnaire Kubernetes",
|
|
2856
2858
|
"kubeOverrideNoun": "le remplacement Kubernetes",
|
|
2857
|
-
"customNoun": "ce gestionnaire"
|
|
2859
|
+
"customNoun": "ce gestionnaire",
|
|
2860
|
+
"cloudflareNoun": "le gestionnaire Cloudflare"
|
|
2861
|
+
},
|
|
2862
|
+
"cloudflare": {
|
|
2863
|
+
"intro": "Déploie un Worker Cloudflare par pull request en déclenchant le workflow d’aperçu du dépôt cible. cat-factory ne parle jamais directement à Cloudflare : il crée un déploiement, lit son statut et publie un statut inactive pour le démonter.",
|
|
2864
|
+
"label": "Nom affiché",
|
|
2865
|
+
"subdomain": "Sous-domaine workers.dev",
|
|
2866
|
+
"subdomainHint": "L’URL d’aperçu devient https://WORKER.SUBDOMAIN.workers.dev — saisissez uniquement le libellé du sous-domaine, sans « .workers.dev ».",
|
|
2867
|
+
"token": "Jeton d’API du VCS",
|
|
2868
|
+
"tokenPlaceholder": "Collez un jeton à portée fine",
|
|
2869
|
+
"tokenKeep": "Laissez vide pour conserver le jeton enregistré",
|
|
2870
|
+
"tokenHint": "Nécessite « Deployments : read & write » sur le dépôt, et rien d’autre.",
|
|
2871
|
+
"repo": "Dépôt du workflow (facultatif)",
|
|
2872
|
+
"repoHint": "Laissez vide pour utiliser le dépôt propre à chaque frame de service. Ne le fixez que si un seul dépôt porte le workflow d’aperçu de plusieurs services.",
|
|
2873
|
+
"advanced": "Avancé",
|
|
2874
|
+
"workerTemplate": "Modèle de nom du Worker",
|
|
2875
|
+
"environmentTemplate": "Modèle de nom d’environnement de déploiement",
|
|
2876
|
+
"templateHint": "Ce sont le contrat avec le workflow d’aperçu : cat-factory en dérive l’URL et le workflow nomme ses ressources de la même façon. Laissez vide pour reprendre la nomenclature du workflow de référence. Espaces réservés disponibles : pullNumber, branch, blockId.",
|
|
2877
|
+
"apiBaseUrl": "URL de base de l’API du VCS",
|
|
2878
|
+
"connectedAs": "Les aperçus sont déployés sur {subdomain}.workers.dev."
|
|
2858
2879
|
}
|
|
2859
2880
|
},
|
|
2860
2881
|
"modelPolicy": {
|
|
@@ -4414,6 +4435,7 @@
|
|
|
4414
4435
|
"provisionType": {
|
|
4415
4436
|
"kubernetes": "Kubernetes",
|
|
4416
4437
|
"docker-compose": "Docker Compose",
|
|
4438
|
+
"cloudflare": "Cloudflare Workers",
|
|
4417
4439
|
"custom": "Personnalisé",
|
|
4418
4440
|
"infraless": "Sans infrastructure"
|
|
4419
4441
|
},
|
|
@@ -4421,6 +4443,7 @@
|
|
|
4421
4443
|
"local-docker": "Docker local",
|
|
4422
4444
|
"local-k3s": "k3s local",
|
|
4423
4445
|
"remote-kubernetes": "Kubernetes distant",
|
|
4446
|
+
"cloudflare": "Aperçu Cloudflare",
|
|
4424
4447
|
"remote-custom": "Personnalisé distant (HTTP)",
|
|
4425
4448
|
"none": "Aucun"
|
|
4426
4449
|
}
|
package/i18n/locales/he.json
CHANGED
|
@@ -800,6 +800,7 @@
|
|
|
800
800
|
"infraless": "ללא תשתית",
|
|
801
801
|
"docker-compose": "Docker Compose",
|
|
802
802
|
"kubernetes": "Kubernetes",
|
|
803
|
+
"cloudflare": "תצוגה מקדימה של Cloudflare Workers",
|
|
803
804
|
"custom": "מותאם אישית"
|
|
804
805
|
},
|
|
805
806
|
"composePath": "נתיב docker-compose",
|
|
@@ -842,6 +843,7 @@
|
|
|
842
843
|
"rendererHint": "Raw מחיל את המניפסטים כפי שהם. Kustomize בונה תחילה overlay (דורש את מתאם הפריסה בקונטיינר).",
|
|
843
844
|
"customManifestId": "סוג מניפסט מותאם",
|
|
844
845
|
"customManifestIdPlaceholder": "בחר סוג מניפסט",
|
|
846
|
+
"cloudflareHint": "אין כאן מה להגדיר: המתכון לכל בקשת משיכה נמצא בתהליך העבודה לתצוגה מקדימה של מאגר זה. חבר מטפל של Cloudflare Workers תחת תשתית כדי לבחור את החשבון ואת מוסכמות השמות.",
|
|
845
847
|
"customNoTypes": "עדיין לא הוגדרו סוגי מניפסט מותאמים. הוסף אחד בחלון התשתית.",
|
|
846
848
|
"customManifestIdHint": "הסוג המותאם שהשירות הזה מייצר, המותאם למטפל remote-custom שהמרחב מגדיר.",
|
|
847
849
|
"customManifestPath": "נתיב המניפסט (אופציונלי)",
|
|
@@ -2189,7 +2191,26 @@
|
|
|
2189
2191
|
"loading": "טוען הגדרות תשתית…",
|
|
2190
2192
|
"kubeNoun": "מטפל ה-Kubernetes",
|
|
2191
2193
|
"kubeOverrideNoun": "עקיפת ה-Kubernetes",
|
|
2192
|
-
"customNoun": "מטפל זה"
|
|
2194
|
+
"customNoun": "מטפל זה",
|
|
2195
|
+
"cloudflareNoun": "את מטפל Cloudflare"
|
|
2196
|
+
},
|
|
2197
|
+
"cloudflare": {
|
|
2198
|
+
"intro": "מקים Worker של Cloudflare לכל בקשת משיכה על ידי הפעלת תהליך העבודה לתצוגה מקדימה של המאגר היעד. cat-factory אף פעם לא פונה ישירות ל-Cloudflare: הוא יוצר פריסה, קורא את מצבה, ומפרסם מצב inactive כדי לפרק אותה.",
|
|
2199
|
+
"label": "שם לתצוגה",
|
|
2200
|
+
"subdomain": "תת-דומיין של workers.dev",
|
|
2201
|
+
"subdomainHint": "כתובת התצוגה המקדימה תהיה https://WORKER.SUBDOMAIN.workers.dev — הזן רק את תווית תת-הדומיין, בלי \".workers.dev\".",
|
|
2202
|
+
"token": "אסימון API של מערכת ניהול הגרסאות",
|
|
2203
|
+
"tokenPlaceholder": "הדבק אסימון בעל הרשאות מדויקות",
|
|
2204
|
+
"tokenKeep": "השאר ריק כדי לשמור על האסימון הקיים",
|
|
2205
|
+
"tokenHint": "נדרשת הרשאת \"Deployments: read & write\" על המאגר בלבד.",
|
|
2206
|
+
"repo": "המאגר שמכיל את תהליך העבודה (אופציונלי)",
|
|
2207
|
+
"repoHint": "השאר ריק כדי להשתמש במאגר של כל מסגרת שירות. קבע ערך רק כאשר מאגר אחד מחזיק את תהליך התצוגה המקדימה עבור כמה שירותים.",
|
|
2208
|
+
"advanced": "מתקדם",
|
|
2209
|
+
"workerTemplate": "תבנית לשם ה-Worker",
|
|
2210
|
+
"environmentTemplate": "תבנית לשם סביבת הפריסה",
|
|
2211
|
+
"templateHint": "אלה ההסכם מול תהליך התצוגה המקדימה: cat-factory גוזר מהם את הכתובת, ותהליך העבודה מעניק לאותם משאבים את אותם שמות. השאר ריק כדי להשתמש בשמות של תהליך העבודה הייחוס. מצייני מקום זמינים: pullNumber, branch, blockId.",
|
|
2212
|
+
"apiBaseUrl": "כתובת הבסיס של ה-API של מערכת ניהול הגרסאות",
|
|
2213
|
+
"connectedAs": "תצוגות מקדימות נפרסות אל {subdomain}.workers.dev."
|
|
2193
2214
|
}
|
|
2194
2215
|
},
|
|
2195
2216
|
"providerConnection": {
|
|
@@ -4425,6 +4446,7 @@
|
|
|
4425
4446
|
"provisionType": {
|
|
4426
4447
|
"kubernetes": "Kubernetes",
|
|
4427
4448
|
"docker-compose": "Docker Compose",
|
|
4449
|
+
"cloudflare": "Cloudflare Workers",
|
|
4428
4450
|
"custom": "מותאם",
|
|
4429
4451
|
"infraless": "ללא תשתית"
|
|
4430
4452
|
},
|
|
@@ -4432,6 +4454,7 @@
|
|
|
4432
4454
|
"local-docker": "Docker מקומי",
|
|
4433
4455
|
"local-k3s": "k3s מקומי",
|
|
4434
4456
|
"remote-kubernetes": "Kubernetes מרוחק",
|
|
4457
|
+
"cloudflare": "תצוגה מקדימה של Cloudflare",
|
|
4435
4458
|
"remote-custom": "מותאם מרוחק (HTTP)",
|
|
4436
4459
|
"none": "ללא"
|
|
4437
4460
|
}
|
package/i18n/locales/it.json
CHANGED
|
@@ -173,7 +173,26 @@
|
|
|
173
173
|
"loading": "Caricamento delle impostazioni dell'infrastruttura…",
|
|
174
174
|
"kubeNoun": "l'handler Kubernetes",
|
|
175
175
|
"kubeOverrideNoun": "l'override Kubernetes",
|
|
176
|
-
"customNoun": "questo handler"
|
|
176
|
+
"customNoun": "questo handler",
|
|
177
|
+
"cloudflareNoun": "l’handler Cloudflare"
|
|
178
|
+
},
|
|
179
|
+
"cloudflare": {
|
|
180
|
+
"intro": "Avvia un Worker Cloudflare per ogni pull request attivando il workflow di anteprima del repository di destinazione. cat-factory non parla mai direttamente con Cloudflare: crea un deployment, ne legge lo stato e pubblica uno stato inactive per smantellarlo.",
|
|
181
|
+
"label": "Nome visualizzato",
|
|
182
|
+
"subdomain": "Sottodominio workers.dev",
|
|
183
|
+
"subdomainHint": "L’URL di anteprima diventa https://WORKER.SUBDOMAIN.workers.dev: inserisci solo l’etichetta del sottodominio, senza \".workers.dev\".",
|
|
184
|
+
"token": "Token API del VCS",
|
|
185
|
+
"tokenPlaceholder": "Incolla un token a granularità fine",
|
|
186
|
+
"tokenKeep": "Lascia vuoto per mantenere il token salvato",
|
|
187
|
+
"tokenHint": "Richiede \"Deployments: read & write\" sul repository e nient’altro.",
|
|
188
|
+
"repo": "Repository del workflow (facoltativo)",
|
|
189
|
+
"repoHint": "Lascia vuoto per usare il repository di ciascun frame di servizio. Fissalo solo quando un repository contiene il workflow di anteprima per più servizi.",
|
|
190
|
+
"advanced": "Avanzate",
|
|
191
|
+
"workerTemplate": "Modello del nome del Worker",
|
|
192
|
+
"environmentTemplate": "Modello del nome dell’ambiente di deployment",
|
|
193
|
+
"templateHint": "Sono il contratto con il workflow di anteprima: cat-factory ne ricava l’URL e il workflow nomina le sue risorse allo stesso modo. Lascia vuoto per usare la denominazione del workflow di riferimento. Segnaposto disponibili: pullNumber, branch, blockId.",
|
|
194
|
+
"apiBaseUrl": "URL base dell’API del VCS",
|
|
195
|
+
"connectedAs": "Le anteprime vengono distribuite su {subdomain}.workers.dev."
|
|
177
196
|
}
|
|
178
197
|
},
|
|
179
198
|
"providerConnection": {
|
|
@@ -1100,6 +1119,7 @@
|
|
|
1100
1119
|
"infraless": "Nessuna infrastruttura",
|
|
1101
1120
|
"docker-compose": "Docker Compose",
|
|
1102
1121
|
"kubernetes": "Kubernetes",
|
|
1122
|
+
"cloudflare": "Anteprima Cloudflare Workers",
|
|
1103
1123
|
"custom": "Personalizzato"
|
|
1104
1124
|
},
|
|
1105
1125
|
"composePath": "Percorso docker-compose",
|
|
@@ -1142,6 +1162,7 @@
|
|
|
1142
1162
|
"rendererHint": "Raw applica i manifest cosi' come sono. Kustomize compila prima un overlay (richiede l'adattatore di deploy in container).",
|
|
1143
1163
|
"customManifestId": "Tipo di manifest personalizzato",
|
|
1144
1164
|
"customManifestIdPlaceholder": "Scegli un tipo di manifest",
|
|
1165
|
+
"cloudflareHint": "Qui non c’è nulla da configurare: la ricetta per ogni pull request si trova nel workflow di anteprima di questo repository. Collega un handler Cloudflare Workers in Infrastruttura per scegliere account e denominazione.",
|
|
1145
1166
|
"customNoTypes": "Nessun tipo di manifest personalizzato ancora definito. Aggiungine uno nella finestra Infrastruttura.",
|
|
1146
1167
|
"customManifestIdHint": "Il tipo personalizzato che questo servizio produce, abbinato a un handler remote-custom configurato dal workspace.",
|
|
1147
1168
|
"customManifestPath": "Percorso del manifest (facoltativo)",
|
|
@@ -4756,6 +4777,7 @@
|
|
|
4756
4777
|
"provisionType": {
|
|
4757
4778
|
"kubernetes": "Kubernetes",
|
|
4758
4779
|
"docker-compose": "Docker Compose",
|
|
4780
|
+
"cloudflare": "Cloudflare Workers",
|
|
4759
4781
|
"custom": "Personalizzato",
|
|
4760
4782
|
"infraless": "Nessuna infrastruttura"
|
|
4761
4783
|
},
|
|
@@ -4763,6 +4785,7 @@
|
|
|
4763
4785
|
"local-docker": "Docker locale",
|
|
4764
4786
|
"local-k3s": "k3s locale",
|
|
4765
4787
|
"remote-kubernetes": "Kubernetes remoto",
|
|
4788
|
+
"cloudflare": "Anteprima Cloudflare",
|
|
4766
4789
|
"remote-custom": "Personalizzato remoto (HTTP)",
|
|
4767
4790
|
"none": "Nessuno"
|
|
4768
4791
|
}
|
package/i18n/locales/ja.json
CHANGED
|
@@ -800,6 +800,7 @@
|
|
|
800
800
|
"infraless": "インフラなし",
|
|
801
801
|
"docker-compose": "Docker Compose",
|
|
802
802
|
"kubernetes": "Kubernetes",
|
|
803
|
+
"cloudflare": "Cloudflare Workers プレビュー",
|
|
803
804
|
"custom": "カスタム"
|
|
804
805
|
},
|
|
805
806
|
"composePath": "docker-compose のパス",
|
|
@@ -842,6 +843,7 @@
|
|
|
842
843
|
"rendererHint": "Raw はマニフェストをそのまま適用します。Kustomize はまずオーバーレイをビルドします(コンテナのデプロイアダプターが必要)。",
|
|
843
844
|
"customManifestId": "カスタムマニフェストタイプ",
|
|
844
845
|
"customManifestIdPlaceholder": "マニフェストタイプを選択",
|
|
846
|
+
"cloudflareHint": "ここで設定する項目はありません。プルリクエストごとの手順はこのリポジトリのプレビュー用ワークフローにあります。アカウントと命名を選ぶには、インフラストラクチャで Cloudflare Workers ハンドラーを接続してください。",
|
|
845
847
|
"customNoTypes": "カスタムマニフェストタイプはまだ定義されていません。インフラウィンドウで追加してください。",
|
|
846
848
|
"customManifestIdHint": "このサービスが生成するカスタムタイプ。ワークスペースが構成する remote-custom ハンドラーと照合されます。",
|
|
847
849
|
"customManifestPath": "マニフェストのパス(任意)",
|
|
@@ -2190,7 +2192,26 @@
|
|
|
2190
2192
|
"loading": "インフラ設定を読み込んでいます…",
|
|
2191
2193
|
"kubeNoun": "Kubernetes ハンドラー",
|
|
2192
2194
|
"kubeOverrideNoun": "Kubernetes のオーバーライド",
|
|
2193
|
-
"customNoun": "このハンドラー"
|
|
2195
|
+
"customNoun": "このハンドラー",
|
|
2196
|
+
"cloudflareNoun": "Cloudflare ハンドラー"
|
|
2197
|
+
},
|
|
2198
|
+
"cloudflare": {
|
|
2199
|
+
"intro": "対象リポジトリのプレビュー用ワークフローを起動して、プルリクエストごとに Cloudflare Worker を立ち上げます。cat-factory が Cloudflare と直接やり取りすることはありません。デプロイメントを作成し、その状態を読み取り、破棄時には inactive 状態を書き込みます。",
|
|
2200
|
+
"label": "表示名",
|
|
2201
|
+
"subdomain": "workers.dev サブドメイン",
|
|
2202
|
+
"subdomainHint": "プレビュー URL は https://WORKER.SUBDOMAIN.workers.dev になります。「.workers.dev」を除いたサブドメインのラベルだけを入力してください。",
|
|
2203
|
+
"token": "VCS API トークン",
|
|
2204
|
+
"tokenPlaceholder": "細かい権限のトークンを貼り付けてください",
|
|
2205
|
+
"tokenKeep": "空欄のままにすると保存済みのトークンを保持します",
|
|
2206
|
+
"tokenHint": "リポジトリに対する Deployments の読み取り・書き込み権限のみが必要です。",
|
|
2207
|
+
"repo": "ワークフローのリポジトリ(任意)",
|
|
2208
|
+
"repoHint": "空欄にすると各サービスフレーム自身のリポジトリを使用します。1 つのリポジトリが複数サービスのプレビュー用ワークフローを持つ場合のみ指定してください。",
|
|
2209
|
+
"advanced": "詳細設定",
|
|
2210
|
+
"workerTemplate": "Worker 名のテンプレート",
|
|
2211
|
+
"environmentTemplate": "デプロイメント環境名のテンプレート",
|
|
2212
|
+
"templateHint": "これらはプレビュー用ワークフローとの取り決めです。cat-factory はここから URL を導出し、ワークフローも同じ名前でリソースを作成します。空欄にすると参照ワークフローの命名を使用します。使用できるプレースホルダー: pullNumber、branch、blockId。",
|
|
2213
|
+
"apiBaseUrl": "VCS API のベース URL",
|
|
2214
|
+
"connectedAs": "プレビューは {subdomain}.workers.dev にデプロイされます。"
|
|
2194
2215
|
}
|
|
2195
2216
|
},
|
|
2196
2217
|
"providerConnection": {
|
|
@@ -4426,6 +4447,7 @@
|
|
|
4426
4447
|
"provisionType": {
|
|
4427
4448
|
"kubernetes": "Kubernetes",
|
|
4428
4449
|
"docker-compose": "Docker Compose",
|
|
4450
|
+
"cloudflare": "Cloudflare Workers",
|
|
4429
4451
|
"custom": "カスタム",
|
|
4430
4452
|
"infraless": "インフラなし"
|
|
4431
4453
|
},
|
|
@@ -4433,6 +4455,7 @@
|
|
|
4433
4455
|
"local-docker": "ローカル Docker",
|
|
4434
4456
|
"local-k3s": "ローカル k3s",
|
|
4435
4457
|
"remote-kubernetes": "リモート Kubernetes",
|
|
4458
|
+
"cloudflare": "Cloudflare プレビュー",
|
|
4436
4459
|
"remote-custom": "リモートカスタム (HTTP)",
|
|
4437
4460
|
"none": "なし"
|
|
4438
4461
|
}
|
package/i18n/locales/pl.json
CHANGED
|
@@ -800,6 +800,7 @@
|
|
|
800
800
|
"infraless": "Bez infrastruktury",
|
|
801
801
|
"docker-compose": "Docker Compose",
|
|
802
802
|
"kubernetes": "Kubernetes",
|
|
803
|
+
"cloudflare": "Podgląd Cloudflare Workers",
|
|
803
804
|
"custom": "Niestandardowy"
|
|
804
805
|
},
|
|
805
806
|
"composePath": "Ścieżka docker-compose",
|
|
@@ -842,6 +843,7 @@
|
|
|
842
843
|
"rendererHint": "Raw stosuje manifesty bez zmian. Kustomize najpierw buduje overlay (wymaga kontenerowego adaptera wdrożenia).",
|
|
843
844
|
"customManifestId": "Niestandardowy typ manifestu",
|
|
844
845
|
"customManifestIdPlaceholder": "Wybierz typ manifestu",
|
|
846
|
+
"cloudflareHint": "Nie ma tu nic do skonfigurowania: przepis dla każdego pull requesta znajduje się we własnym workflow podglądu tego repozytorium. Podłącz obsługę Cloudflare Workers w sekcji Infrastruktura, aby wybrać konto i nazewnictwo.",
|
|
845
847
|
"customNoTypes": "Nie zdefiniowano jeszcze niestandardowych typów manifestów. Dodaj jeden w oknie Infrastruktura.",
|
|
846
848
|
"customManifestIdHint": "Niestandardowy typ, który tworzy ta usługa, dopasowany do handlera remote-custom skonfigurowanego przez przestrzeń roboczą.",
|
|
847
849
|
"customManifestPath": "Ścieżka manifestu (opcjonalnie)",
|
|
@@ -2854,7 +2856,26 @@
|
|
|
2854
2856
|
"loading": "Ładowanie ustawień infrastruktury…",
|
|
2855
2857
|
"kubeNoun": "obsługę Kubernetes",
|
|
2856
2858
|
"kubeOverrideNoun": "nadpisanie Kubernetes",
|
|
2857
|
-
"customNoun": "tę obsługę"
|
|
2859
|
+
"customNoun": "tę obsługę",
|
|
2860
|
+
"cloudflareNoun": "obsługę Cloudflare"
|
|
2861
|
+
},
|
|
2862
|
+
"cloudflare": {
|
|
2863
|
+
"intro": "Uruchamia Worker Cloudflare dla każdego pull requesta, wyzwalając workflow podglądu w docelowym repozytorium. cat-factory nigdy nie komunikuje się bezpośrednio z Cloudflare: tworzy wdrożenie, odczytuje jego status i publikuje status inactive, aby je usunąć.",
|
|
2864
|
+
"label": "Nazwa wyświetlana",
|
|
2865
|
+
"subdomain": "Subdomena workers.dev",
|
|
2866
|
+
"subdomainHint": "Adres podglądu to https://WORKER.SUBDOMAIN.workers.dev — wpisz samą etykietę subdomeny, bez „.workers.dev”.",
|
|
2867
|
+
"token": "Token API systemu kontroli wersji",
|
|
2868
|
+
"tokenPlaceholder": "Wklej token o precyzyjnych uprawnieniach",
|
|
2869
|
+
"tokenKeep": "Pozostaw puste, aby zachować zapisany token",
|
|
2870
|
+
"tokenHint": "Wymaga uprawnienia „Deployments: read & write” do repozytorium i niczego więcej.",
|
|
2871
|
+
"repo": "Repozytorium z workflow (opcjonalnie)",
|
|
2872
|
+
"repoHint": "Pozostaw puste, aby użyć własnego repozytorium każdej ramki usługi. Ustaw tylko wtedy, gdy jedno repozytorium zawiera workflow podglądu dla wielu usług.",
|
|
2873
|
+
"advanced": "Zaawansowane",
|
|
2874
|
+
"workerTemplate": "Szablon nazwy Workera",
|
|
2875
|
+
"environmentTemplate": "Szablon nazwy środowiska wdrożenia",
|
|
2876
|
+
"templateHint": "To umowa z workflow podglądu: cat-factory wyprowadza z nich adres URL, a workflow tak samo nazywa swoje zasoby. Pozostaw puste, aby użyć nazewnictwa z workflow referencyjnego. Dostępne symbole: pullNumber, branch, blockId.",
|
|
2877
|
+
"apiBaseUrl": "Bazowy adres URL API systemu kontroli wersji",
|
|
2878
|
+
"connectedAs": "Podglądy są wdrażane pod adresem {subdomain}.workers.dev."
|
|
2858
2879
|
}
|
|
2859
2880
|
},
|
|
2860
2881
|
"modelPolicy": {
|
|
@@ -4414,6 +4435,7 @@
|
|
|
4414
4435
|
"provisionType": {
|
|
4415
4436
|
"kubernetes": "Kubernetes",
|
|
4416
4437
|
"docker-compose": "Docker Compose",
|
|
4438
|
+
"cloudflare": "Cloudflare Workers",
|
|
4417
4439
|
"custom": "Niestandardowy",
|
|
4418
4440
|
"infraless": "Bez infrastruktury"
|
|
4419
4441
|
},
|
|
@@ -4421,6 +4443,7 @@
|
|
|
4421
4443
|
"local-docker": "Lokalny Docker",
|
|
4422
4444
|
"local-k3s": "Lokalny k3s",
|
|
4423
4445
|
"remote-kubernetes": "Zdalny Kubernetes",
|
|
4446
|
+
"cloudflare": "Podgląd Cloudflare",
|
|
4424
4447
|
"remote-custom": "Zdalny niestandardowy (HTTP)",
|
|
4425
4448
|
"none": "Brak"
|
|
4426
4449
|
}
|
package/i18n/locales/tr.json
CHANGED
|
@@ -800,6 +800,7 @@
|
|
|
800
800
|
"infraless": "Altyapısız",
|
|
801
801
|
"docker-compose": "Docker Compose",
|
|
802
802
|
"kubernetes": "Kubernetes",
|
|
803
|
+
"cloudflare": "Cloudflare Workers önizlemesi",
|
|
803
804
|
"custom": "Özel"
|
|
804
805
|
},
|
|
805
806
|
"composePath": "docker-compose yolu",
|
|
@@ -842,6 +843,7 @@
|
|
|
842
843
|
"rendererHint": "Raw manifestleri olduğu gibi uygular. Kustomize önce bir overlay oluşturur (kapsayıcı dağıtım adaptörü gerekir).",
|
|
843
844
|
"customManifestId": "Özel manifest türü",
|
|
844
845
|
"customManifestIdPlaceholder": "Bir manifest türü seçin",
|
|
846
|
+
"cloudflareHint": "Burada yapılandırılacak bir şey yok: her pull request için izlenecek adımlar bu deponun kendi önizleme iş akışında. Hesabı ve adlandırmayı seçmek için Altyapı bölümünden bir Cloudflare Workers işleyicisi bağlayın.",
|
|
845
847
|
"customNoTypes": "Henüz özel manifest türü tanımlanmadı. Altyapı penceresinden bir tane ekleyin.",
|
|
846
848
|
"customManifestIdHint": "Bu servisin ürettiği özel tür; çalışma alanının yapılandırdığı remote-custom işleyiciyle eşleştirilir.",
|
|
847
849
|
"customManifestPath": "Manifest yolu (isteğe bağlı)",
|
|
@@ -2190,7 +2192,26 @@
|
|
|
2190
2192
|
"loading": "Altyapı ayarları yükleniyor…",
|
|
2191
2193
|
"kubeNoun": "Kubernetes işleyicisi",
|
|
2192
2194
|
"kubeOverrideNoun": "Kubernetes geçersiz kılması",
|
|
2193
|
-
"customNoun": "bu işleyici"
|
|
2195
|
+
"customNoun": "bu işleyici",
|
|
2196
|
+
"cloudflareNoun": "Cloudflare işleyicisini"
|
|
2197
|
+
},
|
|
2198
|
+
"cloudflare": {
|
|
2199
|
+
"intro": "Hedef deponun kendi önizleme iş akışını tetikleyerek her pull request için bir Cloudflare Worker ayağa kaldırır. cat-factory Cloudflare ile hiçbir zaman doğrudan konuşmaz: bir dağıtım oluşturur, durumunu okur ve kaldırmak için inactive durumu yazar.",
|
|
2200
|
+
"label": "Görünen ad",
|
|
2201
|
+
"subdomain": "workers.dev alt alan adı",
|
|
2202
|
+
"subdomainHint": "Önizleme adresi https://WORKER.SUBDOMAIN.workers.dev olur — yalnızca alt alan adı etiketini girin, \".workers.dev\" olmadan.",
|
|
2203
|
+
"token": "VCS API belirteci",
|
|
2204
|
+
"tokenPlaceholder": "İnce ayarlı bir belirteç yapıştırın",
|
|
2205
|
+
"tokenKeep": "Kayıtlı belirteci korumak için boş bırakın",
|
|
2206
|
+
"tokenHint": "Depo üzerinde yalnızca \"Deployments: read & write\" yetkisi gerekir.",
|
|
2207
|
+
"repo": "İş akışının bulunduğu depo (isteğe bağlı)",
|
|
2208
|
+
"repoHint": "Her hizmet çerçevesinin kendi deposunu kullanmak için boş bırakın. Yalnızca tek bir depo birden çok hizmetin önizleme iş akışını barındırıyorsa sabitleyin.",
|
|
2209
|
+
"advanced": "Gelişmiş",
|
|
2210
|
+
"workerTemplate": "Worker adı şablonu",
|
|
2211
|
+
"environmentTemplate": "Dağıtım ortamı adı şablonu",
|
|
2212
|
+
"templateHint": "Bunlar önizleme iş akışıyla yapılan anlaşmadır: cat-factory adresi bunlardan türetir ve iş akışı kaynaklarını aynı şekilde adlandırır. Referans iş akışının adlandırmasını kullanmak için boş bırakın. Kullanılabilir yer tutucular: pullNumber, branch, blockId.",
|
|
2213
|
+
"apiBaseUrl": "VCS API taban adresi",
|
|
2214
|
+
"connectedAs": "Önizlemeler {subdomain}.workers.dev üzerine dağıtılır."
|
|
2194
2215
|
}
|
|
2195
2216
|
},
|
|
2196
2217
|
"providerConnection": {
|
|
@@ -4426,6 +4447,7 @@
|
|
|
4426
4447
|
"provisionType": {
|
|
4427
4448
|
"kubernetes": "Kubernetes",
|
|
4428
4449
|
"docker-compose": "Docker Compose",
|
|
4450
|
+
"cloudflare": "Cloudflare Workers",
|
|
4429
4451
|
"custom": "Özel",
|
|
4430
4452
|
"infraless": "Altyapısız"
|
|
4431
4453
|
},
|
|
@@ -4433,6 +4455,7 @@
|
|
|
4433
4455
|
"local-docker": "Yerel Docker",
|
|
4434
4456
|
"local-k3s": "Yerel k3s",
|
|
4435
4457
|
"remote-kubernetes": "Uzak Kubernetes",
|
|
4458
|
+
"cloudflare": "Cloudflare önizlemesi",
|
|
4436
4459
|
"remote-custom": "Uzak özel (HTTP)",
|
|
4437
4460
|
"none": "Yok"
|
|
4438
4461
|
}
|
package/i18n/locales/uk.json
CHANGED
|
@@ -800,6 +800,7 @@
|
|
|
800
800
|
"infraless": "Без інфраструктури",
|
|
801
801
|
"docker-compose": "Docker Compose",
|
|
802
802
|
"kubernetes": "Kubernetes",
|
|
803
|
+
"cloudflare": "Попередній перегляд Cloudflare Workers",
|
|
803
804
|
"custom": "Власний"
|
|
804
805
|
},
|
|
805
806
|
"composePath": "Шлях docker-compose",
|
|
@@ -842,6 +843,7 @@
|
|
|
842
843
|
"rendererHint": "Raw застосовує маніфести як є. Kustomize спершу будує overlay (потрібен контейнерний адаптер розгортання).",
|
|
843
844
|
"customManifestId": "Власний тип маніфесту",
|
|
844
845
|
"customManifestIdPlaceholder": "Виберіть тип маніфесту",
|
|
846
|
+
"cloudflareHint": "Тут нема чого налаштовувати: рецепт для кожного пул-реквесту міститься у власному робочому процесі попереднього перегляду цього репозиторію. Підключіть обробник Cloudflare Workers у розділі «Інфраструктура», щоб обрати обліковий запис і найменування.",
|
|
845
847
|
"customNoTypes": "Власні типи маніфестів ще не визначені. Додайте один у вікні Інфраструктура.",
|
|
846
848
|
"customManifestIdHint": "Власний тип, який створює ця служба, зіставлений з обробником remote-custom, який налаштовує робочий простір.",
|
|
847
849
|
"customManifestPath": "Шлях до маніфесту (необов'язково)",
|
|
@@ -2854,7 +2856,26 @@
|
|
|
2854
2856
|
"loading": "Завантаження налаштувань інфраструктури…",
|
|
2855
2857
|
"kubeNoun": "обробник Kubernetes",
|
|
2856
2858
|
"kubeOverrideNoun": "перевизначення Kubernetes",
|
|
2857
|
-
"customNoun": "цей обробник"
|
|
2859
|
+
"customNoun": "цей обробник",
|
|
2860
|
+
"cloudflareNoun": "обробник Cloudflare"
|
|
2861
|
+
},
|
|
2862
|
+
"cloudflare": {
|
|
2863
|
+
"intro": "Піднімає окремий Cloudflare Worker для кожного пул-реквесту, запускаючи власний робочий процес попереднього перегляду цільового репозиторію. cat-factory ніколи не звертається до Cloudflare напряму: він створює розгортання, читає його статус і публікує статус inactive, щоб його прибрати.",
|
|
2864
|
+
"label": "Відображувана назва",
|
|
2865
|
+
"subdomain": "Субдомен workers.dev",
|
|
2866
|
+
"subdomainHint": "Адреса перегляду буде https://WORKER.SUBDOMAIN.workers.dev — введіть лише мітку субдомену, без «.workers.dev».",
|
|
2867
|
+
"token": "Токен API системи контролю версій",
|
|
2868
|
+
"tokenPlaceholder": "Вставте токен із точними дозволами",
|
|
2869
|
+
"tokenKeep": "Залиште порожнім, щоб зберегти наявний токен",
|
|
2870
|
+
"tokenHint": "Потрібен лише дозвіл «Deployments: read & write» для репозиторію.",
|
|
2871
|
+
"repo": "Репозиторій з робочим процесом (необовʼязково)",
|
|
2872
|
+
"repoHint": "Залиште порожнім, щоб використовувати власний репозиторій кожного фрейму сервісу. Задавайте лише тоді, коли один репозиторій містить робочий процес перегляду для кількох сервісів.",
|
|
2873
|
+
"advanced": "Додатково",
|
|
2874
|
+
"workerTemplate": "Шаблон назви Worker",
|
|
2875
|
+
"environmentTemplate": "Шаблон назви середовища розгортання",
|
|
2876
|
+
"templateHint": "Це домовленість із робочим процесом перегляду: cat-factory виводить із них адресу, а робочий процес так само називає свої ресурси. Залиште порожнім, щоб узяти найменування з еталонного робочого процесу. Доступні підстановки: pullNumber, branch, blockId.",
|
|
2877
|
+
"apiBaseUrl": "Базова адреса API системи контролю версій",
|
|
2878
|
+
"connectedAs": "Перегляди розгортаються на {subdomain}.workers.dev."
|
|
2858
2879
|
}
|
|
2859
2880
|
},
|
|
2860
2881
|
"modelPolicy": {
|
|
@@ -4414,6 +4435,7 @@
|
|
|
4414
4435
|
"provisionType": {
|
|
4415
4436
|
"kubernetes": "Kubernetes",
|
|
4416
4437
|
"docker-compose": "Docker Compose",
|
|
4438
|
+
"cloudflare": "Cloudflare Workers",
|
|
4417
4439
|
"custom": "Власний",
|
|
4418
4440
|
"infraless": "Без інфраструктури"
|
|
4419
4441
|
},
|
|
@@ -4421,6 +4443,7 @@
|
|
|
4421
4443
|
"local-docker": "Локальний Docker",
|
|
4422
4444
|
"local-k3s": "Локальний k3s",
|
|
4423
4445
|
"remote-kubernetes": "Віддалений Kubernetes",
|
|
4446
|
+
"cloudflare": "Попередній перегляд Cloudflare",
|
|
4424
4447
|
"remote-custom": "Віддалений власний (HTTP)",
|
|
4425
4448
|
"none": "Немає"
|
|
4426
4449
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.161.0",
|
|
4
4
|
"description": "Reusable Nuxt layer for the Agent Architecture Board SPA (components, stores, composables, pages). Consume it from a thin deployment app via `extends: ['@cat-factory/app']` and point it at your backend with NUXT_PUBLIC_API_BASE. See deploy/frontend for an example.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"valibot": "^1.4.2",
|
|
41
41
|
"vue": "3.5.40",
|
|
42
42
|
"wretch": "^3.0.9",
|
|
43
|
-
"@cat-factory/contracts": "0.
|
|
43
|
+
"@cat-factory/contracts": "0.175.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@toad-contracts/testing": "0.3.2",
|