tileflow 0.1.0-alpha.20 → 0.1.0-alpha.21

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.
Files changed (3) hide show
  1. package/README.md +4 -4
  2. package/dist/index.js +43 -15
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -269,10 +269,10 @@ npx tileflow tileset publish ./data/stores.pmtiles --id stores --team @acme --at
269
269
  npx tileflow tileset status stores --team @acme --json
270
270
  ```
271
271
 
272
- Use your own file, Team selector, and attribution. Inspection is account-free. Publication validates
273
- and uploads a managed dataset using Team data authority, not a map-only deploy key. Interrupted
274
- uploads are resumable; a completed version becomes current at stable delivery URLs. Purge is
275
- explicit, requires confirmation, and can be blocked by retained deployment dependencies.
272
+ Use your own file, Team and attribution. Inspection needs no account. Publication requires Team data
273
+ authority and renews account-backed authorization during long transfers and validation. Interrupted
274
+ uploads resume; published versions become current at stable delivery URLs. Purge requires confirmation
275
+ and can be blocked by retained deployment dependencies.
276
276
 
277
277
  Administratively disabled uploads return `TF_TILESET_UPLOAD_DISABLED` without retrying.
278
278
  Temporary service failures retain bounded retries.
package/dist/index.js CHANGED
@@ -4501,7 +4501,7 @@ async function requestTeamCapability(session, team, scopes, options = {}) {
4501
4501
  if (!response.json || body.schemaVersion !== 1 || typeof body.capability !== "string" || !body.capability.startsWith("tf_cap_") || body.capability.length > 8192 || body.reference !== team || !isProjectIdentity(body.team) || `@${body.team.slug}` !== team || !validIsoDate(body.expiresAt) || !Array.isArray(body.scopes) || body.scopes.join("\0") !== [...scopes].sort().join("\0")) {
4502
4502
  return { error: "Team capability response was invalid.", ok: false };
4503
4503
  }
4504
- return { capability: body.capability, ok: true, team: body.team };
4504
+ return { capability: body.capability, expiresAt: body.expiresAt, ok: true, team: body.team };
4505
4505
  }
4506
4506
  async function listAccountTeams(session, options = {}) {
4507
4507
  const response = await requestHostedJson(
@@ -6308,20 +6308,41 @@ async function resolveTeamAuthority(options, scopes, dependencies) {
6308
6308
  return null;
6309
6309
  }
6310
6310
  const capability = await requestTeamCapability(selected.session, `@${team.slug}`, scopes);
6311
- if (!capability.ok) {
6312
- emitFailure(options.json, "team_capability_failed", capability.error);
6311
+ if (!capability.ok || capability.team.id !== team.id) {
6312
+ emitFailure(
6313
+ options.json,
6314
+ "team_capability_failed",
6315
+ capability.ok ? "Team capability response was invalid." : capability.error
6316
+ );
6313
6317
  return null;
6314
6318
  }
6319
+ let current = capability;
6320
+ let renewal;
6321
+ const getCredential = async () => {
6322
+ if (Date.parse(current.expiresAt) > Date.now() + 3e4) return current.capability;
6323
+ renewal ??= requestTeamCapability(selected.session, `@${team.slug}`, scopes).then((next) => {
6324
+ if (!next.ok || next.team.id !== team.id || Date.parse(next.expiresAt) <= Date.now() + 3e4) {
6325
+ throw new Error("Team authorization could not be renewed. Run tileflow login.");
6326
+ }
6327
+ current = next;
6328
+ }).finally(() => {
6329
+ renewal = void 0;
6330
+ });
6331
+ await renewal;
6332
+ return current.capability;
6333
+ };
6315
6334
  return {
6316
6335
  apiOrigin: selected.session.apiOrigin,
6317
6336
  credential: capability.capability,
6337
+ getCredential,
6318
6338
  team
6319
6339
  };
6320
6340
  }
6321
- function authorizedTeamRequest(authority, path, method, init = {}) {
6341
+ async function authorizedTeamRequest(authority, path, method, init = {}) {
6342
+ const credential = await authority.getCredential?.() ?? authority.credential;
6322
6343
  return requestHostedJson(authority.apiOrigin, path, {
6323
6344
  ...init.body === void 0 ? {} : { body: init.body },
6324
- headers: { Authorization: `Bearer ${authority.credential}`, ...init.headers },
6345
+ headers: { Authorization: `Bearer ${credential}`, ...init.headers },
6325
6346
  method
6326
6347
  });
6327
6348
  }
@@ -8536,6 +8557,15 @@ function createHostedTeamTilesetUploadTransport(input) {
8536
8557
  const basePath = `/v1/tilesets/${encodeURIComponent(input.tilesetId)}/uploads`;
8537
8558
  const control = async (path, init) => {
8538
8559
  for (let attempt = 1; attempt <= maximumControlAttempts; attempt += 1) {
8560
+ let credential;
8561
+ try {
8562
+ credential = await input.getCredential?.() ?? input.credential;
8563
+ } catch {
8564
+ throw new TeamTilesetUploadError(
8565
+ "TF_TILESET_UPLOAD_UNAVAILABLE",
8566
+ "Team authorization could not be renewed. Run tileflow login and retry the upload."
8567
+ );
8568
+ }
8539
8569
  let response;
8540
8570
  try {
8541
8571
  response = await requestHostedJson(
@@ -8544,7 +8574,7 @@ function createHostedTeamTilesetUploadTransport(input) {
8544
8574
  {
8545
8575
  ...init,
8546
8576
  headers: {
8547
- Authorization: `Bearer ${input.credential}`,
8577
+ Authorization: `Bearer ${credential}`,
8548
8578
  ...init.body ? { "Content-Type": "application/json" } : {},
8549
8579
  ...init.headers
8550
8580
  }
@@ -9000,7 +9030,7 @@ function registerTilesetCommands(program2, dependencies) {
9000
9030
  const prepared = await prepareTeamTilesetUpload(uploadFile);
9001
9031
  const authority = await resolveTeamAuthority(options, ["tilesets:write"], dependencies);
9002
9032
  if (!authority) return;
9003
- const registration = await requestHostedJson(authority.apiOrigin, "/v1/tilesets", {
9033
+ const registration = await authorizedTeamRequest(authority, "/v1/tilesets", "POST", {
9004
9034
  body: JSON.stringify({
9005
9035
  ...options.attribution ? { attribution: options.attribution } : {},
9006
9036
  format: "pmtiles",
@@ -9008,10 +9038,8 @@ function registerTilesetCommands(program2, dependencies) {
9008
9038
  slug: options.id
9009
9039
  }),
9010
9040
  headers: {
9011
- Authorization: `Bearer ${authority.credential}`,
9012
9041
  "Content-Type": "application/json"
9013
- },
9014
- method: "POST"
9042
+ }
9015
9043
  });
9016
9044
  const registered = asRecord4(registration.body);
9017
9045
  const resourceId = String(registered.tilesetId ?? "");
@@ -9044,6 +9072,7 @@ function registerTilesetCommands(program2, dependencies) {
9044
9072
  transport: createHostedTeamTilesetUploadTransport({
9045
9073
  apiOrigin: authority.apiOrigin,
9046
9074
  credential: authority.credential,
9075
+ getCredential: authority.getCredential,
9047
9076
  tilesetId: resourceId
9048
9077
  }),
9049
9078
  upload: prepared
@@ -9133,15 +9162,14 @@ function registerTilesetCommands(program2, dependencies) {
9133
9162
  }
9134
9163
  const authority = await resolveTeamAuthority(options, ["tilesets:write"], dependencies);
9135
9164
  if (!authority) return;
9136
- const response = await requestHostedJson(
9137
- authority.apiOrigin,
9165
+ const response = await authorizedTeamRequest(
9166
+ authority,
9138
9167
  `/v1/tilesets/${encodeURIComponent(id)}`,
9168
+ "DELETE",
9139
9169
  {
9140
9170
  headers: {
9141
- Authorization: `Bearer ${authority.credential}`,
9142
9171
  "X-Tileflow-Confirm-Tileset-Purge": id
9143
- },
9144
- method: "DELETE"
9172
+ }
9145
9173
  }
9146
9174
  );
9147
9175
  if (!response.ok) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tileflow",
3
- "version": "0.1.0-alpha.20",
3
+ "version": "0.1.0-alpha.21",
4
4
  "license": "Apache-2.0",
5
5
  "description": "CLI-only tools for Tileflow config, capture, visual testing, and deploy.",
6
6
  "type": "module",
@@ -38,8 +38,8 @@
38
38
  "@tileflow/capture": ">=0.1.0-alpha.37 <0.1.0-beta.0",
39
39
  "@tileflow/coordinates": ">=0.1.0-alpha.3 <0.1.0-beta.0",
40
40
  "@tileflow/coordinates-runtime": ">=0.1.0-alpha.6 <0.1.0-beta.0",
41
- "@tileflow/core": ">=0.1.0-alpha.45 <0.1.0-beta.0",
42
- "@tileflow/dev": ">=0.1.0-alpha.41 <0.1.0-beta.0",
41
+ "@tileflow/core": ">=0.1.0-alpha.46 <0.1.0-beta.0",
42
+ "@tileflow/dev": ">=0.1.0-alpha.42 <0.1.0-beta.0",
43
43
  "@tileflow/maps": ">=0.1.0-alpha.18 <0.1.0-beta.0",
44
44
  "commander": "^15.0.0",
45
45
  "hono": "4.13.14",