@aws-blocks/core 0.1.3 → 0.1.4
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/dist/constants.d.ts +12 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +12 -0
- package/dist/scripts/dev-server-config.test.d.ts +2 -0
- package/dist/scripts/dev-server-config.test.d.ts.map +1 -0
- package/dist/scripts/dev-server-config.test.js +37 -0
- package/dist/scripts/dev-server.d.ts +19 -0
- package/dist/scripts/dev-server.d.ts.map +1 -1
- package/dist/scripts/dev-server.js +38 -5
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/src/constants.ts +13 -0
- package/src/scripts/dev-server-config.test.ts +43 -0
- package/src/scripts/dev-server.ts +48 -6
- package/src/version.ts +1 -1
package/dist/constants.d.ts
CHANGED
|
@@ -24,4 +24,16 @@ export declare const BLOCKS_RPC_PREFIX = "/aws-blocks/api";
|
|
|
24
24
|
* prefix; CloudFront forwards the subtree and the Lambda dispatches by path.
|
|
25
25
|
*/
|
|
26
26
|
export declare const BLOCKS_AUTH_PREFIX = "/aws-blocks/auth";
|
|
27
|
+
/**
|
|
28
|
+
* Reserved path for the client runtime config (`config.json`).
|
|
29
|
+
*
|
|
30
|
+
* In production CloudFront serves `${BLOCKS_SANDBOX_PREFIX}/*` from S3 as
|
|
31
|
+
* static assets (see hosting.ts) so the browser client can resolve its API
|
|
32
|
+
* URL. The local dev server mirrors this by serving the config from the front
|
|
33
|
+
* door itself, instead of proxying the request to the framework dev server —
|
|
34
|
+
* which only serves its own static dir (Next.js `public/`, etc.) and would 404
|
|
35
|
+
* on a project-root file. Keeping this symmetric with production is what makes
|
|
36
|
+
* the browser client work the same in `dev`, `sandbox`, and deployed.
|
|
37
|
+
*/
|
|
38
|
+
export declare const BLOCKS_SANDBOX_PREFIX = "/.blocks-sandbox";
|
|
27
39
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,eAAO,MAAM,gBAAgB,gBAAgB,CAAC;AAE9C;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAEnD;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,eAAO,MAAM,gBAAgB,gBAAgB,CAAC;AAE9C;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAEnD;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,qBAAqB,CAAC;AAErD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,qBAAqB,CAAC"}
|
package/dist/constants.js
CHANGED
|
@@ -26,3 +26,15 @@ export const BLOCKS_RPC_PREFIX = '/aws-blocks/api';
|
|
|
26
26
|
* prefix; CloudFront forwards the subtree and the Lambda dispatches by path.
|
|
27
27
|
*/
|
|
28
28
|
export const BLOCKS_AUTH_PREFIX = '/aws-blocks/auth';
|
|
29
|
+
/**
|
|
30
|
+
* Reserved path for the client runtime config (`config.json`).
|
|
31
|
+
*
|
|
32
|
+
* In production CloudFront serves `${BLOCKS_SANDBOX_PREFIX}/*` from S3 as
|
|
33
|
+
* static assets (see hosting.ts) so the browser client can resolve its API
|
|
34
|
+
* URL. The local dev server mirrors this by serving the config from the front
|
|
35
|
+
* door itself, instead of proxying the request to the framework dev server —
|
|
36
|
+
* which only serves its own static dir (Next.js `public/`, etc.) and would 404
|
|
37
|
+
* on a project-root file. Keeping this symmetric with production is what makes
|
|
38
|
+
* the browser client work the same in `dev`, `sandbox`, and deployed.
|
|
39
|
+
*/
|
|
40
|
+
export const BLOCKS_SANDBOX_PREFIX = '/.blocks-sandbox';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-server-config.test.d.ts","sourceRoot":"","sources":["../../src/scripts/dev-server-config.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { describe, it } from 'node:test';
|
|
4
|
+
import assert from 'node:assert';
|
|
5
|
+
import { buildBlocksConfig, isBlocksConfigRequest } from './dev-server.js';
|
|
6
|
+
describe('buildBlocksConfig — client runtime config', () => {
|
|
7
|
+
it('points the browser at the localhost front door RPC endpoint', () => {
|
|
8
|
+
assert.deepStrictEqual(buildBlocksConfig(3000, false), {
|
|
9
|
+
apiUrl: 'http://localhost:3000/aws-blocks/api',
|
|
10
|
+
environment: 'local',
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
it('honors a custom port', () => {
|
|
14
|
+
assert.strictEqual(buildBlocksConfig(4000, false).apiUrl, 'http://localhost:4000/aws-blocks/api');
|
|
15
|
+
});
|
|
16
|
+
it('marks the environment as sandbox but keeps the localhost front door', () => {
|
|
17
|
+
assert.deepStrictEqual(buildBlocksConfig(3000, true), {
|
|
18
|
+
apiUrl: 'http://localhost:3000/aws-blocks/api',
|
|
19
|
+
environment: 'sandbox',
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
describe('isBlocksConfigRequest — reserved runtime-config path', () => {
|
|
24
|
+
it('matches GET /.blocks-sandbox/config.json', () => {
|
|
25
|
+
assert.strictEqual(isBlocksConfigRequest('GET', '/.blocks-sandbox/config.json'), true);
|
|
26
|
+
});
|
|
27
|
+
it('ignores non-GET methods (only the static-style read is reserved)', () => {
|
|
28
|
+
assert.strictEqual(isBlocksConfigRequest('POST', '/.blocks-sandbox/config.json'), false);
|
|
29
|
+
assert.strictEqual(isBlocksConfigRequest('HEAD', '/.blocks-sandbox/config.json'), false);
|
|
30
|
+
});
|
|
31
|
+
it('does not match other paths (frontend/app routes pass through to the proxy)', () => {
|
|
32
|
+
assert.strictEqual(isBlocksConfigRequest('GET', '/'), false);
|
|
33
|
+
assert.strictEqual(isBlocksConfigRequest('GET', '/api/chat'), false);
|
|
34
|
+
assert.strictEqual(isBlocksConfigRequest('GET', '/.blocks-sandbox/other.json'), false);
|
|
35
|
+
assert.strictEqual(isBlocksConfigRequest('GET', '/aws-blocks/api'), false);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -4,6 +4,25 @@ export declare const LOCALHOST_PATTERN: RegExp;
|
|
|
4
4
|
* Reflects back origins matching localhost/127.0.0.1; otherwise returns the fallback.
|
|
5
5
|
*/
|
|
6
6
|
export declare function resolveDevCorsOrigin(origin: string): string;
|
|
7
|
+
/** Shape of the client runtime config the browser fetches to discover the API URL. */
|
|
8
|
+
export interface BlocksRuntimeConfig {
|
|
9
|
+
apiUrl: string;
|
|
10
|
+
environment: 'local' | 'sandbox';
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Build the runtime config the browser fetches at `${BLOCKS_SANDBOX_PREFIX}/config.json`.
|
|
14
|
+
* In sandbox mode the browser still targets the localhost front door (the dev
|
|
15
|
+
* server proxies `/aws-blocks/api` to the deployed API), so the shape is the
|
|
16
|
+
* same in both modes — only `environment` differs.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildBlocksConfig(port: number, isSandbox: boolean): BlocksRuntimeConfig;
|
|
19
|
+
/**
|
|
20
|
+
* True for the reserved runtime-config request the dev server answers itself
|
|
21
|
+
* (mirroring production, where CloudFront serves `${BLOCKS_SANDBOX_PREFIX}/*`
|
|
22
|
+
* statically) instead of proxying it to the framework dev server — which only
|
|
23
|
+
* serves its own static dir (Next.js `public/`, etc.) and would 404.
|
|
24
|
+
*/
|
|
25
|
+
export declare function isBlocksConfigRequest(method: string, pathname: string): boolean;
|
|
7
26
|
export interface DevServerOptions {
|
|
8
27
|
/** Customer-facing port. Default: 3000. */
|
|
9
28
|
port?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../src/scripts/dev-server.ts"],"names":[],"mappings":"AAmCA,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAEhF;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,MAAM,WAAW,gBAAgB;IAC/B,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAmCD,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../src/scripts/dev-server.ts"],"names":[],"mappings":"AAmCA,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAEhF;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,sFAAsF;AACtF,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,GAAG,SAAS,CAAC;CAClC;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,mBAAmB,CAKvF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE/E;AAED,MAAM,WAAW,gBAAgB;IAC/B,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAmCD,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,iBA8P7D"}
|
|
@@ -9,7 +9,7 @@ import { createConnection } from 'node:net';
|
|
|
9
9
|
import httpProxy from 'http-proxy';
|
|
10
10
|
import { writeClientCode } from './generate-client.js';
|
|
11
11
|
import { ApiError } from '../errors.js';
|
|
12
|
-
import { BLOCKS_RPC_PREFIX } from '../constants.js';
|
|
12
|
+
import { BLOCKS_RPC_PREFIX, BLOCKS_SANDBOX_PREFIX } from '../constants.js';
|
|
13
13
|
import { matchRoute, lockRouteRegistry } from '../raw-route.js';
|
|
14
14
|
import { registerBuiltinRoutes } from '../builtin-routes.js';
|
|
15
15
|
import { parseRpcRequest, successResponse, errorResponseFromCatch, methodNotFoundResponse, } from '../rpc.js';
|
|
@@ -34,6 +34,27 @@ export const LOCALHOST_PATTERN = /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/;
|
|
|
34
34
|
export function resolveDevCorsOrigin(origin) {
|
|
35
35
|
return LOCALHOST_PATTERN.test(origin) ? origin : 'http://localhost:3000';
|
|
36
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Build the runtime config the browser fetches at `${BLOCKS_SANDBOX_PREFIX}/config.json`.
|
|
39
|
+
* In sandbox mode the browser still targets the localhost front door (the dev
|
|
40
|
+
* server proxies `/aws-blocks/api` to the deployed API), so the shape is the
|
|
41
|
+
* same in both modes — only `environment` differs.
|
|
42
|
+
*/
|
|
43
|
+
export function buildBlocksConfig(port, isSandbox) {
|
|
44
|
+
return {
|
|
45
|
+
apiUrl: `http://localhost:${port}${BLOCKS_RPC_PREFIX}`,
|
|
46
|
+
environment: isSandbox ? 'sandbox' : 'local',
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* True for the reserved runtime-config request the dev server answers itself
|
|
51
|
+
* (mirroring production, where CloudFront serves `${BLOCKS_SANDBOX_PREFIX}/*`
|
|
52
|
+
* statically) instead of proxying it to the framework dev server — which only
|
|
53
|
+
* serves its own static dir (Next.js `public/`, etc.) and would 404.
|
|
54
|
+
*/
|
|
55
|
+
export function isBlocksConfigRequest(method, pathname) {
|
|
56
|
+
return method === 'GET' && pathname === `${BLOCKS_SANDBOX_PREFIX}/config.json`;
|
|
57
|
+
}
|
|
37
58
|
/**
|
|
38
59
|
* Initialize all building blocks that have an initialize() method.
|
|
39
60
|
* This is the "local deploy" phase - mirrors CDK deploy.
|
|
@@ -95,11 +116,9 @@ export async function startDevServer(options) {
|
|
|
95
116
|
// BLOCKS_API_URL server-side, so the request still reaches the deployed Lambda.
|
|
96
117
|
// This makes sandbox single-origin, matching `npm run dev` and the prod
|
|
97
118
|
// CloudFront proxy; `crossDomain` stays unnecessary.
|
|
119
|
+
const blocksConfig = buildBlocksConfig(port, isSandbox);
|
|
98
120
|
mkdirSync('.blocks-sandbox', { recursive: true });
|
|
99
|
-
writeFileSync('.blocks-sandbox/config.json', JSON.stringify(
|
|
100
|
-
apiUrl: `http://localhost:${port}${BLOCKS_RPC_PREFIX}`,
|
|
101
|
-
environment: isSandbox ? 'sandbox' : 'local',
|
|
102
|
-
}, null, 2));
|
|
121
|
+
writeFileSync('.blocks-sandbox/config.json', JSON.stringify(blocksConfig, null, 2));
|
|
103
122
|
// 1. Set up global collectors for plugin discovery
|
|
104
123
|
globalThis.__BLOCKS_CLIENT_MIDDLEWARE__ = [];
|
|
105
124
|
globalThis.__BLOCKS_DEV_ATTACHMENTS__ = [];
|
|
@@ -181,6 +200,20 @@ export async function startDevServer(options) {
|
|
|
181
200
|
res.end();
|
|
182
201
|
return;
|
|
183
202
|
}
|
|
203
|
+
// ── Blocks runtime config ──────────────────────────────────────────
|
|
204
|
+
// Reserved path: serve it from the front door so it works for every
|
|
205
|
+
// framework (Next/Nuxt/Astro/SPA all proxy through this :3000 server),
|
|
206
|
+
// mirroring production where CloudFront serves `${BLOCKS_SANDBOX_PREFIX}/*`
|
|
207
|
+
// statically. Otherwise the request is proxied to the framework dev
|
|
208
|
+
// server, which can't serve this project-root file and 404s.
|
|
209
|
+
if (isBlocksConfigRequest(method, url.pathname)) {
|
|
210
|
+
res.writeHead(200, {
|
|
211
|
+
'Content-Type': 'application/json',
|
|
212
|
+
'Cache-Control': 'no-store',
|
|
213
|
+
});
|
|
214
|
+
res.end(JSON.stringify(blocksConfig));
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
184
217
|
// ── API/RawRoute requests ──────────────────────────────────────────
|
|
185
218
|
if (isApiRequest(method, url.pathname)) {
|
|
186
219
|
if (isSandbox && apiProxy) {
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const CORE_VERSION = "0.1.
|
|
1
|
+
export declare const CORE_VERSION = "0.1.4";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Auto-generated by scripts/generate-version.mjs — do not edit manually
|
|
2
|
-
export const CORE_VERSION = '0.1.
|
|
2
|
+
export const CORE_VERSION = '0.1.4';
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
|
@@ -29,3 +29,16 @@ export const BLOCKS_RPC_PREFIX = '/aws-blocks/api';
|
|
|
29
29
|
* prefix; CloudFront forwards the subtree and the Lambda dispatches by path.
|
|
30
30
|
*/
|
|
31
31
|
export const BLOCKS_AUTH_PREFIX = '/aws-blocks/auth';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Reserved path for the client runtime config (`config.json`).
|
|
35
|
+
*
|
|
36
|
+
* In production CloudFront serves `${BLOCKS_SANDBOX_PREFIX}/*` from S3 as
|
|
37
|
+
* static assets (see hosting.ts) so the browser client can resolve its API
|
|
38
|
+
* URL. The local dev server mirrors this by serving the config from the front
|
|
39
|
+
* door itself, instead of proxying the request to the framework dev server —
|
|
40
|
+
* which only serves its own static dir (Next.js `public/`, etc.) and would 404
|
|
41
|
+
* on a project-root file. Keeping this symmetric with production is what makes
|
|
42
|
+
* the browser client work the same in `dev`, `sandbox`, and deployed.
|
|
43
|
+
*/
|
|
44
|
+
export const BLOCKS_SANDBOX_PREFIX = '/.blocks-sandbox';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { describe, it } from 'node:test';
|
|
4
|
+
import assert from 'node:assert';
|
|
5
|
+
import { buildBlocksConfig, isBlocksConfigRequest } from './dev-server.js';
|
|
6
|
+
|
|
7
|
+
describe('buildBlocksConfig — client runtime config', () => {
|
|
8
|
+
it('points the browser at the localhost front door RPC endpoint', () => {
|
|
9
|
+
assert.deepStrictEqual(buildBlocksConfig(3000, false), {
|
|
10
|
+
apiUrl: 'http://localhost:3000/aws-blocks/api',
|
|
11
|
+
environment: 'local',
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('honors a custom port', () => {
|
|
16
|
+
assert.strictEqual(buildBlocksConfig(4000, false).apiUrl, 'http://localhost:4000/aws-blocks/api');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('marks the environment as sandbox but keeps the localhost front door', () => {
|
|
20
|
+
assert.deepStrictEqual(buildBlocksConfig(3000, true), {
|
|
21
|
+
apiUrl: 'http://localhost:3000/aws-blocks/api',
|
|
22
|
+
environment: 'sandbox',
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('isBlocksConfigRequest — reserved runtime-config path', () => {
|
|
28
|
+
it('matches GET /.blocks-sandbox/config.json', () => {
|
|
29
|
+
assert.strictEqual(isBlocksConfigRequest('GET', '/.blocks-sandbox/config.json'), true);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('ignores non-GET methods (only the static-style read is reserved)', () => {
|
|
33
|
+
assert.strictEqual(isBlocksConfigRequest('POST', '/.blocks-sandbox/config.json'), false);
|
|
34
|
+
assert.strictEqual(isBlocksConfigRequest('HEAD', '/.blocks-sandbox/config.json'), false);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('does not match other paths (frontend/app routes pass through to the proxy)', () => {
|
|
38
|
+
assert.strictEqual(isBlocksConfigRequest('GET', '/'), false);
|
|
39
|
+
assert.strictEqual(isBlocksConfigRequest('GET', '/api/chat'), false);
|
|
40
|
+
assert.strictEqual(isBlocksConfigRequest('GET', '/.blocks-sandbox/other.json'), false);
|
|
41
|
+
assert.strictEqual(isBlocksConfigRequest('GET', '/aws-blocks/api'), false);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';
|
|
5
5
|
import { pathToFileURL, URL } from 'node:url';
|
|
6
6
|
import { resolve, dirname, join } from 'node:path';
|
|
7
|
-
import {
|
|
7
|
+
import { writeFileSync, mkdirSync } from 'node:fs';
|
|
8
8
|
import { spawn, type ChildProcess } from 'node:child_process';
|
|
9
9
|
import { createConnection } from 'node:net';
|
|
10
10
|
import httpProxy from 'http-proxy';
|
|
11
11
|
import { writeClientCode } from './generate-client.js';
|
|
12
12
|
import { ApiError } from '../errors.js';
|
|
13
|
-
import { BLOCKS_RPC_PREFIX } from '../constants.js';
|
|
13
|
+
import { BLOCKS_RPC_PREFIX, BLOCKS_SANDBOX_PREFIX } from '../constants.js';
|
|
14
14
|
import { matchRoute, lockRouteRegistry } from '../raw-route.js';
|
|
15
15
|
import { registerBuiltinRoutes } from '../builtin-routes.js';
|
|
16
16
|
import {
|
|
@@ -43,6 +43,35 @@ export function resolveDevCorsOrigin(origin: string): string {
|
|
|
43
43
|
return LOCALHOST_PATTERN.test(origin) ? origin : 'http://localhost:3000';
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
/** Shape of the client runtime config the browser fetches to discover the API URL. */
|
|
47
|
+
export interface BlocksRuntimeConfig {
|
|
48
|
+
apiUrl: string;
|
|
49
|
+
environment: 'local' | 'sandbox';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Build the runtime config the browser fetches at `${BLOCKS_SANDBOX_PREFIX}/config.json`.
|
|
54
|
+
* In sandbox mode the browser still targets the localhost front door (the dev
|
|
55
|
+
* server proxies `/aws-blocks/api` to the deployed API), so the shape is the
|
|
56
|
+
* same in both modes — only `environment` differs.
|
|
57
|
+
*/
|
|
58
|
+
export function buildBlocksConfig(port: number, isSandbox: boolean): BlocksRuntimeConfig {
|
|
59
|
+
return {
|
|
60
|
+
apiUrl: `http://localhost:${port}${BLOCKS_RPC_PREFIX}`,
|
|
61
|
+
environment: isSandbox ? 'sandbox' : 'local',
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* True for the reserved runtime-config request the dev server answers itself
|
|
67
|
+
* (mirroring production, where CloudFront serves `${BLOCKS_SANDBOX_PREFIX}/*`
|
|
68
|
+
* statically) instead of proxying it to the framework dev server — which only
|
|
69
|
+
* serves its own static dir (Next.js `public/`, etc.) and would 404.
|
|
70
|
+
*/
|
|
71
|
+
export function isBlocksConfigRequest(method: string, pathname: string): boolean {
|
|
72
|
+
return method === 'GET' && pathname === `${BLOCKS_SANDBOX_PREFIX}/config.json`;
|
|
73
|
+
}
|
|
74
|
+
|
|
46
75
|
export interface DevServerOptions {
|
|
47
76
|
/** Customer-facing port. Default: 3000. */
|
|
48
77
|
port?: number;
|
|
@@ -125,11 +154,9 @@ export async function startDevServer(options: DevServerOptions) {
|
|
|
125
154
|
// BLOCKS_API_URL server-side, so the request still reaches the deployed Lambda.
|
|
126
155
|
// This makes sandbox single-origin, matching `npm run dev` and the prod
|
|
127
156
|
// CloudFront proxy; `crossDomain` stays unnecessary.
|
|
157
|
+
const blocksConfig = buildBlocksConfig(port, isSandbox);
|
|
128
158
|
mkdirSync('.blocks-sandbox', { recursive: true });
|
|
129
|
-
writeFileSync('.blocks-sandbox/config.json', JSON.stringify(
|
|
130
|
-
apiUrl: `http://localhost:${port}${BLOCKS_RPC_PREFIX}`,
|
|
131
|
-
environment: isSandbox ? 'sandbox' : 'local',
|
|
132
|
-
}, null, 2));
|
|
159
|
+
writeFileSync('.blocks-sandbox/config.json', JSON.stringify(blocksConfig, null, 2));
|
|
133
160
|
|
|
134
161
|
// 1. Set up global collectors for plugin discovery
|
|
135
162
|
(globalThis as any).__BLOCKS_CLIENT_MIDDLEWARE__ = [];
|
|
@@ -221,6 +248,21 @@ export async function startDevServer(options: DevServerOptions) {
|
|
|
221
248
|
return;
|
|
222
249
|
}
|
|
223
250
|
|
|
251
|
+
// ── Blocks runtime config ──────────────────────────────────────────
|
|
252
|
+
// Reserved path: serve it from the front door so it works for every
|
|
253
|
+
// framework (Next/Nuxt/Astro/SPA all proxy through this :3000 server),
|
|
254
|
+
// mirroring production where CloudFront serves `${BLOCKS_SANDBOX_PREFIX}/*`
|
|
255
|
+
// statically. Otherwise the request is proxied to the framework dev
|
|
256
|
+
// server, which can't serve this project-root file and 404s.
|
|
257
|
+
if (isBlocksConfigRequest(method, url.pathname)) {
|
|
258
|
+
res.writeHead(200, {
|
|
259
|
+
'Content-Type': 'application/json',
|
|
260
|
+
'Cache-Control': 'no-store',
|
|
261
|
+
});
|
|
262
|
+
res.end(JSON.stringify(blocksConfig));
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
|
|
224
266
|
// ── API/RawRoute requests ──────────────────────────────────────────
|
|
225
267
|
if (isApiRequest(method, url.pathname)) {
|
|
226
268
|
if (isSandbox && apiProxy) {
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Auto-generated by scripts/generate-version.mjs — do not edit manually
|
|
2
|
-
export const CORE_VERSION = '0.1.
|
|
2
|
+
export const CORE_VERSION = '0.1.4';
|