@fabrika/provider-zerops 0.9.0-dev.1 → 0.9.0-dev.2
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/package.json +15 -14
- package/src/execution.ts +45 -8
- package/types/src/api/client.d.ts +5 -0
- package/types/src/api/errors.d.ts +24 -0
- package/types/src/api/polling.d.ts +41 -0
- package/types/src/api/readers.d.ts +977 -0
- package/types/src/api/service-env-limit.d.ts +17 -0
- package/types/src/api/service-env-response.d.ts +23 -0
- package/types/src/api/types.d.ts +638 -0
- package/types/src/api.d.ts +6 -0
- package/types/src/authoring.d.ts +9 -0
- package/types/src/cli-args.d.ts +19 -0
- package/types/src/cli.d.ts +10 -0
- package/types/src/collaborators.d.ts +18 -0
- package/types/src/compile.d.ts +91 -0
- package/types/src/control.d.ts +41 -0
- package/types/src/database-budget.d.ts +38 -0
- package/types/src/descriptor.d.ts +28 -0
- package/types/src/execution.d.ts +137 -0
- package/types/src/exposure.d.ts +47 -0
- package/types/src/index.d.ts +31 -0
- package/types/src/installation/admin-options.d.ts +24 -0
- package/types/src/installation/admin.d.ts +35 -0
- package/types/src/installation/checker-release.d.ts +12 -0
- package/types/src/installation/deploy-options.d.ts +37 -0
- package/types/src/installation/deploy.d.ts +96 -0
- package/types/src/installation/generated/platform-console-schema.d.ts +2 -0
- package/types/src/installation/generated/platform-proxy-manifest.d.ts +2 -0
- package/types/src/installation/hosts.d.ts +38 -0
- package/types/src/installation/index.d.ts +9 -0
- package/types/src/installation/init-options.d.ts +38 -0
- package/types/src/installation/init.d.ts +60 -0
- package/types/src/installation/install-collaborators.d.ts +24 -0
- package/types/src/installation/install-environment.d.ts +70 -0
- package/types/src/installation/install-options.d.ts +49 -0
- package/types/src/installation/install-project.d.ts +13 -0
- package/types/src/installation/install-provisioning.d.ts +58 -0
- package/types/src/installation/install-secrets.d.ts +30 -0
- package/types/src/installation/install-token.d.ts +10 -0
- package/types/src/installation/install.d.ts +23 -0
- package/types/src/installation/installation-source.d.ts +8 -0
- package/types/src/installation/log.d.ts +44 -0
- package/types/src/installation/machine-key.d.ts +19 -0
- package/types/src/installation/mcp.d.ts +18 -0
- package/types/src/installation/placement-options.d.ts +11 -0
- package/types/src/installation/platform-archive.d.ts +7 -0
- package/types/src/installation/platform-source.d.ts +8 -0
- package/types/src/installation/platform-upload.d.ts +3 -0
- package/types/src/installation/proxy-manifest.d.ts +105 -0
- package/types/src/installation/secrets.d.ts +17 -0
- package/types/src/installation/sidecar.d.ts +51 -0
- package/types/src/installation/source-options.d.ts +1 -0
- package/types/src/installation/topology/artifacts.d.ts +8 -0
- package/types/src/installation/topology/index.d.ts +5 -0
- package/types/src/installation/topology/installation-schemas.d.ts +2242 -0
- package/types/src/installation/topology/invariants.d.ts +23 -0
- package/types/src/installation/topology/setups.d.ts +58 -0
- package/types/src/installation/topology/topology.d.ts +148 -0
- package/types/src/installation/topology/validate.d.ts +11 -0
- package/types/src/installation/upgrade-options.d.ts +26 -0
- package/types/src/installation/upgrade-output.d.ts +6 -0
- package/types/src/installation/upgrade.d.ts +88 -0
- package/types/src/managed-env.d.ts +57 -0
- package/types/src/manifest.d.ts +206 -0
- package/types/src/namespace/claims.d.ts +3 -0
- package/types/src/namespace/codec.d.ts +334 -0
- package/types/src/namespace/constants.d.ts +25 -0
- package/types/src/namespace/errors.d.ts +15 -0
- package/types/src/namespace/manifest.d.ts +4 -0
- package/types/src/namespace/operator.d.ts +12 -0
- package/types/src/namespace/provisioning.d.ts +4 -0
- package/types/src/namespace/proxy-attempt.d.ts +36 -0
- package/types/src/namespace/proxy-reads.d.ts +33 -0
- package/types/src/namespace/proxy-secrets.d.ts +8 -0
- package/types/src/namespace/proxy-source.d.ts +74 -0
- package/types/src/namespace/topology.d.ts +9 -0
- package/types/src/namespace/types.d.ts +99 -0
- package/types/src/namespace/update.d.ts +6 -0
- package/types/src/namespace/validation.d.ts +12 -0
- package/types/src/namespace.d.ts +9 -0
- package/types/src/plan.d.ts +12 -0
- package/types/src/provider.d.ts +65 -0
- package/types/src/proxy-manifest-carrier.d.ts +16 -0
- package/types/src/schema.generated.d.ts +376 -0
- package/types/src/service-names.d.ts +4 -0
- package/types/src/service-references.d.ts +13 -0
- package/types/src/source/constants.d.ts +6 -0
- package/types/src/source/port.d.ts +60 -0
- package/types/src/source/types.d.ts +4 -0
- package/types/src/source/validation.d.ts +19 -0
- package/types/src/source.d.ts +2 -0
- package/types/src/types.d.ts +121 -0
- package/types/src/version-attempt.d.ts +8 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fabrika/provider-zerops",
|
|
3
|
-
"version": "0.9.0-dev.
|
|
3
|
+
"version": "0.9.0-dev.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -12,27 +12,28 @@
|
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
14
|
"src",
|
|
15
|
-
"!src/**/__tests__/**"
|
|
15
|
+
"!src/**/__tests__/**",
|
|
16
|
+
"types"
|
|
16
17
|
],
|
|
17
18
|
"exports": {
|
|
18
19
|
".": {
|
|
19
20
|
"bun": "./src/index.ts",
|
|
20
|
-
"types": "./src/index.ts",
|
|
21
|
+
"types": "./types/src/index.d.ts",
|
|
21
22
|
"default": "./src/index.ts"
|
|
22
23
|
},
|
|
23
24
|
"./cli": {
|
|
24
25
|
"bun": "./src/cli.ts",
|
|
25
|
-
"types": "./src/cli.ts",
|
|
26
|
+
"types": "./types/src/cli.d.ts",
|
|
26
27
|
"default": "./src/cli.ts"
|
|
27
28
|
},
|
|
28
29
|
"./installation": {
|
|
29
30
|
"bun": "./src/installation/index.ts",
|
|
30
|
-
"types": "./src/installation/index.ts",
|
|
31
|
+
"types": "./types/src/installation/index.d.ts",
|
|
31
32
|
"default": "./src/installation/index.ts"
|
|
32
33
|
},
|
|
33
34
|
"./installation/topology": {
|
|
34
35
|
"bun": "./src/installation/topology/index.ts",
|
|
35
|
-
"types": "./src/installation/topology/index.ts",
|
|
36
|
+
"types": "./types/src/installation/topology/index.d.ts",
|
|
36
37
|
"default": "./src/installation/topology/index.ts"
|
|
37
38
|
}
|
|
38
39
|
},
|
|
@@ -43,14 +44,14 @@
|
|
|
43
44
|
},
|
|
44
45
|
"dependencies": {
|
|
45
46
|
"zod": "^3.25.76",
|
|
46
|
-
"@fabrika/auth": "0.9.0-dev.
|
|
47
|
-
"@fabrika/auth-core": "0.9.0-dev.
|
|
48
|
-
"@fabrika/email": "0.9.0-dev.
|
|
49
|
-
"@fabrika/iam-contract": "0.9.0-dev.
|
|
50
|
-
"@fabrika/installation-init": "0.9.0-dev.
|
|
51
|
-
"@fabrika/operations-contract": "0.9.0-dev.
|
|
52
|
-
"@fabrika/provider-contract": "0.9.0-dev.
|
|
53
|
-
"@fabrika/proxy-core": "0.9.0-dev.
|
|
47
|
+
"@fabrika/auth": "0.9.0-dev.2",
|
|
48
|
+
"@fabrika/auth-core": "0.9.0-dev.2",
|
|
49
|
+
"@fabrika/email": "0.9.0-dev.2",
|
|
50
|
+
"@fabrika/iam-contract": "0.9.0-dev.2",
|
|
51
|
+
"@fabrika/installation-init": "0.9.0-dev.2",
|
|
52
|
+
"@fabrika/operations-contract": "0.9.0-dev.2",
|
|
53
|
+
"@fabrika/provider-contract": "0.9.0-dev.2",
|
|
54
|
+
"@fabrika/proxy-core": "0.9.0-dev.2",
|
|
54
55
|
"yaml": "^2.9.1"
|
|
55
56
|
}
|
|
56
57
|
}
|
package/src/execution.ts
CHANGED
|
@@ -265,13 +265,17 @@ const START_SCRIPT = 'fabrika/start.generated.sh'
|
|
|
265
265
|
const DEV_INIT_SCRIPT = 'fabrika/dev-init.generated.sh'
|
|
266
266
|
const PLATFORM_TSCONFIG = 'fabrika/tsconfig.platform.json'
|
|
267
267
|
|
|
268
|
-
/**
|
|
268
|
+
/**
|
|
269
|
+
* The compiler options of the platform's type check; the application's own `tsconfig.json` and its `paths` are not read.
|
|
270
|
+
* It covers the SPA under `web/` too: Bun bundles the SPA without checking its types.
|
|
271
|
+
*/
|
|
269
272
|
const PLATFORM_TSCONFIG_CONTENTS = JSON.stringify({
|
|
270
273
|
compilerOptions: {
|
|
271
274
|
target: 'ES2022',
|
|
272
275
|
module: 'ESNext',
|
|
273
276
|
moduleResolution: 'bundler',
|
|
274
277
|
lib: ['ES2022', 'DOM', 'DOM.Iterable'],
|
|
278
|
+
jsx: 'react-jsx',
|
|
275
279
|
types: ['bun'],
|
|
276
280
|
strict: true,
|
|
277
281
|
noUncheckedIndexedAccess: true,
|
|
@@ -282,7 +286,7 @@ const PLATFORM_TSCONFIG_CONTENTS = JSON.stringify({
|
|
|
282
286
|
isolatedModules: true,
|
|
283
287
|
noEmit: true,
|
|
284
288
|
},
|
|
285
|
-
include: ['../fabrika.contract.ts', '../src', 'entry.generated.ts'],
|
|
289
|
+
include: ['../fabrika.contract.ts', '../src', '../web', 'entry.generated.ts'],
|
|
286
290
|
})
|
|
287
291
|
|
|
288
292
|
/** One `printf` writing `lines` to `path`. Each line is single-quoted, so it may hold neither `'` nor an expansion. */
|
|
@@ -351,11 +355,11 @@ const writeBase64Command = (path: string, content: string): string => {
|
|
|
351
355
|
return `printf '%s' '${encoded}' | base64 -d > ${path}`
|
|
352
356
|
}
|
|
353
357
|
|
|
354
|
-
/** The build's check chain as the dev launcher runs it in the application root
|
|
358
|
+
/** The build's check chain, in its order, as the dev launcher runs it in the application root on what the container holds. */
|
|
355
359
|
const devChecks = (release: string): DevLauncherConfig['checks'] => [
|
|
356
|
-
{ name: 'tests', command:
|
|
357
|
-
{ name: 'fabrika-check', command: `cd /tmp && bun x --bun -p @fabrika/check@${release} fabrika-check ${RUNTIME_ROOT}` },
|
|
360
|
+
{ name: 'tests', command: TESTS_COMMAND },
|
|
358
361
|
{ name: 'tsc', command: `cd /tmp && bun x --bun -p typescript@${PLATFORM_TYPESCRIPT_VERSION} tsc -p ${RUNTIME_ROOT}/${PLATFORM_TSCONFIG}` },
|
|
362
|
+
{ name: 'fabrika-check', command: `cd /tmp && bun x --bun -p @fabrika/check@${release} fabrika-check ${RUNTIME_ROOT}` },
|
|
359
363
|
]
|
|
360
364
|
|
|
361
365
|
/** What the dev launcher reads (`DEV_LAUNCHER_CONFIG_FILE`): the platform's, written after the checks. */
|
|
@@ -394,6 +398,37 @@ const initCommandScripts = (execution: ZeropsLockedExecution): readonly string[]
|
|
|
394
398
|
|
|
395
399
|
const INSTALL = 'bun install --frozen-lockfile --ignore-scripts'
|
|
396
400
|
|
|
401
|
+
/**
|
|
402
|
+
* What `@fabrika/db/testing` prints after the label of a test file it skips without `FABRIKA_TEST_POSTGRES_URL`. Every
|
|
403
|
+
* framework release prints it, so the platform counts it for any application's release.
|
|
404
|
+
*/
|
|
405
|
+
const DATABASE_TEST_SKIP_MARKER = ' skipped: set FABRIKA_TEST_POSTGRES_URL to run the Postgres-backed tests'
|
|
406
|
+
|
|
407
|
+
/** The prefix of the line the tests command prints after the test run. */
|
|
408
|
+
const TESTS_REPORT_PREFIX = 'fabrika-tests:'
|
|
409
|
+
|
|
410
|
+
/** One `bun -e "…"` running `script`, which may hold none of the characters a double-quoted shell word expands. */
|
|
411
|
+
const bunEvalCommand = (script: readonly string[]): string => {
|
|
412
|
+
const source = script.join(' ')
|
|
413
|
+
if (/["$`\\!]/.test(source)) throw new Error('zerops: a generated bun -e script must not contain a quote, an expansion or a backslash')
|
|
414
|
+
return `bun -e "${source}"`
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// The build has no database, so every Postgres-backed test file skips and the run still passes. This command runs the
|
|
418
|
+
// tests as before and then says how many files did not run, so a green test step does not read as a tested database.
|
|
419
|
+
const TESTS_COMMAND = bunEvalCommand([
|
|
420
|
+
"const child = Bun.spawn([process.execPath, 'test', '--isolate', '--pass-with-no-tests'], { stdout: 'inherit', stderr: 'pipe' });",
|
|
421
|
+
'const decoder = new TextDecoder();',
|
|
422
|
+
"let output = '';",
|
|
423
|
+
'for await (const chunk of child.stderr) { process.stderr.write(chunk); output += decoder.decode(chunk, { stream: true }) }',
|
|
424
|
+
'const code = await child.exited;',
|
|
425
|
+
`const marker = '${DATABASE_TEST_SKIP_MARKER}';`,
|
|
426
|
+
'const skipped = output.split(String.fromCharCode(10)).filter((line) => line.includes(marker)).map((line) => line.slice(0, line.indexOf(marker)).trim());',
|
|
427
|
+
`const prefix = '${TESTS_REPORT_PREFIX}';`,
|
|
428
|
+
"console.warn(skipped.length === 0 ? prefix + ' no Postgres-backed test file skipped' : prefix + ' ' + skipped.length + ' Postgres-backed test files did not run, because the build has no database: ' + skipped.join(', '));",
|
|
429
|
+
'process.exit(code);',
|
|
430
|
+
])
|
|
431
|
+
|
|
397
432
|
// After every check: a map is uploaded only for a build that can deploy. A failed upload never fails the build; the
|
|
398
433
|
// provider reads the state from the report line.
|
|
399
434
|
const sourceMapUpload = (release: string): string => `cd /tmp && bun x --bun -p @fabrika/check@${release} fabrika-source-maps ${SOURCE_ROOT} || true`
|
|
@@ -412,19 +447,21 @@ const sourceMapBuildVariables = (upload: OperationsSourceMapBuildUpload): Record
|
|
|
412
447
|
/**
|
|
413
448
|
* The generated build commands, in order; the authored SPA commands run before all of them. The application's tests
|
|
414
449
|
* run first: they are authored code, so everything after them is reinstalled, regenerated or checked again. They run
|
|
415
|
-
* `--isolate`, as the application skill runs them: a test file's DOM globals otherwise leak into the next file.
|
|
450
|
+
* `--isolate`, as the application skill runs them: a test file's DOM globals otherwise leak into the next file. `tsc`
|
|
451
|
+
* runs before the checker, as in the skill's loop: the usual quick fix of a type error is a cast or an `any`, which only
|
|
452
|
+
* the checker refuses, so the checker is the last word on the code.
|
|
416
453
|
*/
|
|
417
454
|
export function generatedBuildCommands(execution: ZeropsLockedExecution, authoredSpa: readonly string[] = []): readonly string[] {
|
|
418
455
|
if (!LOCKED_APP_ID_PATTERN.test(execution.appId)) throw new Error('zerops: a contract application id must match [a-z0-9][a-z0-9-]*')
|
|
419
456
|
if (!FRAMEWORK_RELEASE_PATTERN.test(execution.checkRelease)) throw new Error('zerops: the checker release must be a release version')
|
|
420
457
|
return [
|
|
421
458
|
INSTALL,
|
|
422
|
-
|
|
459
|
+
TESTS_COMMAND,
|
|
423
460
|
`rm -rf node_modules && ${INSTALL}`,
|
|
424
461
|
`bun -e "await import('@fabrika/app/build').then((build) => build.writeGeneratedEntry('.', 'bun'))"`,
|
|
425
|
-
`cd /tmp && bun x --bun -p @fabrika/check@${execution.checkRelease} fabrika-check ${SOURCE_ROOT}`,
|
|
426
462
|
writeFileCommand(PLATFORM_TSCONFIG, [PLATFORM_TSCONFIG_CONTENTS]),
|
|
427
463
|
`cd /tmp && bun x --bun -p typescript@${PLATFORM_TYPESCRIPT_VERSION} tsc -p ${SOURCE_ROOT}/${PLATFORM_TSCONFIG}`,
|
|
464
|
+
`cd /tmp && bun x --bun -p @fabrika/check@${execution.checkRelease} fabrika-check ${SOURCE_ROOT}`,
|
|
428
465
|
...initScripts(execution).map((script) => writeFileCommand(script.path, script.lines)),
|
|
429
466
|
...(execution.dev === undefined
|
|
430
467
|
? [writeFileCommand(START_SCRIPT, startScript)]
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ZeropsApi, ZeropsApiOptions } from './types';
|
|
2
|
+
/** Base URL of the Zerops public REST API. */
|
|
3
|
+
export declare const ZEROPS_API_BASE = "https://api.app-prg1.zerops.io/api/rest/public";
|
|
4
|
+
/** Build the real client. Every request carries the bearer and the run's signal. */
|
|
5
|
+
export declare const createZeropsApi: (options: ZeropsApiOptions) => ZeropsApi;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const isAppVersionNotFoundResponse: (value: unknown) => boolean;
|
|
2
|
+
/**
|
|
3
|
+
* A non-2xx answer from the Zerops API. `code` is the platform's own error identifier, so a caller can
|
|
4
|
+
* branch on `userDataDuplicateKey` rather than matching a prose message.
|
|
5
|
+
*/
|
|
6
|
+
export declare class ZeropsApiError extends Error {
|
|
7
|
+
readonly status: number;
|
|
8
|
+
readonly code: string;
|
|
9
|
+
constructor(message: string, status: number, code: string);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The platform's code for "this service publishes no HTTP port", the answer `enableSubdomainAccess` gives
|
|
13
|
+
* before a service's first deploy. Exported so a caller can say what is missing instead of relaying prose.
|
|
14
|
+
*/
|
|
15
|
+
export declare const ZEROPS_SERVICE_NOT_HTTP = "serviceStackIsNotHttp";
|
|
16
|
+
/**
|
|
17
|
+
* Turn a non-2xx response into a `ZeropsApiError`. Zerops answers with `{ error: { code, message, meta } }`
|
|
18
|
+
* (the envelope observed live; the OpenAPI `Error` schema shows the inner `{ code, message }`).
|
|
19
|
+
*
|
|
20
|
+
* `redactDetail` drops the server's MESSAGE, which a validation error can fill with the value it
|
|
21
|
+
* rejected. The CODE is a fixed identifier and is kept either way — without it nothing downstream can
|
|
22
|
+
* tell a duplicate key from a missing service.
|
|
23
|
+
*/
|
|
24
|
+
export declare const apiError: (label: string, status: number, body: unknown, redactDetail: boolean) => ZeropsApiError;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Sleeper } from '../collaborators';
|
|
2
|
+
import { type ZeropsApi, type ZeropsProcess } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Poll ONE process to completion.
|
|
5
|
+
*
|
|
6
|
+
* The same loop `deployPlatformService` (`installation/deploy.ts`) runs over `/app-version`, run over `/process`
|
|
7
|
+
* instead: read, decide ONLY on a status this build knows to be terminal, sleep, and give up on a deadline
|
|
8
|
+
* of our own rather than on a coincidence. Returns the finished process so a caller can read
|
|
9
|
+
* `actionName`/`appVersionId` off it.
|
|
10
|
+
*
|
|
11
|
+
* Anything outside `ZEROPS_PROCESS_TERMINAL` means "keep waiting", including a status this build has never
|
|
12
|
+
* seen — which is why an unpublished vocabulary (see that constant) can cost a timeout and never a false
|
|
13
|
+
* success. A non-`FINISHED` terminal status throws, naming the status and nothing else.
|
|
14
|
+
*/
|
|
15
|
+
export declare const waitForProcess: (input: {
|
|
16
|
+
api: Pick<ZeropsApi, "getProcess">;
|
|
17
|
+
processId: string;
|
|
18
|
+
sleep: Sleeper;
|
|
19
|
+
signal: AbortSignal;
|
|
20
|
+
/** What to call this process in a failure or timeout message. Defaults to its id. */
|
|
21
|
+
label?: string;
|
|
22
|
+
intervalMs?: number;
|
|
23
|
+
attempts?: number;
|
|
24
|
+
}) => Promise<ZeropsProcess>;
|
|
25
|
+
/**
|
|
26
|
+
* `enableSubdomainAccess`, repeated while the service does not yet publish an HTTP port.
|
|
27
|
+
*
|
|
28
|
+
* Live-verified: right after a service's first app version reads ACTIVE the platform still answers
|
|
29
|
+
* `serviceStackIsNotHttp`, and a minute later the same call is accepted. The ports lag ACTIVE, so that
|
|
30
|
+
* answer means "not yet" for a bounded window. Past it the last refusal is rethrown unchanged, so a caller
|
|
31
|
+
* still names the missing port. Any other failure is rethrown at once. The 2xx still proves nothing: the
|
|
32
|
+
* caller decides by reading `subdomainAccess` back.
|
|
33
|
+
*/
|
|
34
|
+
export declare const enableSubdomainAccessWhenHttp: (input: {
|
|
35
|
+
api: Pick<ZeropsApi, "enableSubdomainAccess">;
|
|
36
|
+
serviceId: string;
|
|
37
|
+
sleep: Sleeper;
|
|
38
|
+
signal: AbortSignal;
|
|
39
|
+
intervalMs?: number;
|
|
40
|
+
attempts?: number;
|
|
41
|
+
}) => Promise<void>;
|