@webpieces/gcp-identity 0.3.371 → 0.3.373
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/README.md +2 -1
- package/package.json +3 -3
- package/src/index.d.ts +1 -1
- package/src/index.js +2 -3
- package/src/index.js.map +1 -1
- package/src/metadata.d.ts +5 -1
- package/src/metadata.js +13 -2
- package/src/metadata.js.map +1 -1
- package/src/urls.d.ts +12 -16
- package/src/urls.js +21 -32
- package/src/urls.js.map +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,8 @@ tests) every call falls back to a deterministic localhost value so no GCP is nee
|
|
|
6
6
|
|
|
7
7
|
- `getProjectId()` / `getNumericProjectId()` / `getRegion()` — cached metadata lookups
|
|
8
8
|
- `getServiceName()` — logical name from `K_SERVICE` (strips a `tf-` prefix), else `'local'`
|
|
9
|
-
- `getSelfCloudRunUrl()`
|
|
9
|
+
- `getSelfCloudRunUrl()` — this service's own base URL
|
|
10
|
+
- `resolveServiceUrl(svcName)` — the base URL to call svcName: a `ClientRegistry` override wins, else the Cloud Run URL is derived on GCP, else (off-GCP, unregistered) it throws
|
|
10
11
|
- `getRuntimeServiceAccountEmail()` — the SA this process runs as
|
|
11
12
|
- `mintIdToken(audience)` — Google-signed OIDC ID token (a `dev-oidc.*` token off-GCP)
|
|
12
13
|
- `verifyOidcFromCallers(idToken, callers)` — verify + allow-list the caller SA
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webpieces/gcp-identity",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.373",
|
|
4
4
|
"description": "GCP runtime identity: project/region metadata, Cloud Run URLs, OIDC mint/verify",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"access": "public"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@webpieces/core-context": "0.3.
|
|
27
|
-
"@webpieces/core-util": "0.3.
|
|
26
|
+
"@webpieces/core-context": "0.3.373",
|
|
27
|
+
"@webpieces/core-util": "0.3.373",
|
|
28
28
|
"google-auth-library": "9.15.1",
|
|
29
29
|
"gcp-metadata": "6.1.1",
|
|
30
30
|
"inversify": "7.10.4",
|
package/src/index.d.ts
CHANGED
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
* via an app-bound AuthConfig) and the RPC + Cloud Tasks clients.
|
|
10
10
|
*/
|
|
11
11
|
export { isOnGcp } from './metadata';
|
|
12
|
-
export { getServiceName, getProjectId, getRegion, getRuntimeServiceAccountEmail, getSelfCloudRunUrl,
|
|
12
|
+
export { getServiceName, getProjectId, getRegion, getRuntimeServiceAccountEmail, getSelfCloudRunUrl, resolveServiceUrl, LOCAL_SERVICE_ACCOUNT_EMAIL, } from './urls';
|
|
13
13
|
export { GcpOidc, OidcVerifyResult } from './oidc';
|
package/src/index.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* via an app-bound AuthConfig) and the RPC + Cloud Tasks clients.
|
|
11
11
|
*/
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.OidcVerifyResult = exports.GcpOidc = exports.LOCAL_SERVICE_ACCOUNT_EMAIL = exports.
|
|
13
|
+
exports.OidcVerifyResult = exports.GcpOidc = exports.LOCAL_SERVICE_ACCOUNT_EMAIL = exports.resolveServiceUrl = exports.getSelfCloudRunUrl = exports.getRuntimeServiceAccountEmail = exports.getRegion = exports.getProjectId = exports.getServiceName = exports.isOnGcp = void 0;
|
|
14
14
|
var metadata_1 = require("./metadata");
|
|
15
15
|
Object.defineProperty(exports, "isOnGcp", { enumerable: true, get: function () { return metadata_1.isOnGcp; } });
|
|
16
16
|
var urls_1 = require("./urls");
|
|
@@ -19,8 +19,7 @@ Object.defineProperty(exports, "getProjectId", { enumerable: true, get: function
|
|
|
19
19
|
Object.defineProperty(exports, "getRegion", { enumerable: true, get: function () { return urls_1.getRegion; } });
|
|
20
20
|
Object.defineProperty(exports, "getRuntimeServiceAccountEmail", { enumerable: true, get: function () { return urls_1.getRuntimeServiceAccountEmail; } });
|
|
21
21
|
Object.defineProperty(exports, "getSelfCloudRunUrl", { enumerable: true, get: function () { return urls_1.getSelfCloudRunUrl; } });
|
|
22
|
-
Object.defineProperty(exports, "
|
|
23
|
-
Object.defineProperty(exports, "resolveTargetUrl", { enumerable: true, get: function () { return urls_1.resolveTargetUrl; } });
|
|
22
|
+
Object.defineProperty(exports, "resolveServiceUrl", { enumerable: true, get: function () { return urls_1.resolveServiceUrl; } });
|
|
24
23
|
Object.defineProperty(exports, "LOCAL_SERVICE_ACCOUNT_EMAIL", { enumerable: true, get: function () { return urls_1.LOCAL_SERVICE_ACCOUNT_EMAIL; } });
|
|
25
24
|
var oidc_1 = require("./oidc");
|
|
26
25
|
Object.defineProperty(exports, "GcpOidc", { enumerable: true, get: function () { return oidc_1.GcpOidc; } });
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/cloud/gcp-identity/src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AAEH,uCAAqC;AAA5B,mGAAA,OAAO,OAAA;AAChB,+
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/cloud/gcp-identity/src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AAEH,uCAAqC;AAA5B,mGAAA,OAAO,OAAA;AAChB,+BAQgB;AAPZ,sGAAA,cAAc,OAAA;AACd,oGAAA,YAAY,OAAA;AACZ,iGAAA,SAAS,OAAA;AACT,qHAAA,6BAA6B,OAAA;AAC7B,0GAAA,kBAAkB,OAAA;AAClB,yGAAA,iBAAiB,OAAA;AACjB,mHAAA,2BAA2B,OAAA;AAE/B,+BAAmD;AAA1C,+FAAA,OAAO,OAAA;AAAE,wGAAA,gBAAgB,OAAA","sourcesContent":["/**\n * @webpieces/gcp-identity\n *\n * GCP runtime identity (Node-only). Metadata, Cloud Run URLs, and OIDC mint/verify,\n * all read from the metadata server / ADC at runtime with deterministic localhost\n * fallbacks off-GCP so local dev and tests never touch GCP.\n *\n * Underpins the @AuthOidc service-to-service auth mode (enforced by the framework AuthFilter\n * via an app-bound AuthConfig) and the RPC + Cloud Tasks clients.\n */\n\nexport { isOnGcp } from './metadata';\nexport {\n getServiceName,\n getProjectId,\n getRegion,\n getRuntimeServiceAccountEmail,\n getSelfCloudRunUrl,\n resolveServiceUrl,\n LOCAL_SERVICE_ACCOUNT_EMAIL,\n} from './urls';\nexport { GcpOidc, OidcVerifyResult } from './oidc';\n"]}
|
package/src/metadata.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* True when running on GCP Cloud Run. Gated on `K_SERVICE` (set by Cloud Run) so local dev does NO
|
|
3
|
+
* metadata network probe. For non-Cloud-Run GCP (GCE / Cloud Functions, which don't set `K_SERVICE`),
|
|
4
|
+
* set `METADATA_SERVER_DETECTION=assume-present` to force on-GCP behavior.
|
|
5
|
+
*/
|
|
2
6
|
export declare function isOnGcp(): Promise<boolean>;
|
|
3
7
|
/** GCP project id (e.g. 'my-project'). Only call when isOnGcp() is true. */
|
|
4
8
|
export declare function readProjectId(): Promise<string>;
|
package/src/metadata.js
CHANGED
|
@@ -12,16 +12,27 @@ const gcpMetadata = tslib_1.__importStar(require("gcp-metadata"));
|
|
|
12
12
|
* process (the metadata server is stable for the life of the instance). Off-GCP
|
|
13
13
|
* `isOnGcp()` is false and the callers fall back to localhost values, so nothing
|
|
14
14
|
* here is ever reached in local dev / tests.
|
|
15
|
+
*
|
|
16
|
+
* `isOnGcp()` is decided from the `K_SERVICE` env var (which Cloud Run always sets),
|
|
17
|
+
* NOT a metadata network probe — so local dev never blocks on the ~3s
|
|
18
|
+
* `gcpMetadata.isAvailable()` timeout. Every caller (project id, region, Cloud Run URL
|
|
19
|
+
* resolution, OIDC minting, Cloud Tasks) short-circuits through this one gate.
|
|
15
20
|
*/
|
|
16
21
|
let cachedOnGcp;
|
|
17
22
|
let cachedProjectId;
|
|
18
23
|
let cachedNumericProjectId;
|
|
19
24
|
let cachedRegion;
|
|
20
25
|
let cachedSaEmail;
|
|
21
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* True when running on GCP Cloud Run. Gated on `K_SERVICE` (set by Cloud Run) so local dev does NO
|
|
28
|
+
* metadata network probe. For non-Cloud-Run GCP (GCE / Cloud Functions, which don't set `K_SERVICE`),
|
|
29
|
+
* set `METADATA_SERVER_DETECTION=assume-present` to force on-GCP behavior.
|
|
30
|
+
*/
|
|
22
31
|
function isOnGcp() {
|
|
23
32
|
if (!cachedOnGcp) {
|
|
24
|
-
|
|
33
|
+
const onGcp = process.env['K_SERVICE'] !== undefined ||
|
|
34
|
+
process.env['METADATA_SERVER_DETECTION'] === 'assume-present';
|
|
35
|
+
cachedOnGcp = Promise.resolve(onGcp);
|
|
25
36
|
}
|
|
26
37
|
return cachedOnGcp;
|
|
27
38
|
}
|
package/src/metadata.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../../../../packages/cloud/gcp-identity/src/metadata.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../../../../packages/cloud/gcp-identity/src/metadata.ts"],"names":[],"mappings":";;AAyBA,0BAQC;AAUD,sCAKC;AAGD,oDAKC;AAGD,gCAQC;AAGD,wEAKC;;AA3ED,kEAA4C;AAE5C;;;;;;;;;;GAUG;AAEH,IAAI,WAAyC,CAAC;AAC9C,IAAI,eAA4C,CAAC;AACjD,IAAI,sBAAmD,CAAC;AACxD,IAAI,YAAyC,CAAC;AAC9C,IAAI,aAA0C,CAAC;AAE/C;;;;GAIG;AACH,SAAgB,OAAO;IACnB,IAAI,CAAC,WAAW,EAAE,CAAC;QACf,MAAM,KAAK,GACP,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,SAAS;YACtC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,KAAK,gBAAgB,CAAC;QAClE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,WAAW,CAAC;AACvB,CAAC;AAED,oFAAoF;AACpF,wEAAwE;AACxE,iGAAiG;AACjG,SAAS,QAAQ,CAAC,KAAc;IAC5B,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC;AAED,4EAA4E;AAC5E,SAAgB,aAAa;IACzB,IAAI,CAAC,eAAe,EAAE,CAAC;QACnB,eAAe,GAAG,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,eAAe,CAAC;AAC3B,CAAC;AAED,yDAAyD;AACzD,SAAgB,oBAAoB;IAChC,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC1B,sBAAsB,GAAG,WAAW,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,sBAAsB,CAAC;AAClC,CAAC;AAED,4FAA4F;AAC5F,SAAgB,UAAU;IACtB,IAAI,CAAC,YAAY,EAAE,CAAC;QAChB,YAAY,GAAG,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,GAAW,EAAE,EAAE;YAC9E,MAAM,GAAG,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YACjC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACnD,CAAC,CAAC,CAAC;IACP,CAAC;IACD,OAAO,YAAY,CAAC;AACxB,CAAC;AAED,sDAAsD;AACtD,SAAgB,8BAA8B;IAC1C,IAAI,CAAC,aAAa,EAAE,CAAC;QACjB,aAAa,GAAG,WAAW,CAAC,QAAQ,CAAC,gCAAgC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO,aAAa,CAAC;AACzB,CAAC","sourcesContent":["import * as gcpMetadata from 'gcp-metadata';\n\n/**\n * Cached reads of the GCP metadata server. Every value is fetched at most once per\n * process (the metadata server is stable for the life of the instance). Off-GCP\n * `isOnGcp()` is false and the callers fall back to localhost values, so nothing\n * here is ever reached in local dev / tests.\n *\n * `isOnGcp()` is decided from the `K_SERVICE` env var (which Cloud Run always sets),\n * NOT a metadata network probe — so local dev never blocks on the ~3s\n * `gcpMetadata.isAvailable()` timeout. Every caller (project id, region, Cloud Run URL\n * resolution, OIDC minting, Cloud Tasks) short-circuits through this one gate.\n */\n\nlet cachedOnGcp: Promise<boolean> | undefined;\nlet cachedProjectId: Promise<string> | undefined;\nlet cachedNumericProjectId: Promise<string> | undefined;\nlet cachedRegion: Promise<string> | undefined;\nlet cachedSaEmail: Promise<string> | undefined;\n\n/**\n * True when running on GCP Cloud Run. Gated on `K_SERVICE` (set by Cloud Run) so local dev does NO\n * metadata network probe. For non-Cloud-Run GCP (GCE / Cloud Functions, which don't set `K_SERVICE`),\n * set `METADATA_SERVER_DETECTION=assume-present` to force on-GCP behavior.\n */\nexport function isOnGcp(): Promise<boolean> {\n if (!cachedOnGcp) {\n const onGcp =\n process.env['K_SERVICE'] !== undefined ||\n process.env['METADATA_SERVER_DETECTION'] === 'assume-present';\n cachedOnGcp = Promise.resolve(onGcp);\n }\n return cachedOnGcp;\n}\n\n// gcp-metadata returns loosely-typed values; coerce every metadata read to a string\n// through this one helper so the rest of the file stays strongly typed.\n// webpieces-disable no-any-unknown -- single coercion point for gcp-metadata's loose return type\nfunction asString(value: unknown): string {\n return String(value);\n}\n\n/** GCP project id (e.g. 'my-project'). Only call when isOnGcp() is true. */\nexport function readProjectId(): Promise<string> {\n if (!cachedProjectId) {\n cachedProjectId = gcpMetadata.project('project-id').then(asString);\n }\n return cachedProjectId;\n}\n\n/** Numeric project id (used to build Cloud Run URLs). */\nexport function readNumericProjectId(): Promise<string> {\n if (!cachedNumericProjectId) {\n cachedNumericProjectId = gcpMetadata.project('numeric-project-id').then(asString);\n }\n return cachedNumericProjectId;\n}\n\n/** Cloud Run region (e.g. 'us-central1'), parsed from 'projects/<num>/regions/<region>'. */\nexport function readRegion(): Promise<string> {\n if (!cachedRegion) {\n cachedRegion = gcpMetadata.instance('region').then(asString).then((raw: string) => {\n const idx = raw.lastIndexOf('/');\n return idx >= 0 ? raw.substring(idx + 1) : raw;\n });\n }\n return cachedRegion;\n}\n\n/** The service-account email this process runs as. */\nexport function readRuntimeServiceAccountEmail(): Promise<string> {\n if (!cachedSaEmail) {\n cachedSaEmail = gcpMetadata.instance('service-accounts/default/email').then(asString);\n }\n return cachedSaEmail;\n}\n"]}
|
package/src/urls.d.ts
CHANGED
|
@@ -17,22 +17,18 @@ export declare function getRuntimeServiceAccountEmail(): Promise<string>;
|
|
|
17
17
|
*/
|
|
18
18
|
export declare function getSelfCloudRunUrl(): Promise<string>;
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* actually fetches it during tests); a real local multi-service run can override
|
|
23
|
-
* via the CLOUD_RUN_URL_<UPPER_SNAKE_NAME> env var.
|
|
24
|
-
*/
|
|
25
|
-
export declare function getCloudRunUrl(serviceName: string): Promise<string>;
|
|
26
|
-
/**
|
|
27
|
-
* Resolve the base URL a client should call.
|
|
20
|
+
* Resolve the base URL a client should call for `svcName`. The ONE resolver every RPC / Cloud Tasks
|
|
21
|
+
* client uses. Precedence:
|
|
28
22
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
23
|
+
* 1. A {@link ClientRegistry} override wins — this is how you reach anything the derivation cannot
|
|
24
|
+
* describe: a localhost port, another region, another project, a non-Cloud-Run host. Each
|
|
25
|
+
* environment populates the registry from its own per-env config.
|
|
26
|
+
* 2. Otherwise, on GCP the URL is DERIVED from the Cloud Run service name + project + region
|
|
27
|
+
* (via {@link isOnGcp}) — same project, same region, zero maintenance across demo/qa/prod.
|
|
28
|
+
* 3. Otherwise (off-GCP and unregistered) it THROWS — a missing mapping is a setup bug, not a
|
|
29
|
+
* silent mis-route.
|
|
33
30
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* as the logging name.
|
|
31
|
+
* So clients carry ONLY a `svcName`; there is no per-client `targetUrl` (a client is built once but a
|
|
32
|
+
* URL is per-environment — that belongs in the registry, not on the client).
|
|
37
33
|
*/
|
|
38
|
-
export declare function
|
|
34
|
+
export declare function resolveServiceUrl(svcName: string): Promise<string>;
|
package/src/urls.js
CHANGED
|
@@ -6,8 +6,8 @@ exports.getProjectId = getProjectId;
|
|
|
6
6
|
exports.getRegion = getRegion;
|
|
7
7
|
exports.getRuntimeServiceAccountEmail = getRuntimeServiceAccountEmail;
|
|
8
8
|
exports.getSelfCloudRunUrl = getSelfCloudRunUrl;
|
|
9
|
-
exports.
|
|
10
|
-
|
|
9
|
+
exports.resolveServiceUrl = resolveServiceUrl;
|
|
10
|
+
const core_util_1 = require("@webpieces/core-util");
|
|
11
11
|
const metadata_1 = require("./metadata");
|
|
12
12
|
/** Local fallback SA email used off-GCP so 'self' caller checks are deterministic. */
|
|
13
13
|
exports.LOCAL_SERVICE_ACCOUNT_EMAIL = 'local@localhost.invalid';
|
|
@@ -58,43 +58,32 @@ async function getSelfCloudRunUrl() {
|
|
|
58
58
|
return `https://${kService}-${numericProjectId}.${region}.run.app`;
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
61
|
+
* Resolve the base URL a client should call for `svcName`. The ONE resolver every RPC / Cloud Tasks
|
|
62
|
+
* client uses. Precedence:
|
|
63
|
+
*
|
|
64
|
+
* 1. A {@link ClientRegistry} override wins — this is how you reach anything the derivation cannot
|
|
65
|
+
* describe: a localhost port, another region, another project, a non-Cloud-Run host. Each
|
|
66
|
+
* environment populates the registry from its own per-env config.
|
|
67
|
+
* 2. Otherwise, on GCP the URL is DERIVED from the Cloud Run service name + project + region
|
|
68
|
+
* (via {@link isOnGcp}) — same project, same region, zero maintenance across demo/qa/prod.
|
|
69
|
+
* 3. Otherwise (off-GCP and unregistered) it THROWS — a missing mapping is a setup bug, not a
|
|
70
|
+
* silent mis-route.
|
|
71
|
+
*
|
|
72
|
+
* So clients carry ONLY a `svcName`; there is no per-client `targetUrl` (a client is built once but a
|
|
73
|
+
* URL is per-environment — that belongs in the registry, not on the client).
|
|
65
74
|
*/
|
|
66
|
-
|
|
67
|
-
|
|
75
|
+
// webpieces-disable no-function-outside-class -- pure GCP url helper; every sibling in this module is a free function
|
|
76
|
+
async function resolveServiceUrl(svcName) {
|
|
77
|
+
const override = core_util_1.ClientRegistry.tryLookup(svcName);
|
|
68
78
|
if (override) {
|
|
69
79
|
return override;
|
|
70
80
|
}
|
|
71
81
|
if (!(await (0, metadata_1.isOnGcp)())) {
|
|
72
|
-
|
|
82
|
+
throw new Error(`No URL for service "${svcName}". On GCP it is derived from the Cloud Run service name; ` +
|
|
83
|
+
`off-GCP register it: ClientRegistry.addMapping(svcName, port) or addUrlMapping(svcName, url).`);
|
|
73
84
|
}
|
|
74
85
|
const numericProjectId = await (0, metadata_1.readNumericProjectId)();
|
|
75
86
|
const region = await (0, metadata_1.readRegion)();
|
|
76
|
-
return `https://${
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Resolve the base URL a client should call.
|
|
80
|
-
*
|
|
81
|
-
* We lookup your service in the same project, same region, and form the url from the container
|
|
82
|
-
* information unless you pass in a targetUrl, so you do not have to maintain targetUrls. This
|
|
83
|
-
* works across your demo, qa, prod environments as long as each environment is in its own
|
|
84
|
-
* projectId, which is typical.
|
|
85
|
-
*
|
|
86
|
-
* Supply `targetUrl` only to reach somewhere that lookup cannot describe — another region,
|
|
87
|
-
* another project, or a non-Cloud-Run host. It wins over `svcName`, which is then used purely
|
|
88
|
-
* as the logging name.
|
|
89
|
-
*/
|
|
90
|
-
// webpieces-disable no-function-outside-class -- pure GCP url helper; every sibling in this module is a free function
|
|
91
|
-
async function resolveTargetUrl(svcName, targetUrl) {
|
|
92
|
-
if (targetUrl) {
|
|
93
|
-
return targetUrl;
|
|
94
|
-
}
|
|
95
|
-
return getCloudRunUrl(svcName);
|
|
96
|
-
}
|
|
97
|
-
function toEnvKey(serviceName) {
|
|
98
|
-
return serviceName.toUpperCase().replace(/[^A-Z0-9]+/g, '_');
|
|
87
|
+
return `https://${svcName}-${numericProjectId}.${region}.run.app`;
|
|
99
88
|
}
|
|
100
89
|
//# sourceMappingURL=urls.js.map
|
package/src/urls.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"urls.js","sourceRoot":"","sources":["../../../../../packages/cloud/gcp-identity/src/urls.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"urls.js","sourceRoot":"","sources":["../../../../../packages/cloud/gcp-identity/src/urls.ts"],"names":[],"mappings":";;;AAUA,wCAMC;AAGD,oCAKC;AAGD,8BAKC;AAGD,sEAKC;AAMD,gDASC;AAkBD,8CAcC;AAvFD,oDAAsD;AACtD,yCAAsH;AAEtH,sFAAsF;AACzE,QAAA,2BAA2B,GAAG,yBAAyB,CAAC;AAErE;;;GAGG;AACH,SAAgB,cAAc;IAC1B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC1C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC;IACnB,CAAC;IACD,OAAO,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AACpF,CAAC;AAED,kDAAkD;AAC3C,KAAK,UAAU,YAAY;IAC9B,IAAI,CAAC,CAAC,MAAM,IAAA,kBAAO,GAAE,CAAC,EAAE,CAAC;QACrB,OAAO,eAAe,CAAC;IAC3B,CAAC;IACD,OAAO,IAAA,wBAAa,GAAE,CAAC;AAC3B,CAAC;AAED,4CAA4C;AACrC,KAAK,UAAU,SAAS;IAC3B,IAAI,CAAC,CAAC,MAAM,IAAA,kBAAO,GAAE,CAAC,EAAE,CAAC;QACrB,OAAO,OAAO,CAAC;IACnB,CAAC;IACD,OAAO,IAAA,qBAAU,GAAE,CAAC;AACxB,CAAC;AAED,8DAA8D;AACvD,KAAK,UAAU,6BAA6B;IAC/C,IAAI,CAAC,CAAC,MAAM,IAAA,kBAAO,GAAE,CAAC,EAAE,CAAC;QACrB,OAAO,mCAA2B,CAAC;IACvC,CAAC;IACD,OAAO,IAAA,yCAA8B,GAAE,CAAC;AAC5C,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,kBAAkB;IACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC1C,IAAI,CAAC,CAAC,MAAM,IAAA,kBAAO,GAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC;QAC3C,OAAO,oBAAoB,IAAI,EAAE,CAAC;IACtC,CAAC;IACD,MAAM,gBAAgB,GAAG,MAAM,IAAA,+BAAoB,GAAE,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAU,GAAE,CAAC;IAClC,OAAO,WAAW,QAAQ,IAAI,gBAAgB,IAAI,MAAM,UAAU,CAAC;AACvE,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,sHAAsH;AAC/G,KAAK,UAAU,iBAAiB,CAAC,OAAe;IACnD,MAAM,QAAQ,GAAG,0BAAc,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACnD,IAAI,QAAQ,EAAE,CAAC;QACX,OAAO,QAAQ,CAAC;IACpB,CAAC;IACD,IAAI,CAAC,CAAC,MAAM,IAAA,kBAAO,GAAE,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACX,uBAAuB,OAAO,2DAA2D;YACzF,+FAA+F,CAClG,CAAC;IACN,CAAC;IACD,MAAM,gBAAgB,GAAG,MAAM,IAAA,+BAAoB,GAAE,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAU,GAAE,CAAC;IAClC,OAAO,WAAW,OAAO,IAAI,gBAAgB,IAAI,MAAM,UAAU,CAAC;AACtE,CAAC","sourcesContent":["import { ClientRegistry } from '@webpieces/core-util';\nimport { isOnGcp, readNumericProjectId, readRegion, readProjectId, readRuntimeServiceAccountEmail } from './metadata';\n\n/** Local fallback SA email used off-GCP so 'self' caller checks are deterministic. */\nexport const LOCAL_SERVICE_ACCOUNT_EMAIL = 'local@localhost.invalid';\n\n/**\n * Logical service name from K_SERVICE (Cloud Run sets this), stripping a leading\n * 'tf-' Terraform prefix. Off-GCP returns 'local'. Synchronous — env only.\n */\nexport function getServiceName(): string {\n const kService = process.env['K_SERVICE'];\n if (!kService) {\n return 'local';\n }\n return kService.startsWith('tf-') ? kService.substring('tf-'.length) : kService;\n}\n\n/** GCP project id, or 'local-project' off-GCP. */\nexport async function getProjectId(): Promise<string> {\n if (!(await isOnGcp())) {\n return 'local-project';\n }\n return readProjectId();\n}\n\n/** Cloud Run region, or 'local' off-GCP. */\nexport async function getRegion(): Promise<string> {\n if (!(await isOnGcp())) {\n return 'local';\n }\n return readRegion();\n}\n\n/** The runtime SA email, or the local placeholder off-GCP. */\nexport async function getRuntimeServiceAccountEmail(): Promise<string> {\n if (!(await isOnGcp())) {\n return LOCAL_SERVICE_ACCOUNT_EMAIL;\n }\n return readRuntimeServiceAccountEmail();\n}\n\n/**\n * This service's own base URL (its Cloud Tasks self-enqueue target / public base).\n * Off-GCP → http://localhost:<PORT>.\n */\nexport async function getSelfCloudRunUrl(): Promise<string> {\n const kService = process.env['K_SERVICE'];\n if (!(await isOnGcp()) || !kService) {\n const port = process.env['PORT'] ?? '8080';\n return `http://localhost:${port}`;\n }\n const numericProjectId = await readNumericProjectId();\n const region = await readRegion();\n return `https://${kService}-${numericProjectId}.${region}.run.app`;\n}\n\n/**\n * Resolve the base URL a client should call for `svcName`. The ONE resolver every RPC / Cloud Tasks\n * client uses. Precedence:\n *\n * 1. A {@link ClientRegistry} override wins — this is how you reach anything the derivation cannot\n * describe: a localhost port, another region, another project, a non-Cloud-Run host. Each\n * environment populates the registry from its own per-env config.\n * 2. Otherwise, on GCP the URL is DERIVED from the Cloud Run service name + project + region\n * (via {@link isOnGcp}) — same project, same region, zero maintenance across demo/qa/prod.\n * 3. Otherwise (off-GCP and unregistered) it THROWS — a missing mapping is a setup bug, not a\n * silent mis-route.\n *\n * So clients carry ONLY a `svcName`; there is no per-client `targetUrl` (a client is built once but a\n * URL is per-environment — that belongs in the registry, not on the client).\n */\n// webpieces-disable no-function-outside-class -- pure GCP url helper; every sibling in this module is a free function\nexport async function resolveServiceUrl(svcName: string): Promise<string> {\n const override = ClientRegistry.tryLookup(svcName);\n if (override) {\n return override;\n }\n if (!(await isOnGcp())) {\n throw new Error(\n `No URL for service \"${svcName}\". On GCP it is derived from the Cloud Run service name; ` +\n `off-GCP register it: ClientRegistry.addMapping(svcName, port) or addUrlMapping(svcName, url).`,\n );\n }\n const numericProjectId = await readNumericProjectId();\n const region = await readRegion();\n return `https://${svcName}-${numericProjectId}.${region}.run.app`;\n}\n"]}
|