@apifuse/provider-sdk 2.2.0-beta.62 → 2.2.0-beta.63
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/AUTHORING.md +268 -9
- package/CHANGELOG.md +4 -0
- package/README.md +1 -0
- package/bin/apifuse-check.ts +84 -2
- package/bin/apifuse-dev.ts +11 -31
- package/bin/apifuse-migrate-deployment.ts +200 -0
- package/bin/apifuse-pack-check.ts +11 -4
- package/bin/apifuse-pack-types.ts +187 -4
- package/bin/apifuse-record.ts +44 -32
- package/bin/apifuse-test.ts +3 -1
- package/dist/cli/commands.d.ts +1 -1
- package/dist/cli/commands.js +11 -0
- package/dist/cli/deployment-intent.d.ts +178 -0
- package/dist/cli/deployment-intent.js +277 -0
- package/dist/cli/migrate-deployment-intent.d.ts +132 -0
- package/dist/cli/migrate-deployment-intent.js +1552 -0
- package/dist/cli/migrate-provider-shape.d.ts +5 -1
- package/dist/cli/migrate-provider-shape.js +4 -2
- package/dist/cli/resolver-runtime.d.ts +21 -0
- package/dist/cli/resolver-runtime.js +31 -0
- package/dist/define.d.ts +3 -0
- package/dist/define.js +5 -0
- package/dist/dev.d.ts +3 -1
- package/dist/dev.js +6 -1
- package/dist/engine.d.ts +35 -1
- package/dist/engine.js +21 -2
- package/dist/error-resolution.d.ts +1 -0
- package/dist/error-resolution.js +54 -0
- package/dist/errors.d.ts +39 -1
- package/dist/errors.js +50 -0
- package/dist/i18n/error-messages.d.ts +86 -0
- package/dist/i18n/error-messages.js +192 -0
- package/dist/i18n/index.d.ts +1 -0
- package/dist/i18n/index.js +1 -0
- package/dist/i18n/keys.d.ts +12 -0
- package/dist/i18n/keys.js +76 -5
- package/dist/index.d.ts +7 -1
- package/dist/index.js +6 -0
- package/dist/lint.d.ts +10 -0
- package/dist/lint.js +412 -49
- package/dist/provider.d.ts +5 -5
- package/dist/provider.js +2 -2
- package/dist/runtime/browser-telemetry-binding.d.ts +5 -0
- package/dist/runtime/browser-telemetry-binding.js +83 -0
- package/dist/runtime/browser-telemetry.d.ts +76 -0
- package/dist/runtime/browser-telemetry.js +165 -0
- package/dist/runtime/browser.d.ts +3 -0
- package/dist/runtime/browser.js +208 -47
- package/dist/runtime/cache-telemetry.d.ts +71 -0
- package/dist/runtime/cache-telemetry.js +177 -0
- package/dist/runtime/cache.js +67 -7
- package/dist/runtime/capability-response.d.ts +3 -0
- package/dist/runtime/capability-response.js +56 -0
- package/dist/runtime/capability-telemetry.d.ts +46 -0
- package/dist/runtime/capability-telemetry.js +68 -0
- package/dist/runtime/diagnostic-env.d.ts +3 -0
- package/dist/runtime/diagnostic-env.js +10 -1
- package/dist/runtime/engine-mode.d.ts +74 -0
- package/dist/runtime/engine-mode.js +152 -0
- package/dist/runtime/http-telemetry-guard.d.ts +10 -0
- package/dist/runtime/http-telemetry-guard.js +62 -10
- package/dist/runtime/http.js +141 -35
- package/dist/runtime/instrumentation.js +92 -13
- package/dist/runtime/ocr-telemetry.d.ts +82 -0
- package/dist/runtime/ocr-telemetry.js +192 -0
- package/dist/runtime/ocr.js +30 -8
- package/dist/runtime/request-telemetry.d.ts +2 -0
- package/dist/runtime/request-telemetry.js +2 -1
- package/dist/runtime/resolver-runtime-options.d.ts +14 -0
- package/dist/runtime/resolver-runtime-options.js +33 -0
- package/dist/runtime/resolver-shared.d.ts +3 -2
- package/dist/runtime/resolver-shared.js +4 -4
- package/dist/runtime/resolver-telemetry.d.ts +1 -0
- package/dist/runtime/resolver-telemetry.js +1 -1
- package/dist/runtime/resolver-vendors/browser.d.ts +2 -0
- package/dist/runtime/resolver-vendors/browser.js +46 -0
- package/dist/runtime/resolver-vendors/hosts.d.ts +21 -0
- package/dist/runtime/resolver-vendors/hosts.js +35 -0
- package/dist/runtime/resolver-vendors/hypersolutions.js +2 -2
- package/dist/runtime/resolver-vendors/types.d.ts +5 -4
- package/dist/runtime/resolver.d.ts +4 -1
- package/dist/runtime/resolver.js +46 -13
- package/dist/runtime/state-telemetry.d.ts +79 -0
- package/dist/runtime/state-telemetry.js +194 -0
- package/dist/runtime/state.d.ts +3 -0
- package/dist/runtime/state.js +26 -7
- package/dist/runtime/stealth-cookies.d.ts +5 -1
- package/dist/runtime/stealth-cookies.js +21 -1
- package/dist/runtime/stealth-owned-headers.d.ts +26 -0
- package/dist/runtime/stealth-owned-headers.js +37 -0
- package/dist/runtime/stealth-telemetry.d.ts +92 -0
- package/dist/runtime/stealth-telemetry.js +179 -0
- package/dist/runtime/stealth.d.ts +4 -1
- package/dist/runtime/stealth.js +228 -85
- package/dist/runtime/stt-telemetry.d.ts +77 -0
- package/dist/runtime/stt-telemetry.js +176 -0
- package/dist/runtime/stt.js +15 -6
- package/dist/server/error-stack-frames.d.ts +35 -0
- package/dist/server/error-stack-frames.js +219 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.js +4 -0
- package/dist/server/sdk-version.d.ts +3 -0
- package/dist/server/sdk-version.js +19 -0
- package/dist/server/self-test.js +1 -18
- package/dist/server/sensitive-values.d.ts +1 -1
- package/dist/server/sensitive-values.js +9 -0
- package/dist/server/serve-implementation.d.ts +51 -2
- package/dist/server/serve-implementation.js +337 -90
- package/dist/server/types.d.ts +1 -0
- package/dist/server/types.js +7 -0
- package/dist/stateful/stateful-provider-owner-forwarder.js +22 -0
- package/dist/stateful/stateful-provider-runtime-context.d.ts +3 -0
- package/dist/stateful/stateful-provider-runtime-context.js +1 -0
- package/dist/types.d.ts +94 -1
- package/package.json +6 -1
- package/src/cli/commands.ts +14 -0
- package/src/cli/deployment-intent.ts +364 -0
- package/src/cli/migrate-deployment-intent.ts +1908 -0
- package/src/cli/migrate-provider-shape.ts +10 -4
- package/src/cli/resolver-runtime.ts +72 -0
- package/src/define.ts +13 -0
- package/src/dev.ts +9 -2
- package/src/engine.ts +38 -2
- package/src/error-resolution.ts +58 -0
- package/src/errors.ts +77 -1
- package/src/i18n/error-messages.ts +255 -0
- package/src/i18n/index.ts +1 -0
- package/src/i18n/keys.ts +80 -6
- package/src/index.ts +72 -0
- package/src/lint.ts +522 -50
- package/src/provider.ts +10 -0
- package/src/runtime/browser-telemetry-binding.ts +92 -0
- package/src/runtime/browser-telemetry.ts +289 -0
- package/src/runtime/browser.ts +249 -65
- package/src/runtime/cache-telemetry.ts +247 -0
- package/src/runtime/cache.ts +68 -17
- package/src/runtime/capability-response.ts +53 -0
- package/src/runtime/capability-telemetry.ts +101 -0
- package/src/runtime/diagnostic-env.ts +11 -1
- package/src/runtime/engine-mode.ts +233 -0
- package/src/runtime/http-telemetry-guard.ts +66 -13
- package/src/runtime/http.ts +168 -37
- package/src/runtime/instrumentation.ts +105 -16
- package/src/runtime/ocr-telemetry.ts +308 -0
- package/src/runtime/ocr.ts +109 -74
- package/src/runtime/request-telemetry.ts +2 -1
- package/src/runtime/resolver-runtime-options.ts +50 -0
- package/src/runtime/resolver-shared.ts +9 -4
- package/src/runtime/resolver-telemetry.ts +1 -1
- package/src/runtime/resolver-vendors/browser.ts +65 -7
- package/src/runtime/resolver-vendors/hosts.ts +43 -0
- package/src/runtime/resolver-vendors/hypersolutions.ts +2 -2
- package/src/runtime/resolver-vendors/types.ts +5 -4
- package/src/runtime/resolver.ts +64 -21
- package/src/runtime/state-telemetry.ts +298 -0
- package/src/runtime/state.ts +46 -45
- package/src/runtime/stealth-cookies.ts +24 -1
- package/src/runtime/stealth-owned-headers.ts +41 -0
- package/src/runtime/stealth-telemetry.ts +304 -0
- package/src/runtime/stealth.ts +355 -150
- package/src/runtime/stt-telemetry.ts +282 -0
- package/src/runtime/stt.ts +93 -71
- package/src/server/error-stack-frames.ts +214 -0
- package/src/server/index.ts +53 -0
- package/src/server/sdk-version.ts +22 -0
- package/src/server/self-test.ts +1 -21
- package/src/server/sensitive-values.ts +14 -0
- package/src/server/serve-implementation.ts +569 -108
- package/src/server/types.ts +7 -0
- package/src/stateful/stateful-provider-owner-forwarder.ts +23 -0
- package/src/stateful/stateful-provider-runtime-context.ts +4 -0
- package/src/types.ts +99 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/approval-override.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/codemod-syntax.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/connection-precedence.ts.txt +0 -10
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-a.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-b.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-barrel.ts.txt +0 -2
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-computed.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-a.ts.txt +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-b.ts.txt +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-barrel.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-catalog.ts.txt +0 -19
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-docs.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-stores.ts.txt +0 -8
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-indirect-config.ts.txt +0 -5
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-nonstatic.ts.txt +0 -4
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-package-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-leaf.ts.txt +0 -10
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-one.ts.txt +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-two.ts.txt +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-one.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-two.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-mixed-index.ts.txt +0 -14
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-registry.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-barrel.ts.txt +0 -2
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-index.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-leaf.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/docs-conflict.ts.txt +0 -8
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-hoisted-array-spread.ts.txt +0 -15
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-imported-array-spread.ts.txt +0 -9
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-kebab-operation-id.ts.txt +0 -17
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-map.ts.txt +0 -5
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-mixed-array-spread.ts.txt +0 -24
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-operation.ts.txt +0 -16
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-snake-operation-id.ts.txt +0 -21
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-duplicate-provider.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-id-unresolved.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-map.ts.txt +0 -3
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-many.ts.txt +0 -18
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-one.ts.txt +0 -13
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoist-all.ts.txt +0 -31
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoisted-const.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/imported-spread.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-map.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-cast-tail.ts.txt +0 -21
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-ekitan.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-override.ts.txt +0 -14
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-en.json +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ja.json +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ko.json +0 -1
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-existing-operation-namespace-en.json +0 -8
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/missing-english-locale.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/no-safety.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/non-literal.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/redundant-approval.ts.txt +0 -6
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-binding-ambiguous.ts.txt +0 -12
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported-other.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported.ts.txt +0 -5
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-key-ambiguous.ts.txt +0 -19
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-shorthand.ts.txt +0 -9
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-typed.ts.txt +0 -11
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-unrelated.ts.txt +0 -13
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/safety-conflict.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/stream.ts.txt +0 -7
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/tool-router-spread.ts.txt +0 -15
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/unparseable.ts.txt +0 -4
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/verbatim-template.ts.txt +0 -12
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ProviderDeploymentOverrides } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Deployment-intent helpers shared by `apifuse check` and
|
|
5
|
+
* `apifuse migrate-deployment`.
|
|
6
|
+
*
|
|
7
|
+
* Deployment intent has exactly one authored home: the optional `deployment`
|
|
8
|
+
* key on `defineProvider()`. The APIFuse registry builder is the only reader;
|
|
9
|
+
* it resolves omitted fields from a runtime profile and rejects anything it
|
|
10
|
+
* cannot resolve. This module mirrors that profile table so the CLI can
|
|
11
|
+
* (a) subtract profile defaults when hoisting a legacy `deploy.ts` into the
|
|
12
|
+
* key and (b) warn when a declared key restates a default. The registry
|
|
13
|
+
* stays canonical — keep the constants below identical to
|
|
14
|
+
* `resolveProviderDeploymentConfig` in `@apifuse/provider-registry`.
|
|
15
|
+
*/
|
|
16
|
+
export type DeploymentRuntime = "shared" | "dedicated" | "browser";
|
|
17
|
+
export type DeploymentLanguage = "typescript" | "python";
|
|
18
|
+
export interface DeploymentResources {
|
|
19
|
+
cpu: string;
|
|
20
|
+
memory: string;
|
|
21
|
+
}
|
|
22
|
+
export interface DeploymentHpa {
|
|
23
|
+
enabled: boolean;
|
|
24
|
+
minReplicas?: number;
|
|
25
|
+
maxReplicas?: number;
|
|
26
|
+
targetCPUUtilizationPercentage?: number;
|
|
27
|
+
}
|
|
28
|
+
/** Fully resolved deployment view: what the platform materializes for a provider. */
|
|
29
|
+
export interface ResolvedDeploymentIntent {
|
|
30
|
+
runtime: DeploymentRuntime;
|
|
31
|
+
language: DeploymentLanguage;
|
|
32
|
+
replicas: number;
|
|
33
|
+
hpa: DeploymentHpa;
|
|
34
|
+
resources: DeploymentResources;
|
|
35
|
+
cache?: {
|
|
36
|
+
redis?: {
|
|
37
|
+
enabled: boolean;
|
|
38
|
+
url?: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
network?: {
|
|
42
|
+
additionalTcpPorts: number[];
|
|
43
|
+
};
|
|
44
|
+
buildContext: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Runtime-profile defaults. `dedicated` carries no resource profile and
|
|
48
|
+
* therefore always needs explicit `resources`.
|
|
49
|
+
*/
|
|
50
|
+
export declare const DEPLOYMENT_PROFILE_DEFAULTS: Readonly<{
|
|
51
|
+
runtime: DeploymentRuntime;
|
|
52
|
+
language: DeploymentLanguage;
|
|
53
|
+
replicas: 1;
|
|
54
|
+
hpa: Readonly<DeploymentHpa>;
|
|
55
|
+
buildContext: ".";
|
|
56
|
+
resources: Readonly<Record<DeploymentRuntime, Readonly<DeploymentResources> | undefined>>;
|
|
57
|
+
}>;
|
|
58
|
+
/**
|
|
59
|
+
* The standalone `deploy.ts` contract (legacy). Mirrors the registry's
|
|
60
|
+
* `ProviderDeploymentConfigSchema`, including its own defaults — note that a
|
|
61
|
+
* legacy file without `hpa` resolved to `{ enabled: false }`, not the
|
|
62
|
+
* profile HPA, so the two default tables are deliberately different.
|
|
63
|
+
*/
|
|
64
|
+
export declare const legacyDeploymentConfigSchema: z.ZodObject<{
|
|
65
|
+
runtime: z.ZodEnum<{
|
|
66
|
+
browser: "browser";
|
|
67
|
+
shared: "shared";
|
|
68
|
+
dedicated: "dedicated";
|
|
69
|
+
}>;
|
|
70
|
+
language: z.ZodEnum<{
|
|
71
|
+
typescript: "typescript";
|
|
72
|
+
python: "python";
|
|
73
|
+
}>;
|
|
74
|
+
replicas: z.ZodDefault<z.ZodNumber>;
|
|
75
|
+
hpa: z.ZodDefault<z.ZodObject<{
|
|
76
|
+
enabled: z.ZodBoolean;
|
|
77
|
+
minReplicas: z.ZodOptional<z.ZodNumber>;
|
|
78
|
+
maxReplicas: z.ZodOptional<z.ZodNumber>;
|
|
79
|
+
targetCPUUtilizationPercentage: z.ZodOptional<z.ZodNumber>;
|
|
80
|
+
}, z.core.$strict>>;
|
|
81
|
+
resources: z.ZodObject<{
|
|
82
|
+
cpu: z.ZodString;
|
|
83
|
+
memory: z.ZodString;
|
|
84
|
+
}, z.core.$strict>;
|
|
85
|
+
cache: z.ZodOptional<z.ZodObject<{
|
|
86
|
+
redis: z.ZodOptional<z.ZodObject<{
|
|
87
|
+
enabled: z.ZodBoolean;
|
|
88
|
+
url: z.ZodOptional<z.ZodString>;
|
|
89
|
+
}, z.core.$strict>>;
|
|
90
|
+
}, z.core.$strict>>;
|
|
91
|
+
network: z.ZodOptional<z.ZodObject<{
|
|
92
|
+
additionalTcpPorts: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
|
|
93
|
+
}, z.core.$strict>>;
|
|
94
|
+
buildContext: z.ZodOptional<z.ZodString & z.ZodType<".", string, z.core.$ZodTypeInternals<".", string>>>;
|
|
95
|
+
}, z.core.$strict>;
|
|
96
|
+
/** The authored `deployment` key: every field optional (registry `ProviderDeploymentOverridesSchema`). */
|
|
97
|
+
export declare const deploymentOverridesSchema: z.ZodObject<{
|
|
98
|
+
runtime: z.ZodOptional<z.ZodEnum<{
|
|
99
|
+
browser: "browser";
|
|
100
|
+
shared: "shared";
|
|
101
|
+
dedicated: "dedicated";
|
|
102
|
+
}>>;
|
|
103
|
+
language: z.ZodOptional<z.ZodEnum<{
|
|
104
|
+
typescript: "typescript";
|
|
105
|
+
python: "python";
|
|
106
|
+
}>>;
|
|
107
|
+
replicas: z.ZodOptional<z.ZodNumber>;
|
|
108
|
+
hpa: z.ZodOptional<z.ZodObject<{
|
|
109
|
+
enabled: z.ZodBoolean;
|
|
110
|
+
minReplicas: z.ZodOptional<z.ZodNumber>;
|
|
111
|
+
maxReplicas: z.ZodOptional<z.ZodNumber>;
|
|
112
|
+
targetCPUUtilizationPercentage: z.ZodOptional<z.ZodNumber>;
|
|
113
|
+
}, z.core.$strict>>;
|
|
114
|
+
resources: z.ZodOptional<z.ZodObject<{
|
|
115
|
+
cpu: z.ZodString;
|
|
116
|
+
memory: z.ZodString;
|
|
117
|
+
}, z.core.$strict>>;
|
|
118
|
+
cache: z.ZodOptional<z.ZodObject<{
|
|
119
|
+
redis: z.ZodOptional<z.ZodObject<{
|
|
120
|
+
enabled: z.ZodBoolean;
|
|
121
|
+
url: z.ZodOptional<z.ZodString>;
|
|
122
|
+
}, z.core.$strict>>;
|
|
123
|
+
}, z.core.$strict>>;
|
|
124
|
+
network: z.ZodOptional<z.ZodObject<{
|
|
125
|
+
additionalTcpPorts: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
|
|
126
|
+
}, z.core.$strict>>;
|
|
127
|
+
buildContext: z.ZodOptional<z.ZodString & z.ZodType<".", string, z.core.$ZodTypeInternals<".", string>>>;
|
|
128
|
+
}, z.core.$strict>;
|
|
129
|
+
export type DeploymentParse<T> = {
|
|
130
|
+
readonly ok: true;
|
|
131
|
+
readonly value: T;
|
|
132
|
+
} | {
|
|
133
|
+
readonly ok: false;
|
|
134
|
+
readonly reason: string;
|
|
135
|
+
};
|
|
136
|
+
/** Parse a legacy `deploy.ts` default export into the resolved view. */
|
|
137
|
+
export declare function normalizeLegacyDeployment(value: unknown): DeploymentParse<ResolvedDeploymentIntent>;
|
|
138
|
+
/** Parse an authored `deployment` key against the strict overrides contract. */
|
|
139
|
+
export declare function parseDeploymentIntent(value: unknown): DeploymentParse<ProviderDeploymentOverrides>;
|
|
140
|
+
/**
|
|
141
|
+
* Resolve an authored key against the runtime profiles, per field;
|
|
142
|
+
* `resources` and `hpa` resolve as whole objects (never deep-merged).
|
|
143
|
+
* Throws when the intent cannot resolve (dedicated runtime without
|
|
144
|
+
* resources, non-default buildContext) — the registry rejects the same.
|
|
145
|
+
*/
|
|
146
|
+
export declare function resolveDeploymentIntent(intent?: ProviderDeploymentOverrides): ResolvedDeploymentIntent;
|
|
147
|
+
/**
|
|
148
|
+
* Two resolved views describe the same deployment when they are deep-equal
|
|
149
|
+
* after dropping empty shells (`network: { additionalTcpPorts: [] }`,
|
|
150
|
+
* `cache: {}`) that carry no intent — the manifests they render are
|
|
151
|
+
* byte-identical.
|
|
152
|
+
*/
|
|
153
|
+
export declare function deploymentIntentsEquivalent(left: ResolvedDeploymentIntent, right: ResolvedDeploymentIntent): boolean;
|
|
154
|
+
export declare function canonicalResolvedDeployment(resolved: ResolvedDeploymentIntent): ResolvedDeploymentIntent;
|
|
155
|
+
/**
|
|
156
|
+
* The smallest `deployment` key that resolves to `resolved`: profile
|
|
157
|
+
* defaults are omitted, `hpa`/`resources` are kept whole when they differ
|
|
158
|
+
* (the resolver never deep-merges them), and empty shells are dropped.
|
|
159
|
+
* Callers prove the result with
|
|
160
|
+
* `deploymentIntentsEquivalent(resolveDeploymentIntent(key), resolved)`.
|
|
161
|
+
*/
|
|
162
|
+
export declare function subtractDeploymentDefaults(resolved: ResolvedDeploymentIntent): ProviderDeploymentOverrides;
|
|
163
|
+
/** Authored order for emitted keys: the registry contract's field order. */
|
|
164
|
+
export declare const DEPLOYMENT_INTENT_FIELD_ORDER: readonly (keyof ProviderDeploymentOverrides)[];
|
|
165
|
+
export interface RedundantDeploymentField {
|
|
166
|
+
/** Dotted path under `deployment`, e.g. `hpa` or `network.additionalTcpPorts`. */
|
|
167
|
+
readonly path: string;
|
|
168
|
+
readonly message: string;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Fields of an authored `deployment` key that restate what the runtime
|
|
172
|
+
* profile already resolves (ADR-0009 "derived values are not re-stated").
|
|
173
|
+
* Accepts an unvalidated value because `apifuse check` inspects the loaded
|
|
174
|
+
* definition, whose key the SDK passes through verbatim.
|
|
175
|
+
*/
|
|
176
|
+
export declare function redundantDeploymentDefaults(intent: unknown): RedundantDeploymentField[];
|
|
177
|
+
/** Structural equality for JSON-shaped values, key order insensitive. */
|
|
178
|
+
export declare function deepEqual(left: unknown, right: unknown): boolean;
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Runtime-profile defaults. `dedicated` carries no resource profile and
|
|
4
|
+
* therefore always needs explicit `resources`.
|
|
5
|
+
*/
|
|
6
|
+
export const DEPLOYMENT_PROFILE_DEFAULTS = Object.freeze({
|
|
7
|
+
runtime: "shared",
|
|
8
|
+
language: "typescript",
|
|
9
|
+
replicas: 1,
|
|
10
|
+
hpa: Object.freeze({
|
|
11
|
+
enabled: true,
|
|
12
|
+
minReplicas: 1,
|
|
13
|
+
maxReplicas: 1,
|
|
14
|
+
targetCPUUtilizationPercentage: 70,
|
|
15
|
+
}),
|
|
16
|
+
buildContext: ".",
|
|
17
|
+
resources: Object.freeze({
|
|
18
|
+
shared: Object.freeze({ cpu: "25m", memory: "128Mi" }),
|
|
19
|
+
browser: Object.freeze({ cpu: "200m", memory: "256Mi" }),
|
|
20
|
+
dedicated: undefined,
|
|
21
|
+
}),
|
|
22
|
+
});
|
|
23
|
+
const BUILD_CONTEXT_CONSTRAINT = 'only "." is accepted; external provider images always build from the materialized checkout root';
|
|
24
|
+
const hpaSchema = z
|
|
25
|
+
.object({
|
|
26
|
+
enabled: z.boolean(),
|
|
27
|
+
minReplicas: z.number().int().positive().optional(),
|
|
28
|
+
maxReplicas: z.number().int().positive().optional(),
|
|
29
|
+
targetCPUUtilizationPercentage: z.number().int().positive().optional(),
|
|
30
|
+
})
|
|
31
|
+
.strict();
|
|
32
|
+
const resourcesSchema = z.object({ cpu: z.string().min(1), memory: z.string().min(1) }).strict();
|
|
33
|
+
const cacheSchema = z
|
|
34
|
+
.object({
|
|
35
|
+
redis: z
|
|
36
|
+
.object({ enabled: z.boolean(), url: z.string().min(1).optional() })
|
|
37
|
+
.strict()
|
|
38
|
+
.optional(),
|
|
39
|
+
})
|
|
40
|
+
.strict();
|
|
41
|
+
const networkSchema = z
|
|
42
|
+
.object({
|
|
43
|
+
additionalTcpPorts: z.array(z.number().int().min(1).max(65535)).default([]),
|
|
44
|
+
})
|
|
45
|
+
.strict();
|
|
46
|
+
const buildContextSchema = z
|
|
47
|
+
.string()
|
|
48
|
+
.min(1)
|
|
49
|
+
.refine((value) => value === ".", { message: BUILD_CONTEXT_CONSTRAINT });
|
|
50
|
+
/**
|
|
51
|
+
* The standalone `deploy.ts` contract (legacy). Mirrors the registry's
|
|
52
|
+
* `ProviderDeploymentConfigSchema`, including its own defaults — note that a
|
|
53
|
+
* legacy file without `hpa` resolved to `{ enabled: false }`, not the
|
|
54
|
+
* profile HPA, so the two default tables are deliberately different.
|
|
55
|
+
*/
|
|
56
|
+
export const legacyDeploymentConfigSchema = z
|
|
57
|
+
.object({
|
|
58
|
+
runtime: z.enum(["shared", "dedicated", "browser"]),
|
|
59
|
+
language: z.enum(["typescript", "python"]),
|
|
60
|
+
replicas: z.number().int().positive().default(1),
|
|
61
|
+
hpa: hpaSchema.default({ enabled: false }),
|
|
62
|
+
resources: resourcesSchema,
|
|
63
|
+
cache: cacheSchema.optional(),
|
|
64
|
+
network: networkSchema.optional(),
|
|
65
|
+
buildContext: buildContextSchema.optional(),
|
|
66
|
+
})
|
|
67
|
+
.strict();
|
|
68
|
+
/** The authored `deployment` key: every field optional (registry `ProviderDeploymentOverridesSchema`). */
|
|
69
|
+
export const deploymentOverridesSchema = z
|
|
70
|
+
.object({
|
|
71
|
+
runtime: z.enum(["shared", "dedicated", "browser"]).optional(),
|
|
72
|
+
language: z.enum(["typescript", "python"]).optional(),
|
|
73
|
+
replicas: z.number().int().positive().optional(),
|
|
74
|
+
hpa: hpaSchema.optional(),
|
|
75
|
+
resources: resourcesSchema.optional(),
|
|
76
|
+
cache: cacheSchema.optional(),
|
|
77
|
+
network: networkSchema.optional(),
|
|
78
|
+
buildContext: buildContextSchema.optional(),
|
|
79
|
+
})
|
|
80
|
+
.strict();
|
|
81
|
+
function formatZodIssues(error) {
|
|
82
|
+
return error.issues
|
|
83
|
+
.map((issue) => {
|
|
84
|
+
const path = issue.path.map(String).join(".");
|
|
85
|
+
return path ? `${path}: ${issue.message}` : issue.message;
|
|
86
|
+
})
|
|
87
|
+
.join("; ");
|
|
88
|
+
}
|
|
89
|
+
/** Parse a legacy `deploy.ts` default export into the resolved view. */
|
|
90
|
+
export function normalizeLegacyDeployment(value) {
|
|
91
|
+
const parsed = legacyDeploymentConfigSchema.safeParse(value);
|
|
92
|
+
if (!parsed.success) {
|
|
93
|
+
return {
|
|
94
|
+
ok: false,
|
|
95
|
+
reason: `deploy.ts is not a valid deployment config: ${formatZodIssues(parsed.error)}`,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
const legacy = parsed.data;
|
|
99
|
+
return {
|
|
100
|
+
ok: true,
|
|
101
|
+
value: {
|
|
102
|
+
runtime: legacy.runtime,
|
|
103
|
+
language: legacy.language,
|
|
104
|
+
replicas: legacy.replicas,
|
|
105
|
+
hpa: legacy.hpa,
|
|
106
|
+
resources: legacy.resources,
|
|
107
|
+
...(legacy.cache ? { cache: legacy.cache } : {}),
|
|
108
|
+
...(legacy.network ? { network: legacy.network } : {}),
|
|
109
|
+
buildContext: legacy.buildContext ?? DEPLOYMENT_PROFILE_DEFAULTS.buildContext,
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/** Parse an authored `deployment` key against the strict overrides contract. */
|
|
114
|
+
export function parseDeploymentIntent(value) {
|
|
115
|
+
const parsed = deploymentOverridesSchema.safeParse(value);
|
|
116
|
+
if (!parsed.success) {
|
|
117
|
+
return { ok: false, reason: `deployment key is invalid: ${formatZodIssues(parsed.error)}` };
|
|
118
|
+
}
|
|
119
|
+
return { ok: true, value: parsed.data };
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Resolve an authored key against the runtime profiles, per field;
|
|
123
|
+
* `resources` and `hpa` resolve as whole objects (never deep-merged).
|
|
124
|
+
* Throws when the intent cannot resolve (dedicated runtime without
|
|
125
|
+
* resources, non-default buildContext) — the registry rejects the same.
|
|
126
|
+
*/
|
|
127
|
+
export function resolveDeploymentIntent(intent = {}) {
|
|
128
|
+
const runtime = intent.runtime ?? DEPLOYMENT_PROFILE_DEFAULTS.runtime;
|
|
129
|
+
const resources = intent.resources ?? DEPLOYMENT_PROFILE_DEFAULTS.resources[runtime];
|
|
130
|
+
if (!resources) {
|
|
131
|
+
throw new Error(`resources: runtime "${runtime}" has no profile default; declare explicit resources { cpu, memory }`);
|
|
132
|
+
}
|
|
133
|
+
if (intent.buildContext !== undefined &&
|
|
134
|
+
intent.buildContext !== DEPLOYMENT_PROFILE_DEFAULTS.buildContext) {
|
|
135
|
+
throw new Error(`buildContext: ${BUILD_CONTEXT_CONSTRAINT}`);
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
runtime,
|
|
139
|
+
language: intent.language ?? DEPLOYMENT_PROFILE_DEFAULTS.language,
|
|
140
|
+
replicas: intent.replicas ?? DEPLOYMENT_PROFILE_DEFAULTS.replicas,
|
|
141
|
+
hpa: intent.hpa ? { ...intent.hpa } : { ...DEPLOYMENT_PROFILE_DEFAULTS.hpa },
|
|
142
|
+
resources: { ...resources },
|
|
143
|
+
...(intent.cache ? { cache: cloneJson(intent.cache) } : {}),
|
|
144
|
+
...(intent.network
|
|
145
|
+
? { network: { additionalTcpPorts: [...(intent.network.additionalTcpPorts ?? [])] } }
|
|
146
|
+
: {}),
|
|
147
|
+
buildContext: intent.buildContext ?? DEPLOYMENT_PROFILE_DEFAULTS.buildContext,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Two resolved views describe the same deployment when they are deep-equal
|
|
152
|
+
* after dropping empty shells (`network: { additionalTcpPorts: [] }`,
|
|
153
|
+
* `cache: {}`) that carry no intent — the manifests they render are
|
|
154
|
+
* byte-identical.
|
|
155
|
+
*/
|
|
156
|
+
export function deploymentIntentsEquivalent(left, right) {
|
|
157
|
+
return deepEqual(canonicalResolvedDeployment(left), canonicalResolvedDeployment(right));
|
|
158
|
+
}
|
|
159
|
+
export function canonicalResolvedDeployment(resolved) {
|
|
160
|
+
const { cache, network, ...rest } = resolved;
|
|
161
|
+
const canonical = { ...rest };
|
|
162
|
+
if (cache?.redis !== undefined)
|
|
163
|
+
canonical.cache = { redis: { ...cache.redis } };
|
|
164
|
+
if (network !== undefined && network.additionalTcpPorts.length > 0) {
|
|
165
|
+
canonical.network = { additionalTcpPorts: [...network.additionalTcpPorts] };
|
|
166
|
+
}
|
|
167
|
+
return canonical;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* The smallest `deployment` key that resolves to `resolved`: profile
|
|
171
|
+
* defaults are omitted, `hpa`/`resources` are kept whole when they differ
|
|
172
|
+
* (the resolver never deep-merges them), and empty shells are dropped.
|
|
173
|
+
* Callers prove the result with
|
|
174
|
+
* `deploymentIntentsEquivalent(resolveDeploymentIntent(key), resolved)`.
|
|
175
|
+
*/
|
|
176
|
+
export function subtractDeploymentDefaults(resolved) {
|
|
177
|
+
const intent = {};
|
|
178
|
+
if (resolved.runtime !== DEPLOYMENT_PROFILE_DEFAULTS.runtime)
|
|
179
|
+
intent.runtime = resolved.runtime;
|
|
180
|
+
if (resolved.language !== DEPLOYMENT_PROFILE_DEFAULTS.language)
|
|
181
|
+
intent.language = resolved.language;
|
|
182
|
+
if (resolved.replicas !== DEPLOYMENT_PROFILE_DEFAULTS.replicas)
|
|
183
|
+
intent.replicas = resolved.replicas;
|
|
184
|
+
if (!deepEqual(resolved.hpa, DEPLOYMENT_PROFILE_DEFAULTS.hpa))
|
|
185
|
+
intent.hpa = { ...resolved.hpa };
|
|
186
|
+
const profileResources = DEPLOYMENT_PROFILE_DEFAULTS.resources[resolved.runtime];
|
|
187
|
+
if (profileResources === undefined || !deepEqual(resolved.resources, profileResources)) {
|
|
188
|
+
intent.resources = { ...resolved.resources };
|
|
189
|
+
}
|
|
190
|
+
if (resolved.cache?.redis !== undefined)
|
|
191
|
+
intent.cache = { redis: { ...resolved.cache.redis } };
|
|
192
|
+
if (resolved.network !== undefined && resolved.network.additionalTcpPorts.length > 0) {
|
|
193
|
+
intent.network = { additionalTcpPorts: [...resolved.network.additionalTcpPorts] };
|
|
194
|
+
}
|
|
195
|
+
// buildContext: "." is the only accepted value, so it is never authored.
|
|
196
|
+
return intent;
|
|
197
|
+
}
|
|
198
|
+
/** Authored order for emitted keys: the registry contract's field order. */
|
|
199
|
+
export const DEPLOYMENT_INTENT_FIELD_ORDER = [
|
|
200
|
+
"runtime",
|
|
201
|
+
"language",
|
|
202
|
+
"replicas",
|
|
203
|
+
"hpa",
|
|
204
|
+
"resources",
|
|
205
|
+
"cache",
|
|
206
|
+
"network",
|
|
207
|
+
"buildContext",
|
|
208
|
+
];
|
|
209
|
+
/**
|
|
210
|
+
* Fields of an authored `deployment` key that restate what the runtime
|
|
211
|
+
* profile already resolves (ADR-0009 "derived values are not re-stated").
|
|
212
|
+
* Accepts an unvalidated value because `apifuse check` inspects the loaded
|
|
213
|
+
* definition, whose key the SDK passes through verbatim.
|
|
214
|
+
*/
|
|
215
|
+
export function redundantDeploymentDefaults(intent) {
|
|
216
|
+
if (!isRecord(intent))
|
|
217
|
+
return [];
|
|
218
|
+
const redundant = [];
|
|
219
|
+
const flag = (path, detail) => {
|
|
220
|
+
redundant.push({ path, message: `deployment.${path} ${detail}; omit it` });
|
|
221
|
+
};
|
|
222
|
+
if (intent.runtime === DEPLOYMENT_PROFILE_DEFAULTS.runtime) {
|
|
223
|
+
flag("runtime", `restates the profile default ("${DEPLOYMENT_PROFILE_DEFAULTS.runtime}")`);
|
|
224
|
+
}
|
|
225
|
+
if (intent.language === DEPLOYMENT_PROFILE_DEFAULTS.language) {
|
|
226
|
+
flag("language", `restates the profile default ("${DEPLOYMENT_PROFILE_DEFAULTS.language}")`);
|
|
227
|
+
}
|
|
228
|
+
if (intent.replicas === DEPLOYMENT_PROFILE_DEFAULTS.replicas) {
|
|
229
|
+
flag("replicas", `restates the profile default (${DEPLOYMENT_PROFILE_DEFAULTS.replicas})`);
|
|
230
|
+
}
|
|
231
|
+
if (deepEqual(intent.hpa, DEPLOYMENT_PROFILE_DEFAULTS.hpa)) {
|
|
232
|
+
flag("hpa", "restates the profile default (enabled, 1-1 replicas, 70% CPU target)");
|
|
233
|
+
}
|
|
234
|
+
const runtime = typeof intent.runtime === "string" && intent.runtime in DEPLOYMENT_PROFILE_DEFAULTS.resources
|
|
235
|
+
? intent.runtime
|
|
236
|
+
: DEPLOYMENT_PROFILE_DEFAULTS.runtime;
|
|
237
|
+
const profileResources = DEPLOYMENT_PROFILE_DEFAULTS.resources[runtime];
|
|
238
|
+
if (profileResources !== undefined && deepEqual(intent.resources, profileResources)) {
|
|
239
|
+
flag("resources", `restates the "${runtime}" profile default (${profileResources.cpu}/${profileResources.memory})`);
|
|
240
|
+
}
|
|
241
|
+
if (intent.buildContext === DEPLOYMENT_PROFILE_DEFAULTS.buildContext) {
|
|
242
|
+
flag("buildContext", 'restates the only accepted value (".")');
|
|
243
|
+
}
|
|
244
|
+
if (isRecord(intent.network)) {
|
|
245
|
+
const ports = intent.network.additionalTcpPorts;
|
|
246
|
+
if (ports === undefined || (Array.isArray(ports) && ports.length === 0)) {
|
|
247
|
+
flag("network", "declares no additional TCP ports (empty shell)");
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (isRecord(intent.cache) && intent.cache.redis === undefined) {
|
|
251
|
+
flag("cache", "declares no redis intent (empty shell)");
|
|
252
|
+
}
|
|
253
|
+
return redundant;
|
|
254
|
+
}
|
|
255
|
+
/** Structural equality for JSON-shaped values, key order insensitive. */
|
|
256
|
+
export function deepEqual(left, right) {
|
|
257
|
+
if (left === right)
|
|
258
|
+
return true;
|
|
259
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
260
|
+
if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length)
|
|
261
|
+
return false;
|
|
262
|
+
return left.every((item, index) => deepEqual(item, right[index]));
|
|
263
|
+
}
|
|
264
|
+
if (!isRecord(left) || !isRecord(right))
|
|
265
|
+
return false;
|
|
266
|
+
const leftKeys = Object.keys(left).filter((key) => left[key] !== undefined);
|
|
267
|
+
const rightKeys = Object.keys(right).filter((key) => right[key] !== undefined);
|
|
268
|
+
if (leftKeys.length !== rightKeys.length)
|
|
269
|
+
return false;
|
|
270
|
+
return leftKeys.every((key) => Object.hasOwn(right, key) && deepEqual(left[key], right[key]));
|
|
271
|
+
}
|
|
272
|
+
function isRecord(value) {
|
|
273
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
274
|
+
}
|
|
275
|
+
function cloneJson(value) {
|
|
276
|
+
return JSON.parse(JSON.stringify(value));
|
|
277
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type { ProviderDeploymentOverrides } from "../types.js";
|
|
2
|
+
import { type ResolvedDeploymentIntent } from "./deployment-intent.js";
|
|
3
|
+
export declare const TYPESCRIPT_REQUIRED_MESSAGE = "apifuse migrate-deployment requires typescript; install it in the workspace running the CLI (bun add -d typescript)";
|
|
4
|
+
/**
|
|
5
|
+
* Deployment-intent migration: retire a provider repository's standalone
|
|
6
|
+
* `deploy.ts`.
|
|
7
|
+
*
|
|
8
|
+
* End state: deployment intent lives only in the `deployment` key of the
|
|
9
|
+
* `defineProvider({...})` declaration, and only the fields that differ from
|
|
10
|
+
* the runtime profile are written. Everything else goes: the `deploy.ts`
|
|
11
|
+
* file, a `deployment` extra on a `{ ...provider, deployment }` default
|
|
12
|
+
* export, and an `import deployment from "./deploy"`. The `/deploy.ts`
|
|
13
|
+
* CODEOWNERS lock is kept by default: the platform still honors a committed
|
|
14
|
+
* legacy file until its fallback is retired, so re-adding one must keep
|
|
15
|
+
* needing operator review. `dropCodeownersLock` removes it once that
|
|
16
|
+
* fallback is gone.
|
|
17
|
+
*
|
|
18
|
+
* The transform never regenerates values from the profile — it moves the
|
|
19
|
+
* values the file actually declares (hand-edited "mirrors" exist in the
|
|
20
|
+
* fleet) and proves equivalence: the key it writes must resolve to exactly
|
|
21
|
+
* what the legacy file resolved to, or it refuses. Like the other codemods
|
|
22
|
+
* it is conservative: anything it cannot fully account for is reported as
|
|
23
|
+
* `refused` with a reason rather than partially migrated.
|
|
24
|
+
*/
|
|
25
|
+
/** How the `defineProvider()` declaration literal was located. */
|
|
26
|
+
export type DeploymentDeclarationShape =
|
|
27
|
+
/** `defineProvider({ ... })` — the literal is the argument (spreads inside are fine). */
|
|
28
|
+
"literal-argument"
|
|
29
|
+
/** `const declaration = { ... }; defineProvider(declaration)` — top-level const literal. */
|
|
30
|
+
| "variable-literal-argument";
|
|
31
|
+
export interface DeploymentIntentMigrationInput {
|
|
32
|
+
/** Current `index.ts` text. */
|
|
33
|
+
readonly indexSource: string;
|
|
34
|
+
/** Current `deploy.ts` text, or undefined when the repository has none. */
|
|
35
|
+
readonly deploySource?: string;
|
|
36
|
+
/** Current `.github/CODEOWNERS` text, or undefined when absent. */
|
|
37
|
+
readonly codeownersSource?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Remove the `/deploy.ts` CODEOWNERS lock (and the scaffold's TEMPORARY
|
|
40
|
+
* comment above it). Off by default — see the module comment.
|
|
41
|
+
*/
|
|
42
|
+
readonly dropCodeownersLock?: boolean;
|
|
43
|
+
readonly indexFileName?: string;
|
|
44
|
+
}
|
|
45
|
+
export type DeploymentIntentMigration = {
|
|
46
|
+
readonly status: "migrated";
|
|
47
|
+
readonly shape: DeploymentDeclarationShape;
|
|
48
|
+
readonly indexSource: string;
|
|
49
|
+
readonly indexChanged: boolean;
|
|
50
|
+
readonly codeownersSource?: string;
|
|
51
|
+
readonly codeownersChanged: boolean;
|
|
52
|
+
/** True when `deploy.ts` existed and must be deleted. */
|
|
53
|
+
readonly removeDeployFile: boolean;
|
|
54
|
+
/** Resolved view the legacy `deploy.ts` declared, when it existed. */
|
|
55
|
+
readonly legacy?: ResolvedDeploymentIntent;
|
|
56
|
+
/** The minimal key now authored in the declaration (empty = profile defaults). */
|
|
57
|
+
readonly intent: ProviderDeploymentOverrides;
|
|
58
|
+
/** What the key resolves to; equals `legacy` when a legacy file existed. */
|
|
59
|
+
readonly resolved: ResolvedDeploymentIntent;
|
|
60
|
+
readonly notes: readonly string[];
|
|
61
|
+
} | {
|
|
62
|
+
readonly status: "unchanged";
|
|
63
|
+
readonly notes: readonly string[];
|
|
64
|
+
} | {
|
|
65
|
+
readonly status: "refused";
|
|
66
|
+
readonly reason: string;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Emitted above the key only when it carries `runtime`: the deployment
|
|
70
|
+
* runtime axis sits next to the execution `runtime` property and must not
|
|
71
|
+
* be read as the same axis.
|
|
72
|
+
*/
|
|
73
|
+
export declare const DEPLOYMENT_RUNTIME_AXIS_COMMENT = "// Deployment runtime axis (shared | dedicated | browser); not the execution runtime above.";
|
|
74
|
+
export declare function migrateDeploymentIntent(input: DeploymentIntentMigrationInput): DeploymentIntentMigration;
|
|
75
|
+
/**
|
|
76
|
+
* Statically read the `deployment` key authored inside the declaration
|
|
77
|
+
* literal of `indexSource` (undefined when absent). Used to prove round
|
|
78
|
+
* trips: the value the transform wrote must resolve to the legacy view.
|
|
79
|
+
*/
|
|
80
|
+
export declare function readDeclaredDeploymentIntent(indexSource: string, fileName?: string): {
|
|
81
|
+
readonly ok: true;
|
|
82
|
+
readonly value: unknown;
|
|
83
|
+
} | {
|
|
84
|
+
readonly ok: false;
|
|
85
|
+
readonly reason: string;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Line (1-based) of a `deployment` property attached to a spread default
|
|
89
|
+
* export (`export default { ...provider, deployment }`), or undefined when
|
|
90
|
+
* the module has no such legacy surface. Used by `apifuse check`: the loaded
|
|
91
|
+
* module cannot tell that extra apart from a declaration-level key, so the
|
|
92
|
+
* source shape is inspected instead.
|
|
93
|
+
*/
|
|
94
|
+
export declare function findSpreadExportDeploymentProperty(indexSource: string, fileName?: string): {
|
|
95
|
+
readonly line: number;
|
|
96
|
+
} | undefined;
|
|
97
|
+
/** Parse a legacy `deploy.ts` module text into the resolved deployment view. */
|
|
98
|
+
export declare function readLegacyDeployFile(deploySource: string): {
|
|
99
|
+
readonly ok: true;
|
|
100
|
+
readonly value: ResolvedDeploymentIntent;
|
|
101
|
+
readonly raw: unknown;
|
|
102
|
+
} | {
|
|
103
|
+
readonly ok: false;
|
|
104
|
+
readonly reason: string;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Repository sources (other than index.ts and deploy.ts themselves) that
|
|
108
|
+
* import the deploy module — `import x from "../deploy"`, re-exports, dynamic
|
|
109
|
+
* `import("./deploy")`, `require("./deploy")`. Deleting deploy.ts while one
|
|
110
|
+
* exists breaks that consumer, so the command refuses until it is removed.
|
|
111
|
+
* `files` carry paths relative to or absolute under `providerRoot`.
|
|
112
|
+
*/
|
|
113
|
+
export declare function findDeployModuleConsumers(providerRoot: string, files: readonly {
|
|
114
|
+
readonly path: string;
|
|
115
|
+
readonly text: string;
|
|
116
|
+
}[]): string[];
|
|
117
|
+
/**
|
|
118
|
+
* Remove the `/deploy.ts` CODEOWNERS line and, when it is preceded by the
|
|
119
|
+
* exact platform-scaffold comment block, that block too. Any other content
|
|
120
|
+
* is preserved byte for byte.
|
|
121
|
+
*/
|
|
122
|
+
export declare function stripCodeownersDeployLock(text: string): {
|
|
123
|
+
readonly text: string;
|
|
124
|
+
readonly changed: boolean;
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Format the key's object literal starting at column `indent.length +
|
|
128
|
+
* "deployment: ".length`: inline when it fits the line width, otherwise
|
|
129
|
+
* expanded one property per line (recursively), trailing commas included —
|
|
130
|
+
* the same decisions a formatter would keep.
|
|
131
|
+
*/
|
|
132
|
+
export declare function formatIntentLiteral(intent: ProviderDeploymentOverrides, indent: string, unit: string): string;
|