tileflow 0.1.0-alpha.10 → 0.1.0-alpha.11
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 +3 -3
- package/dist/index.js +25 -204
- package/docs/cli-setup-and-defaults.md +2 -2
- package/docs/command-families.md +4 -4
- package/docs/native-artifacts.md +1 -1
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -23,8 +23,8 @@ executable. With another package manager, use its local-execution command and th
|
|
|
23
23
|
do not add a second lockfile or rely on a globally installed CLI.
|
|
24
24
|
|
|
25
25
|
`init` creates a singular `tileflow.config.ts` extending the official Streets map. `preview` serves
|
|
26
|
-
the exported map using its configured view
|
|
27
|
-
|
|
26
|
+
the exported map using its configured view; it does not replace an application's normal development
|
|
27
|
+
server.
|
|
28
28
|
|
|
29
29
|
Local validation, compilation, and asset preparation require no account or API key. Preview and
|
|
30
30
|
capture may fetch configured remote tiles and fonts. Config files are executable trusted code,
|
|
@@ -264,7 +264,7 @@ for the verified platform, setup, and development-artifact restrictions.
|
|
|
264
264
|
|
|
265
265
|
Run `npx tileflow --help` or `npx tileflow <command> --help` for the installed command surface.
|
|
266
266
|
The families cover map authoring, semantic language discovery, local visual evidence, datasets and
|
|
267
|
-
icons, account sessions, coordinates, and hosted delivery. Hidden
|
|
267
|
+
icons, account sessions, coordinates, and hosted delivery. Hidden support commands are not a
|
|
268
268
|
recommended application workflow.
|
|
269
269
|
|
|
270
270
|
A manifest 404 usually means assets were not built/served at the component's configured URL.
|
package/dist/index.js
CHANGED
|
@@ -88,7 +88,7 @@ var sessionSchema = z.object({
|
|
|
88
88
|
}).strict().refine((value) => Date.parse(value.expiresAt) > Date.parse(value.createdAt), {
|
|
89
89
|
message: "session expiry must follow creation"
|
|
90
90
|
});
|
|
91
|
-
var
|
|
91
|
+
var authConfigSchema = z.object({
|
|
92
92
|
sessions: z.record(z.string().max(2048), sessionSchema),
|
|
93
93
|
version: z.literal(2)
|
|
94
94
|
}).strict().superRefine((value, context) => {
|
|
@@ -101,16 +101,6 @@ var authConfigV2Schema = z.object({
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
});
|
|
104
|
-
var legacyAuthConfigSchema = z.object({
|
|
105
|
-
apiKey: z.string().min(16).max(4096),
|
|
106
|
-
apiUrl: z.string().min(1).max(2048),
|
|
107
|
-
appUrl: z.string().max(2048).optional(),
|
|
108
|
-
createdAt: z.string().max(64).optional(),
|
|
109
|
-
deviceName: z.string().max(200).optional(),
|
|
110
|
-
keyPrefix: z.string().max(64).optional(),
|
|
111
|
-
projectId: z.string().max(200).optional(),
|
|
112
|
-
scopes: z.array(z.string().max(128)).max(32).optional()
|
|
113
|
-
}).strict();
|
|
114
104
|
function emptyAuthConfig() {
|
|
115
105
|
return Object.freeze({ sessions: Object.freeze({}), version: 2 });
|
|
116
106
|
}
|
|
@@ -128,24 +118,13 @@ async function readAuthFile(path = authConfigPath()) {
|
|
|
128
118
|
} catch {
|
|
129
119
|
return { kind: "invalid" };
|
|
130
120
|
}
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
const legacy = legacyAuthConfigSchema.safeParse(parsed);
|
|
134
|
-
if (legacy.success) {
|
|
135
|
-
return { config: Object.freeze(legacy.data), kind: "legacy_project_login" };
|
|
136
|
-
}
|
|
137
|
-
if (isSupersededProfileState(parsed)) return { kind: "superseded_profiles" };
|
|
138
|
-
return { kind: "invalid" };
|
|
121
|
+
const config = authConfigSchema.safeParse(parsed);
|
|
122
|
+
return config.success ? { config: freezeConfig(config.data), kind: "sessions" } : { kind: "invalid" };
|
|
139
123
|
}
|
|
140
124
|
async function loadAuthConfig(path = authConfigPath()) {
|
|
141
125
|
const state = await readAuthFile(path);
|
|
142
126
|
if (state.kind === "empty") return emptyAuthConfig();
|
|
143
|
-
if (state.kind === "
|
|
144
|
-
if (state.kind === "legacy_project_login" || state.kind === "superseded_profiles") {
|
|
145
|
-
throw new Error(
|
|
146
|
-
"The saved login uses the retired destination-credential model. Run `tileflow login` to authorize your Tileflow account."
|
|
147
|
-
);
|
|
148
|
-
}
|
|
127
|
+
if (state.kind === "sessions") return state.config;
|
|
149
128
|
throw new Error("Tileflow auth state is invalid; no changes were made.");
|
|
150
129
|
}
|
|
151
130
|
async function installAccountSession(session, path = authConfigPath()) {
|
|
@@ -157,7 +136,7 @@ async function installAccountSession(session, path = authConfigPath()) {
|
|
|
157
136
|
if (state.kind === "invalid") {
|
|
158
137
|
throw new Error("Tileflow auth state is invalid; no changes were made.");
|
|
159
138
|
}
|
|
160
|
-
const current = state.kind === "
|
|
139
|
+
const current = state.kind === "sessions" ? state.config : emptyAuthConfig();
|
|
161
140
|
const sessions = { ...current.sessions, [normalized.apiOrigin]: normalized };
|
|
162
141
|
if (Object.keys(sessions).length > maximumOrigins) {
|
|
163
142
|
throw new Error("Tileflow CLI API-origin limit reached.");
|
|
@@ -180,7 +159,7 @@ function removeAccountSession(config, apiUrl) {
|
|
|
180
159
|
return { config: freezeConfig({ sessions, version: 2 }), removed };
|
|
181
160
|
}
|
|
182
161
|
async function writeAuthFileAtomic(config, path = authConfigPath()) {
|
|
183
|
-
const normalized = normalizeConfig(
|
|
162
|
+
const normalized = normalizeConfig(authConfigSchema.parse(config));
|
|
184
163
|
const source = `${JSON.stringify(normalized, null, 2)}
|
|
185
164
|
`;
|
|
186
165
|
if (Buffer.byteLength(source, "utf8") > maximumAuthFileBytes) {
|
|
@@ -226,9 +205,6 @@ function parseProjectReference(value) {
|
|
|
226
205
|
);
|
|
227
206
|
return match ? { organizationSlug: match[1], projectSlug: match[2] } : null;
|
|
228
207
|
}
|
|
229
|
-
function projectReference(value) {
|
|
230
|
-
return `@${value.organization.slug}/${value.project.slug}`;
|
|
231
|
-
}
|
|
232
208
|
function authConfigPath() {
|
|
233
209
|
return resolve(homedir(), ".tileflow", "config.json");
|
|
234
210
|
}
|
|
@@ -250,11 +226,6 @@ function freezeConfig(config) {
|
|
|
250
226
|
);
|
|
251
227
|
return Object.freeze({ sessions: Object.freeze(sessions), version: 2 });
|
|
252
228
|
}
|
|
253
|
-
function isSupersededProfileState(value) {
|
|
254
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
255
|
-
const record = value;
|
|
256
|
-
return record.version === 2 && Boolean(record.profiles && typeof record.profiles === "object") && Boolean(record.selections && typeof record.selections === "object");
|
|
257
|
-
}
|
|
258
229
|
async function syncDirectory(path) {
|
|
259
230
|
if (process.platform === "win32") return;
|
|
260
231
|
const directory = await open(path, "r");
|
|
@@ -2464,47 +2435,17 @@ async function requestMapCapability(session, target, scopes, options = {}) {
|
|
|
2464
2435
|
} catch (error) {
|
|
2465
2436
|
return { error: safeTransportError(error, "Map capability request failed."), ok: false };
|
|
2466
2437
|
}
|
|
2467
|
-
if (!response.ok) {
|
|
2468
|
-
return { error: `Map capability request failed (${response.status}).`, ok: false };
|
|
2469
|
-
}
|
|
2470
|
-
const body = asRecord(response.body);
|
|
2471
|
-
if (!response.json || typeof body.capability !== "string" || !body.capability.startsWith("tf_cap_") || body.capability.length > 8192 || typeof body.mapId !== "string" || !/^map_[A-Za-z0-9_-]{16}$/u.test(body.mapId) || body.mapId !== target.mapId || !validIsoDate(body.expiresAt) || !Array.isArray(body.scopes) || body.scopes.join("\0") !== [...scopes].sort().join("\0")) {
|
|
2472
|
-
return { error: "Map capability response was invalid.", ok: false };
|
|
2473
|
-
}
|
|
2474
|
-
return { capability: body.capability, mapId: body.mapId, ok: true };
|
|
2475
|
-
}
|
|
2476
|
-
async function requestProjectCapability(session, project, scopes, options = {}) {
|
|
2477
|
-
let response;
|
|
2478
|
-
try {
|
|
2479
|
-
response = await requestHostedJson(
|
|
2480
|
-
session.apiOrigin,
|
|
2481
|
-
"/v1/cli/project-capabilities",
|
|
2482
|
-
{
|
|
2483
|
-
...jsonRequest("POST", { project, scopes }),
|
|
2484
|
-
headers: {
|
|
2485
|
-
...authorizationHeaders(session.accountSession),
|
|
2486
|
-
"Content-Type": "application/json"
|
|
2487
|
-
}
|
|
2488
|
-
},
|
|
2489
|
-
options
|
|
2490
|
-
);
|
|
2491
|
-
} catch (error) {
|
|
2492
|
-
return {
|
|
2493
|
-
error: safeTransportError(error, "Project capability request failed."),
|
|
2494
|
-
ok: false
|
|
2495
|
-
};
|
|
2496
|
-
}
|
|
2497
2438
|
if (!response.ok) {
|
|
2498
2439
|
return {
|
|
2499
|
-
error: response.status === 401 ? rejectedAccountSessionMessage : `
|
|
2440
|
+
error: response.status === 401 ? rejectedAccountSessionMessage : `Map capability request failed (${response.status}).`,
|
|
2500
2441
|
ok: false
|
|
2501
2442
|
};
|
|
2502
2443
|
}
|
|
2503
2444
|
const body = asRecord(response.body);
|
|
2504
|
-
if (!response.json || typeof body.capability !== "string" || !body.capability.startsWith("tf_cap_") || body.capability.length > 8192 || body.
|
|
2505
|
-
return { error: "
|
|
2445
|
+
if (!response.json || typeof body.capability !== "string" || !body.capability.startsWith("tf_cap_") || body.capability.length > 8192 || typeof body.mapId !== "string" || !/^map_[A-Za-z0-9_-]{16}$/u.test(body.mapId) || body.mapId !== target.mapId || !validIsoDate(body.expiresAt) || !Array.isArray(body.scopes) || body.scopes.join("\0") !== [...scopes].sort().join("\0")) {
|
|
2446
|
+
return { error: "Map capability response was invalid.", ok: false };
|
|
2506
2447
|
}
|
|
2507
|
-
return { capability: body.capability, ok: true };
|
|
2448
|
+
return { capability: body.capability, mapId: body.mapId, ok: true };
|
|
2508
2449
|
}
|
|
2509
2450
|
async function requestTeamCapability(session, team, scopes, options = {}) {
|
|
2510
2451
|
let response;
|
|
@@ -5292,18 +5233,6 @@ async function fetchAccountProjects(session, includeArchived) {
|
|
|
5292
5233
|
}
|
|
5293
5234
|
return { error: "Destination discovery exceeded its safe page limit.", ok: false, status: 502 };
|
|
5294
5235
|
}
|
|
5295
|
-
async function resolveAccountProjectTarget(session, requestedProject) {
|
|
5296
|
-
const result = await fetchAccountProjects(session, false);
|
|
5297
|
-
if (!result.ok) return { error: result.error, kind: "remote", status: result.status };
|
|
5298
|
-
if (requestedProject) {
|
|
5299
|
-
const parsed = parseProjectReference(requestedProject);
|
|
5300
|
-
if (!parsed) return { kind: "invalid", targets: result.items };
|
|
5301
|
-
const target = result.items.find((candidate) => candidate.reference === requestedProject);
|
|
5302
|
-
return target ? { kind: "selected", target } : { kind: "missing", targets: result.items };
|
|
5303
|
-
}
|
|
5304
|
-
if (result.items.length === 1) return { kind: "selected", target: result.items[0] };
|
|
5305
|
-
return result.items.length ? { kind: "ambiguous", targets: result.items } : { kind: "missing", targets: [] };
|
|
5306
|
-
}
|
|
5307
5236
|
async function requireCommandSession(options, dependencies) {
|
|
5308
5237
|
let config;
|
|
5309
5238
|
try {
|
|
@@ -8445,7 +8374,7 @@ program.command("build").description("Generate static Tileflow styles").option("
|
|
|
8445
8374
|
printKeyValue("Output", pathLabel(resolve8(process.cwd(), options.out)));
|
|
8446
8375
|
}
|
|
8447
8376
|
);
|
|
8448
|
-
program.command("preview").
|
|
8377
|
+
program.command("preview").description("Run a local map preview").option("-c, --config <path>", "config path", defaultConfigPath).option("--against-config <path>", "second config for the comparison workbench").option("--against-map <name>", "map on the right; defaults to --map").option("--against-scene <name>", "committed standalone scene on the right").option("--against-theme <name>", "concrete theme on the right; defaults to --theme").option("--host <host>", "bind host: an explicit IP address or localhost", defaultTileflowDevHost).option("--map <name>", "preview one configured map").option("--theme <name>", "preview one concrete theme; defaults to the map default").option("--renderer <renderer>", "artifact renderer: web or native", "web").option("-p, --port <port>", "preview port", "3333").option("--scene <name>", "preview one committed standalone map scene").option(
|
|
8449
8378
|
"--api-base-url <url>",
|
|
8450
8379
|
"Tileflow API base URL used to resolve official map assets",
|
|
8451
8380
|
process.env.TILEFLOW_API_URL ?? defaultApiUrl
|
|
@@ -8461,7 +8390,7 @@ program.command("preview").alias("dev").description("Run a local map preview").o
|
|
|
8461
8390
|
process.stdout.write(
|
|
8462
8391
|
`${JSON.stringify({
|
|
8463
8392
|
schemaVersion: 1,
|
|
8464
|
-
command: "
|
|
8393
|
+
command: "preview",
|
|
8465
8394
|
event: "error",
|
|
8466
8395
|
code: first?.code ?? "NATIVE_RENDERER_UNSUPPORTED",
|
|
8467
8396
|
phase: first?.phase ?? "command-validation",
|
|
@@ -8481,7 +8410,7 @@ program.command("preview").alias("dev").description("Run a local map preview").o
|
|
|
8481
8410
|
process.stdout.write(
|
|
8482
8411
|
`${JSON.stringify({
|
|
8483
8412
|
schemaVersion: 1,
|
|
8484
|
-
command: "
|
|
8413
|
+
command: "preview",
|
|
8485
8414
|
event: "error",
|
|
8486
8415
|
code: "NATIVE_RENDERER_UNSUPPORTED",
|
|
8487
8416
|
phase: "command-validation",
|
|
@@ -8613,7 +8542,7 @@ program.command("preview").alias("dev").description("Run a local map preview").o
|
|
|
8613
8542
|
process.stdout.write(
|
|
8614
8543
|
`${JSON.stringify({
|
|
8615
8544
|
schemaVersion: 1,
|
|
8616
|
-
command: "
|
|
8545
|
+
command: "preview",
|
|
8617
8546
|
event: recovered ? "recovered" : state.status,
|
|
8618
8547
|
generation: state.generation,
|
|
8619
8548
|
..."lastGoodGeneration" in state && state.lastGoodGeneration !== void 0 ? { lastGoodGeneration: state.lastGoodGeneration } : {},
|
|
@@ -8682,7 +8611,7 @@ program.command("preview").alias("dev").description("Run a local map preview").o
|
|
|
8682
8611
|
process.stdout.write(
|
|
8683
8612
|
`${JSON.stringify({
|
|
8684
8613
|
schemaVersion: 1,
|
|
8685
|
-
command: "
|
|
8614
|
+
command: "preview",
|
|
8686
8615
|
event: "stopped",
|
|
8687
8616
|
generation,
|
|
8688
8617
|
...nativeLifecycleFields
|
|
@@ -8700,24 +8629,10 @@ program.command("deploy").description("Deploy maps to Tileflow and write the fro
|
|
|
8700
8629
|
).option("--cache-dir <path>", "verified Icon Set artifact cache root").option("--offline", "fail a locked Icon Set cache miss instead of hydrating it").action(
|
|
8701
8630
|
async (options) => {
|
|
8702
8631
|
const source = resolveDeploySource(process.env);
|
|
8703
|
-
const resolveApi = (
|
|
8632
|
+
const resolveApi = () => requireApiOptions(options, {
|
|
8704
8633
|
allowStoredCredential: allowsStoredDeployCredential(source),
|
|
8705
8634
|
assertExplicitKeyMap: true,
|
|
8706
|
-
capabilityScopes: ["styles:write"]
|
|
8707
|
-
retryCommand: cliInvocation([
|
|
8708
|
-
"tileflow",
|
|
8709
|
-
"deploy",
|
|
8710
|
-
"--config",
|
|
8711
|
-
options.config,
|
|
8712
|
-
"--manifest",
|
|
8713
|
-
options.manifest,
|
|
8714
|
-
"--api-url",
|
|
8715
|
-
options.apiUrl ?? defaultApiUrl,
|
|
8716
|
-
...options.overwriteSelfHostedManifest ? ["--overwrite-self-hosted-manifest"] : [],
|
|
8717
|
-
...options.mapId ? ["--map-id", options.mapId] : [],
|
|
8718
|
-
...options.map && selectedMap ? ["--map", selectedMap] : [],
|
|
8719
|
-
...options.withNative ? ["--with-native"] : []
|
|
8720
|
-
])
|
|
8635
|
+
capabilityScopes: ["styles:write"]
|
|
8721
8636
|
});
|
|
8722
8637
|
const apiUrl = normalizeApiOrigin(options.apiUrl ?? defaultApiUrl);
|
|
8723
8638
|
delete process.env.TILEFLOW_API_KEY;
|
|
@@ -8823,7 +8738,7 @@ program.command("deploy").description("Deploy maps to Tileflow and write the fro
|
|
|
8823
8738
|
return;
|
|
8824
8739
|
}
|
|
8825
8740
|
const existingManifest = outputManifest;
|
|
8826
|
-
const api = await resolveApi(
|
|
8741
|
+
const api = await resolveApi();
|
|
8827
8742
|
if (!api) return;
|
|
8828
8743
|
const hostedSpriteByPackageHash = /* @__PURE__ */ new Map();
|
|
8829
8744
|
for (const iconPackage of compiledIcons.packages) {
|
|
@@ -9108,13 +9023,6 @@ program.command("status").description("Show deployed compiled styles").option("-
|
|
|
9108
9023
|
try {
|
|
9109
9024
|
api = await requireApiOptions(options, {
|
|
9110
9025
|
capabilityScopes: ["status:read"],
|
|
9111
|
-
retryCommand: cliInvocation([
|
|
9112
|
-
"tileflow",
|
|
9113
|
-
"status",
|
|
9114
|
-
"--api-url",
|
|
9115
|
-
options.apiUrl ?? defaultApiUrl,
|
|
9116
|
-
...options.json ? ["--json"] : []
|
|
9117
|
-
]),
|
|
9118
9026
|
silent: options.json
|
|
9119
9027
|
});
|
|
9120
9028
|
} catch (error) {
|
|
@@ -9164,18 +9072,6 @@ registerIconDiffCommand(iconsCommand, {
|
|
|
9164
9072
|
assertExplicitKeyMap: true,
|
|
9165
9073
|
allowStoredCredential: allowsStoredDeployCredential(source),
|
|
9166
9074
|
capabilityScopes: ["status:read"],
|
|
9167
|
-
retryCommand: cliInvocation([
|
|
9168
|
-
"tileflow",
|
|
9169
|
-
"icons",
|
|
9170
|
-
"diff",
|
|
9171
|
-
"--against",
|
|
9172
|
-
options.against,
|
|
9173
|
-
...options.config ? ["--config", options.config] : [],
|
|
9174
|
-
"--map-id",
|
|
9175
|
-
options.mapId,
|
|
9176
|
-
"--api-url",
|
|
9177
|
-
options.apiUrl ?? defaultApiUrl
|
|
9178
|
-
]),
|
|
9179
9075
|
silent: true
|
|
9180
9076
|
});
|
|
9181
9077
|
}
|
|
@@ -9223,7 +9119,7 @@ async function runTileflowComparisonPreview(options, address) {
|
|
|
9223
9119
|
const emit = (event) => {
|
|
9224
9120
|
if (!options.json) return;
|
|
9225
9121
|
process.stdout.write(
|
|
9226
|
-
`${JSON.stringify({ schemaVersion: 1, command: "
|
|
9122
|
+
`${JSON.stringify({ schemaVersion: 1, command: "preview.compare", ...event })}
|
|
9227
9123
|
`
|
|
9228
9124
|
);
|
|
9229
9125
|
};
|
|
@@ -9613,19 +9509,13 @@ async function loadExistingDeployManifest(manifestPath, options) {
|
|
|
9613
9509
|
async function requireApiOptions(options, behavior = {}) {
|
|
9614
9510
|
const apiUrl = normalizeApiOrigin(options.apiUrl ?? defaultApiUrl);
|
|
9615
9511
|
const requestedMapId = options.mapId;
|
|
9616
|
-
|
|
9617
|
-
if (requestedMapId && !/^map_[A-Za-z0-9_-]{16}$/u.test(requestedMapId)) {
|
|
9512
|
+
if (!requestedMapId || !/^map_[A-Za-z0-9_-]{16}$/u.test(requestedMapId)) {
|
|
9618
9513
|
if (!behavior.silent) logError("Managed Map ID is invalid.");
|
|
9619
9514
|
process.exitCode = 1;
|
|
9620
9515
|
return null;
|
|
9621
9516
|
}
|
|
9622
|
-
if (options.project && !requested) {
|
|
9623
|
-
if (!behavior.silent) logError("Managed destination must use @organization/project syntax.");
|
|
9624
|
-
process.exitCode = 1;
|
|
9625
|
-
return null;
|
|
9626
|
-
}
|
|
9627
9517
|
if (options.apiKey) {
|
|
9628
|
-
if (
|
|
9518
|
+
if (behavior.assertExplicitKeyMap) {
|
|
9629
9519
|
const profile = await validateApiKey(apiUrl, options.apiKey);
|
|
9630
9520
|
if (!profile.ok) {
|
|
9631
9521
|
if (!behavior.silent) logError(profile.error);
|
|
@@ -9638,33 +9528,7 @@ async function requireApiOptions(options, behavior = {}) {
|
|
|
9638
9528
|
return null;
|
|
9639
9529
|
}
|
|
9640
9530
|
}
|
|
9641
|
-
|
|
9642
|
-
const profile = await validateApiKey(apiUrl, options.apiKey);
|
|
9643
|
-
if (!profile.ok) {
|
|
9644
|
-
if (!behavior.silent) logError(profile.error);
|
|
9645
|
-
process.exitCode = 1;
|
|
9646
|
-
return null;
|
|
9647
|
-
}
|
|
9648
|
-
if (profile.value.credentialType === "team_api_key") {
|
|
9649
|
-
if (!behavior.silent) logError("Team credentials require an explicit --map-id.");
|
|
9650
|
-
process.exitCode = 1;
|
|
9651
|
-
return null;
|
|
9652
|
-
}
|
|
9653
|
-
if (requested && projectReference(profile.value) !== options.project) {
|
|
9654
|
-
if (!behavior.silent) {
|
|
9655
|
-
logError(
|
|
9656
|
-
`This project key belongs to ${projectReference(profile.value)}, not ${options.project}.`
|
|
9657
|
-
);
|
|
9658
|
-
}
|
|
9659
|
-
process.exitCode = 1;
|
|
9660
|
-
return null;
|
|
9661
|
-
}
|
|
9662
|
-
}
|
|
9663
|
-
return {
|
|
9664
|
-
apiKey: options.apiKey,
|
|
9665
|
-
apiUrl,
|
|
9666
|
-
...requestedMapId ? { mapId: requestedMapId } : {}
|
|
9667
|
-
};
|
|
9531
|
+
return { apiKey: options.apiKey, apiUrl, mapId: requestedMapId };
|
|
9668
9532
|
}
|
|
9669
9533
|
const allowStoredCredential = behavior.allowStoredCredential !== false && allowsStoredDeployCredential(resolveDeploySource(process.env));
|
|
9670
9534
|
if (!allowStoredCredential) {
|
|
@@ -9697,46 +9561,9 @@ async function requireApiOptions(options, behavior = {}) {
|
|
|
9697
9561
|
process.exitCode = 1;
|
|
9698
9562
|
return null;
|
|
9699
9563
|
}
|
|
9700
|
-
|
|
9701
|
-
const capability2 = await requestMapCapability(
|
|
9702
|
-
resolvedSession.session,
|
|
9703
|
-
{ mapId: requestedMapId },
|
|
9704
|
-
behavior.capabilityScopes ?? ["status:read"]
|
|
9705
|
-
);
|
|
9706
|
-
if (!capability2.ok) {
|
|
9707
|
-
if (!behavior.silent) logError(capability2.error);
|
|
9708
|
-
process.exitCode = 1;
|
|
9709
|
-
return null;
|
|
9710
|
-
}
|
|
9711
|
-
return { apiKey: capability2.capability, apiUrl, mapId: capability2.mapId };
|
|
9712
|
-
}
|
|
9713
|
-
const target = await resolveAccountProjectTarget(resolvedSession.session, options.project);
|
|
9714
|
-
if (target.kind === "remote") {
|
|
9715
|
-
if (!behavior.silent) logError(target.error);
|
|
9716
|
-
process.exitCode = 1;
|
|
9717
|
-
return null;
|
|
9718
|
-
}
|
|
9719
|
-
if (target.kind !== "selected") {
|
|
9720
|
-
if (!behavior.silent) {
|
|
9721
|
-
const references = target.targets.map((candidate) => candidate.reference);
|
|
9722
|
-
if (target.kind === "ambiguous") {
|
|
9723
|
-
const retry = `${behavior.retryCommand ?? "tileflow <command>"} --project ${references[0]}`;
|
|
9724
|
-
logError(`Managed destination is ambiguous: ${references.join(", ")}.`);
|
|
9725
|
-
printNextSteps([`Retry exactly with ${command(retry)}.`]);
|
|
9726
|
-
} else if (target.kind === "invalid") {
|
|
9727
|
-
logError("Managed destination must use @organization/project syntax.");
|
|
9728
|
-
} else {
|
|
9729
|
-
logError(
|
|
9730
|
-
options.project ? `Destination ${options.project} is not accessible to this account.` : "No active managed destination is accessible to this account."
|
|
9731
|
-
);
|
|
9732
|
-
}
|
|
9733
|
-
}
|
|
9734
|
-
process.exitCode = 1;
|
|
9735
|
-
return null;
|
|
9736
|
-
}
|
|
9737
|
-
const capability = await requestProjectCapability(
|
|
9564
|
+
const capability = await requestMapCapability(
|
|
9738
9565
|
resolvedSession.session,
|
|
9739
|
-
|
|
9566
|
+
{ mapId: requestedMapId },
|
|
9740
9567
|
behavior.capabilityScopes ?? ["status:read"]
|
|
9741
9568
|
);
|
|
9742
9569
|
if (!capability.ok) {
|
|
@@ -9744,7 +9571,7 @@ async function requireApiOptions(options, behavior = {}) {
|
|
|
9744
9571
|
process.exitCode = 1;
|
|
9745
9572
|
return null;
|
|
9746
9573
|
}
|
|
9747
|
-
return { apiKey: capability.capability, apiUrl };
|
|
9574
|
+
return { apiKey: capability.capability, apiUrl, mapId: capability.mapId };
|
|
9748
9575
|
}
|
|
9749
9576
|
function printTileflowPreviewError(error) {
|
|
9750
9577
|
if (error instanceof TileflowStyleValidationError2) {
|
|
@@ -9895,12 +9722,6 @@ function plural(count, singular, pluralForm = `${singular}s`) {
|
|
|
9895
9722
|
function command(value) {
|
|
9896
9723
|
return pc6.cyan(value);
|
|
9897
9724
|
}
|
|
9898
|
-
function cliInvocation(parts) {
|
|
9899
|
-
return parts.map(quoteCliArgument).join(" ");
|
|
9900
|
-
}
|
|
9901
|
-
function quoteCliArgument(value) {
|
|
9902
|
-
return /^[A-Za-z0-9_./:@%+=,-]+$/u.test(value) ? value : `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
9903
|
-
}
|
|
9904
9725
|
function link(value) {
|
|
9905
9726
|
return pc6.cyan(value);
|
|
9906
9727
|
}
|
|
@@ -37,8 +37,8 @@ npx tileflow preview --scene madrid-mobile
|
|
|
37
37
|
To work on another map, point `--config` at another singular config. Multi-map catalogs are internal
|
|
38
38
|
orchestration used by this repository's workbench and are not a second public config shape.
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
The `preview` name distinguishes this SDK preview server from an application's own `npm run dev`
|
|
41
|
+
process.
|
|
42
42
|
|
|
43
43
|
`--api-base-url` selects the origin used by official World, Bathymetry vector, Bathymetry DEM,
|
|
44
44
|
Nautical, and terrain TileJSON sources in the generated preview style. In particular, a hybrid
|
package/docs/command-families.md
CHANGED
|
@@ -5,7 +5,7 @@ Start with the [tileflow guide](https://github.com/tileflow/tileflow-sdk/blob/ma
|
|
|
5
5
|
| Family | Commands |
|
|
6
6
|
| ----------------- | ---------------------------------------------------------------------------------------------- |
|
|
7
7
|
| Semantic language | `language manifest`, `language schema` |
|
|
8
|
-
| Map authoring | `init`, `validate`, `inspect`, `explain`, `semantic-diff`, `build`, `preview`
|
|
8
|
+
| Map authoring | `init`, `validate`, `inspect`, `explain`, `semantic-diff`, `build`, `preview` |
|
|
9
9
|
| Local evidence | `setup capture`, `capture`, `visual compare`, `visual analyze`, `visual diff`, `visual update` |
|
|
10
10
|
| Data and assets | `tileset inspect`, `tileset publish/list/status/purge`, `inspect features`, `icons list/diff` |
|
|
11
11
|
| Team Icon Sets | `icon-set publish/list/status/versions/uses/archive/unarchive/purge` |
|
|
@@ -15,7 +15,7 @@ Start with the [tileflow guide](https://github.com/tileflow/tileflow-sdk/blob/ma
|
|
|
15
15
|
|
|
16
16
|
Run `tileflow <command> --help` (or the family help, such as `tileflow icons --help`) for the exact
|
|
17
17
|
arguments and bounded JSON modes. `preview` defaults to the existing web renderer. The explicit
|
|
18
|
-
`preview --renderer native`
|
|
18
|
+
`preview --renderer native` mode serves watched `native-v1` artifacts only;
|
|
19
19
|
Metro remains the React Native JavaScript development server. See
|
|
20
20
|
[Native artifacts and local preview](./native-artifacts.md) for the endpoint and qualification
|
|
21
21
|
boundary.
|
|
@@ -28,5 +28,5 @@ authority when resolving revisions and are the only commands that select revisio
|
|
|
28
28
|
`tileflow.icons.lock.json`. See the
|
|
29
29
|
[Team Icon Set workflow](https://github.com/tileflow/tileflow-sdk/blob/main/packages/cli/docs/team-icon-sets.md).
|
|
30
30
|
|
|
31
|
-
The
|
|
32
|
-
|
|
31
|
+
The hidden `projects` command family lists and manages the internal application destinations of an
|
|
32
|
+
account for support. It is not part of the ordinary workflow or the product catalog.
|
package/docs/native-artifacts.md
CHANGED
|
@@ -30,7 +30,7 @@ The ordinary web commands and their default artifact bytes retain their existing
|
|
|
30
30
|
|
|
31
31
|
## Watch and serve native artifacts
|
|
32
32
|
|
|
33
|
-
`preview`
|
|
33
|
+
`preview` selects the renderer with `--renderer`:
|
|
34
34
|
|
|
35
35
|
```sh
|
|
36
36
|
npx tileflow preview --renderer native --map stores --theme light
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tileflow",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.11",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "CLI-only tools for Tileflow config, capture, visual testing, and deploy.",
|
|
6
6
|
"type": "module",
|
|
@@ -35,15 +35,15 @@
|
|
|
35
35
|
"access": "public"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@hono/node-server": "2.
|
|
39
|
-
"@tileflow/capture": ">=0.1.0-alpha.
|
|
40
|
-
"@tileflow/coordinates": ">=0.1.0-alpha.
|
|
41
|
-
"@tileflow/coordinates-runtime": ">=0.1.0-alpha.
|
|
42
|
-
"@tileflow/core": ">=0.1.0-alpha.
|
|
43
|
-
"@tileflow/dev": ">=0.1.0-alpha.
|
|
44
|
-
"@tileflow/maps": ">=0.1.0-alpha.
|
|
38
|
+
"@hono/node-server": "2.1.3",
|
|
39
|
+
"@tileflow/capture": ">=0.1.0-alpha.29 <0.1.0-beta.0",
|
|
40
|
+
"@tileflow/coordinates": ">=0.1.0-alpha.2 <0.1.0-beta.0",
|
|
41
|
+
"@tileflow/coordinates-runtime": ">=0.1.0-alpha.5 <0.1.0-beta.0",
|
|
42
|
+
"@tileflow/core": ">=0.1.0-alpha.32 <0.1.0-beta.0",
|
|
43
|
+
"@tileflow/dev": ">=0.1.0-alpha.30 <0.1.0-beta.0",
|
|
44
|
+
"@tileflow/maps": ">=0.1.0-alpha.8 <0.1.0-beta.0",
|
|
45
45
|
"commander": "^15.0.0",
|
|
46
|
-
"hono": "4.13.
|
|
46
|
+
"hono": "4.13.7",
|
|
47
47
|
"picocolors": "^1.1.1",
|
|
48
48
|
"zod": "^4.4.3"
|
|
49
49
|
},
|