@eide/foir-cli 0.21.0 → 0.22.0
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/cli.js +199 -16
- package/dist/lib/config-helpers.d.ts +35 -1
- package/dist/lib/config-helpers.js +4 -0
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import { config } from "dotenv";
|
|
5
|
-
import { resolve as
|
|
5
|
+
import { resolve as resolve7, dirname as dirname4 } from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
import { createRequire } from "module";
|
|
8
8
|
import { Command } from "commander";
|
|
@@ -303,13 +303,13 @@ function withErrorHandler(optsFn, fn) {
|
|
|
303
303
|
// src/commands/login.ts
|
|
304
304
|
async function findAvailablePort(start, end) {
|
|
305
305
|
for (let port = start; port <= end; port++) {
|
|
306
|
-
const available = await new Promise((
|
|
306
|
+
const available = await new Promise((resolve8) => {
|
|
307
307
|
const server = http.createServer();
|
|
308
308
|
server.listen(port, () => {
|
|
309
309
|
server.close();
|
|
310
|
-
|
|
310
|
+
resolve8(true);
|
|
311
311
|
});
|
|
312
|
-
server.on("error", () =>
|
|
312
|
+
server.on("error", () => resolve8(false));
|
|
313
313
|
});
|
|
314
314
|
if (available) return port;
|
|
315
315
|
}
|
|
@@ -347,7 +347,7 @@ async function loginAction(globalOpts) {
|
|
|
347
347
|
const state = crypto.randomBytes(16).toString("hex");
|
|
348
348
|
const port = await findAvailablePort(9876, 9900);
|
|
349
349
|
const redirectUri = `http://localhost:${port}/callback`;
|
|
350
|
-
const authCode = await new Promise((
|
|
350
|
+
const authCode = await new Promise((resolve8, reject) => {
|
|
351
351
|
let timeoutId;
|
|
352
352
|
const server = http.createServer((req, res) => {
|
|
353
353
|
const url = new URL(req.url, `http://localhost:${port}`);
|
|
@@ -386,7 +386,7 @@ async function loginAction(globalOpts) {
|
|
|
386
386
|
);
|
|
387
387
|
server.closeAllConnections();
|
|
388
388
|
server.close();
|
|
389
|
-
|
|
389
|
+
resolve8(code);
|
|
390
390
|
}
|
|
391
391
|
});
|
|
392
392
|
server.listen(port);
|
|
@@ -2131,6 +2131,11 @@ import {
|
|
|
2131
2131
|
UpdateLocaleRequestSchema,
|
|
2132
2132
|
DeleteLocaleRequestSchema,
|
|
2133
2133
|
DeleteSettingRequestSchema,
|
|
2134
|
+
GetDesignTokensRequestSchema,
|
|
2135
|
+
UpdateDesignTokensRequestSchema,
|
|
2136
|
+
PublishDesignTokensRequestSchema,
|
|
2137
|
+
UnpublishDesignTokensRequestSchema,
|
|
2138
|
+
GetDesignTokensPublishStatusRequestSchema,
|
|
2134
2139
|
GetNavPreferencesRequestSchema,
|
|
2135
2140
|
UpdateNavPreferencesRequestSchema,
|
|
2136
2141
|
ListRecentlyOpenedRequestSchema,
|
|
@@ -2317,6 +2322,39 @@ function createSettingsMethods(client) {
|
|
|
2317
2322
|
);
|
|
2318
2323
|
return resp.profileSchema ?? null;
|
|
2319
2324
|
},
|
|
2325
|
+
// ── Design Tokens ─────────────────────────────────────────
|
|
2326
|
+
async getDesignTokens(params = {}) {
|
|
2327
|
+
const resp = await client.getDesignTokens(
|
|
2328
|
+
create7(GetDesignTokensRequestSchema, {
|
|
2329
|
+
channel: params.channel === "draft" ? 2 : 1
|
|
2330
|
+
})
|
|
2331
|
+
);
|
|
2332
|
+
return resp.tokens ?? null;
|
|
2333
|
+
},
|
|
2334
|
+
async updateDesignTokens(document) {
|
|
2335
|
+
const resp = await client.updateDesignTokens(
|
|
2336
|
+
create7(UpdateDesignTokensRequestSchema, { document })
|
|
2337
|
+
);
|
|
2338
|
+
return resp.tokens ?? null;
|
|
2339
|
+
},
|
|
2340
|
+
async publishDesignTokens() {
|
|
2341
|
+
const resp = await client.publishDesignTokens(
|
|
2342
|
+
create7(PublishDesignTokensRequestSchema, {})
|
|
2343
|
+
);
|
|
2344
|
+
return resp;
|
|
2345
|
+
},
|
|
2346
|
+
async unpublishDesignTokens() {
|
|
2347
|
+
const resp = await client.unpublishDesignTokens(
|
|
2348
|
+
create7(UnpublishDesignTokensRequestSchema, {})
|
|
2349
|
+
);
|
|
2350
|
+
return resp.tokens ?? null;
|
|
2351
|
+
},
|
|
2352
|
+
async getDesignTokensPublishStatus() {
|
|
2353
|
+
const resp = await client.getDesignTokensPublishStatus(
|
|
2354
|
+
create7(GetDesignTokensPublishStatusRequestSchema, {})
|
|
2355
|
+
);
|
|
2356
|
+
return resp.status ?? null;
|
|
2357
|
+
},
|
|
2320
2358
|
async getCustomerResolutionAttributes(customerId) {
|
|
2321
2359
|
return client.getCustomerResolutionAttributes(
|
|
2322
2360
|
create7(GetCustomerResolutionAttributesRequestSchema, { customerId })
|
|
@@ -4841,6 +4879,8 @@ async function reconcileConfig(client, configId, manifest, options = {}) {
|
|
|
4841
4879
|
authProviders: zeroCounts(),
|
|
4842
4880
|
placementsUpdated: false,
|
|
4843
4881
|
profileSchemaUpdated: false,
|
|
4882
|
+
designTokensUpdated: false,
|
|
4883
|
+
designTokensPublished: false,
|
|
4844
4884
|
apiKeys: [],
|
|
4845
4885
|
apps: zeroCounts(),
|
|
4846
4886
|
updatedModelIds: [],
|
|
@@ -4858,6 +4898,7 @@ async function reconcileConfig(client, configId, manifest, options = {}) {
|
|
|
4858
4898
|
await reconcileAuthProviders(client, manifest.authProviders ?? [], summary);
|
|
4859
4899
|
await reconcilePlacements(client, configId, manifest.placements ?? [], summary);
|
|
4860
4900
|
await reconcileProfileSchema(client, manifest, summary);
|
|
4901
|
+
await reconcileDesignTokens(client, manifest, summary, options.publishDesignTokens ?? false);
|
|
4861
4902
|
await reconcileApiKeys(
|
|
4862
4903
|
client,
|
|
4863
4904
|
manifest.key,
|
|
@@ -4905,7 +4946,7 @@ async function reconcileModels(client, configId, models, summary, force, conflic
|
|
|
4905
4946
|
const cfgFields = m.fields ?? [];
|
|
4906
4947
|
const platFields = ex.fields ?? [];
|
|
4907
4948
|
const snapFields = ex.lastPushedFields;
|
|
4908
|
-
const hasSnapshot =
|
|
4949
|
+
const hasSnapshot = ex.lastPushedAt != null;
|
|
4909
4950
|
const { merged, conflicts } = threeWayMergeKeyed(
|
|
4910
4951
|
indexByKey(cfgFields),
|
|
4911
4952
|
indexByKey(platFields),
|
|
@@ -4930,7 +4971,8 @@ async function reconcileModels(client, configId, models, summary, force, conflic
|
|
|
4930
4971
|
if (manifestKeys.has(key)) continue;
|
|
4931
4972
|
const platFields = ex.fields ?? [];
|
|
4932
4973
|
const snapFields = ex.lastPushedFields;
|
|
4933
|
-
|
|
4974
|
+
const hasSnapshot = ex.lastPushedAt != null;
|
|
4975
|
+
if (hasSnapshot && !deepEqual(platFields, snapFields)) {
|
|
4934
4976
|
conflictOut.push({
|
|
4935
4977
|
modelKey: key,
|
|
4936
4978
|
fieldKey: "<model>",
|
|
@@ -5269,6 +5311,18 @@ async function reconcileProfileSchema(client, manifest, summary) {
|
|
|
5269
5311
|
});
|
|
5270
5312
|
summary.profileSchemaUpdated = true;
|
|
5271
5313
|
}
|
|
5314
|
+
async function reconcileDesignTokens(client, manifest, summary, publishAfterApply) {
|
|
5315
|
+
const tokens = manifest.designTokens;
|
|
5316
|
+
if (!tokens) return;
|
|
5317
|
+
await client.settings.updateDesignTokens(
|
|
5318
|
+
tokens
|
|
5319
|
+
);
|
|
5320
|
+
summary.designTokensUpdated = true;
|
|
5321
|
+
if (publishAfterApply) {
|
|
5322
|
+
await client.settings.publishDesignTokens();
|
|
5323
|
+
summary.designTokensPublished = true;
|
|
5324
|
+
}
|
|
5325
|
+
}
|
|
5272
5326
|
async function reconcileApiKeys(client, configKey, apiKeys, summary, rotateKeys) {
|
|
5273
5327
|
if (apiKeys.length === 0) return;
|
|
5274
5328
|
const existing = await client.identity.listApiKeys({ limit: 200 });
|
|
@@ -5552,6 +5606,10 @@ function printSummary(summary) {
|
|
|
5552
5606
|
if (summary.profileSchemaUpdated) {
|
|
5553
5607
|
lines.push(" Profile: schema updated");
|
|
5554
5608
|
}
|
|
5609
|
+
if (summary.designTokensUpdated) {
|
|
5610
|
+
const detail = summary.designTokensPublished ? "applied & published" : "applied (draft)";
|
|
5611
|
+
lines.push(` Design tokens: ${detail}`);
|
|
5612
|
+
}
|
|
5555
5613
|
if (lines.length > 0) {
|
|
5556
5614
|
for (const line of lines) {
|
|
5557
5615
|
console.log(line);
|
|
@@ -5571,6 +5629,10 @@ function registerPushCommand(program2, globalOpts) {
|
|
|
5571
5629
|
"--publish",
|
|
5572
5630
|
"Promote updated models, operations, auth providers, and profile schema to the published channel after the push. New resources auto-publish; this flag covers updates, which are otherwise left as drafts.",
|
|
5573
5631
|
false
|
|
5632
|
+
).option(
|
|
5633
|
+
"--publish-tokens",
|
|
5634
|
+
"Promote applied design tokens to the published channel after the push. Without this flag, tokens land on the draft channel and the storefront keeps serving the last published snapshot.",
|
|
5635
|
+
false
|
|
5574
5636
|
).option("--env <path>", "Path to .env file (default: .env)").action(
|
|
5575
5637
|
withErrorHandler(
|
|
5576
5638
|
globalOpts,
|
|
@@ -5630,7 +5692,8 @@ function registerPushCommand(program2, globalOpts) {
|
|
|
5630
5692
|
rotateKeys: opts.rotateKeys ?? false,
|
|
5631
5693
|
tenantId: resolved?.project.tenantId,
|
|
5632
5694
|
projectId: resolved?.project.id,
|
|
5633
|
-
force: opts.force ?? false
|
|
5695
|
+
force: opts.force ?? false,
|
|
5696
|
+
publishDesignTokens: opts.publishTokens ?? false
|
|
5634
5697
|
});
|
|
5635
5698
|
} catch (e) {
|
|
5636
5699
|
if (e instanceof PushConflictError) {
|
|
@@ -5859,6 +5922,17 @@ function registerPullCommand(program2, globalOpts) {
|
|
|
5859
5922
|
}
|
|
5860
5923
|
const configDataNoInteg = { ...configData };
|
|
5861
5924
|
delete configDataNoInteg.apps;
|
|
5925
|
+
let designTokens;
|
|
5926
|
+
try {
|
|
5927
|
+
const dt = await client.settings.getDesignTokens({
|
|
5928
|
+
channel: "draft"
|
|
5929
|
+
});
|
|
5930
|
+
const doc = dt?.document;
|
|
5931
|
+
if (doc && Object.keys(doc).length > 0) {
|
|
5932
|
+
designTokens = doc;
|
|
5933
|
+
}
|
|
5934
|
+
} catch {
|
|
5935
|
+
}
|
|
5862
5936
|
const configDataNoProject = { ...configDataNoInteg };
|
|
5863
5937
|
delete configDataNoProject.project;
|
|
5864
5938
|
const manifest = {
|
|
@@ -5870,7 +5944,8 @@ function registerPullCommand(program2, globalOpts) {
|
|
|
5870
5944
|
...config2.connectionDomain ? { operationBaseUrl: config2.connectionDomain } : {},
|
|
5871
5945
|
...projectBlock ? { project: projectBlock } : {},
|
|
5872
5946
|
...configDataNoProject,
|
|
5873
|
-
...apps ? { apps } : {}
|
|
5947
|
+
...apps ? { apps } : {},
|
|
5948
|
+
...designTokens ? { designTokens } : {}
|
|
5874
5949
|
};
|
|
5875
5950
|
delete manifest.force;
|
|
5876
5951
|
const jsonContent = JSON.stringify(manifest, null, 2);
|
|
@@ -5950,6 +6025,7 @@ export default defineConfig(${jsonContent});
|
|
|
5950
6025
|
if (schedules.length > 0) parts.push(`${schedules.length} schedule(s)`);
|
|
5951
6026
|
if (authProviders.length > 0) parts.push(`${authProviders.length} auth provider(s)`);
|
|
5952
6027
|
if (configData.customerProfileSchema) parts.push("customer profile schema");
|
|
6028
|
+
if (designTokens) parts.push("design tokens");
|
|
5953
6029
|
if (apps) {
|
|
5954
6030
|
parts.push(`${Object.keys(apps).length} app(s)`);
|
|
5955
6031
|
}
|
|
@@ -7814,6 +7890,112 @@ function registerSettingsCommands(program2, globalOpts) {
|
|
|
7814
7890
|
);
|
|
7815
7891
|
}
|
|
7816
7892
|
|
|
7893
|
+
// src/commands/design-tokens.ts
|
|
7894
|
+
import { existsSync as existsSync6, readFileSync as readFileSync2 } from "fs";
|
|
7895
|
+
import { resolve as resolve6 } from "path";
|
|
7896
|
+
import chalk12 from "chalk";
|
|
7897
|
+
function registerDesignTokensCommands(program2, globalOpts) {
|
|
7898
|
+
const tokens = program2.command("design-tokens").description("Manage project design tokens (W3C-formatted)");
|
|
7899
|
+
tokens.command("get").description("Print the current design tokens document").option("--channel <channel>", "draft | published", "draft").option(
|
|
7900
|
+
"--resolved",
|
|
7901
|
+
"Print the server-resolved view instead of the raw document"
|
|
7902
|
+
).action(
|
|
7903
|
+
withErrorHandler(globalOpts, async (cmdOpts) => {
|
|
7904
|
+
const opts = globalOpts();
|
|
7905
|
+
const client = await createPlatformClient(opts);
|
|
7906
|
+
const channel = cmdOpts.channel === "published" ? "published" : "draft";
|
|
7907
|
+
const result = await client.settings.getDesignTokens({ channel });
|
|
7908
|
+
if (!result) {
|
|
7909
|
+
console.log("{}");
|
|
7910
|
+
return;
|
|
7911
|
+
}
|
|
7912
|
+
if (cmdOpts.resolved) {
|
|
7913
|
+
console.log(JSON.stringify(result.resolved ?? {}, null, 2));
|
|
7914
|
+
return;
|
|
7915
|
+
}
|
|
7916
|
+
const doc = result.document ?? {};
|
|
7917
|
+
console.log(JSON.stringify(doc, null, 2));
|
|
7918
|
+
})
|
|
7919
|
+
);
|
|
7920
|
+
tokens.command("apply <path>").description("Apply a W3C-formatted JSON design tokens document").option("--publish", "Also publish after applying").action(
|
|
7921
|
+
withErrorHandler(
|
|
7922
|
+
globalOpts,
|
|
7923
|
+
async (path3, cmdOpts) => {
|
|
7924
|
+
const opts = globalOpts();
|
|
7925
|
+
const client = await createPlatformClient(opts);
|
|
7926
|
+
const abs = resolve6(process.cwd(), path3);
|
|
7927
|
+
if (!existsSync6(abs)) {
|
|
7928
|
+
throw new Error(`File not found: ${abs}`);
|
|
7929
|
+
}
|
|
7930
|
+
let parsed;
|
|
7931
|
+
try {
|
|
7932
|
+
parsed = JSON.parse(readFileSync2(abs, "utf-8"));
|
|
7933
|
+
} catch (err) {
|
|
7934
|
+
throw new Error(
|
|
7935
|
+
`Invalid JSON in ${abs}: ${err instanceof Error ? err.message : String(err)}`
|
|
7936
|
+
);
|
|
7937
|
+
}
|
|
7938
|
+
await client.settings.updateDesignTokens(parsed);
|
|
7939
|
+
success(`Design tokens applied (draft) from ${path3}`);
|
|
7940
|
+
if (cmdOpts.publish) {
|
|
7941
|
+
const resp = await client.settings.publishDesignTokens();
|
|
7942
|
+
success("Design tokens published");
|
|
7943
|
+
if (resp.breakingChanges && resp.breakingChanges.length > 0) {
|
|
7944
|
+
console.log(chalk12.yellow("\nBreaking changes:"));
|
|
7945
|
+
for (const c of resp.breakingChanges) {
|
|
7946
|
+
console.log(` ${c.severity} ${c.path}: ${c.description}`);
|
|
7947
|
+
}
|
|
7948
|
+
}
|
|
7949
|
+
}
|
|
7950
|
+
}
|
|
7951
|
+
)
|
|
7952
|
+
);
|
|
7953
|
+
tokens.command("publish").description("Promote the draft tokens to the published channel").action(
|
|
7954
|
+
withErrorHandler(globalOpts, async () => {
|
|
7955
|
+
const opts = globalOpts();
|
|
7956
|
+
const client = await createPlatformClient(opts);
|
|
7957
|
+
const resp = await client.settings.publishDesignTokens();
|
|
7958
|
+
success("Design tokens published");
|
|
7959
|
+
if (resp.breakingChanges && resp.breakingChanges.length > 0) {
|
|
7960
|
+
console.log(chalk12.yellow("\nBreaking changes:"));
|
|
7961
|
+
for (const c of resp.breakingChanges) {
|
|
7962
|
+
console.log(` ${c.severity} ${c.path}: ${c.description}`);
|
|
7963
|
+
}
|
|
7964
|
+
}
|
|
7965
|
+
})
|
|
7966
|
+
);
|
|
7967
|
+
tokens.command("unpublish").description("Remove the published tokens snapshot").action(
|
|
7968
|
+
withErrorHandler(globalOpts, async () => {
|
|
7969
|
+
const opts = globalOpts();
|
|
7970
|
+
const client = await createPlatformClient(opts);
|
|
7971
|
+
await client.settings.unpublishDesignTokens();
|
|
7972
|
+
success("Design tokens unpublished");
|
|
7973
|
+
})
|
|
7974
|
+
);
|
|
7975
|
+
tokens.command("status").description("Show draft / published version status").action(
|
|
7976
|
+
withErrorHandler(globalOpts, async () => {
|
|
7977
|
+
const opts = globalOpts();
|
|
7978
|
+
const client = await createPlatformClient(opts);
|
|
7979
|
+
const status = await client.settings.getDesignTokensPublishStatus();
|
|
7980
|
+
if (!status) {
|
|
7981
|
+
console.log("No design tokens yet.");
|
|
7982
|
+
return;
|
|
7983
|
+
}
|
|
7984
|
+
if (status.hasPendingChanges) {
|
|
7985
|
+
console.log(chalk12.yellow("\u25CF Pending changes"));
|
|
7986
|
+
} else {
|
|
7987
|
+
console.log(chalk12.green("\u25CF Up to date"));
|
|
7988
|
+
}
|
|
7989
|
+
if (status.breakingChanges && status.breakingChanges.length > 0) {
|
|
7990
|
+
console.log(chalk12.yellow("\nPending changes:"));
|
|
7991
|
+
for (const c of status.breakingChanges) {
|
|
7992
|
+
console.log(` ${c.severity} ${c.path}: ${c.description}`);
|
|
7993
|
+
}
|
|
7994
|
+
}
|
|
7995
|
+
})
|
|
7996
|
+
);
|
|
7997
|
+
}
|
|
7998
|
+
|
|
7817
7999
|
// src/commands/variant-catalog.ts
|
|
7818
8000
|
import { VariantCatalogEntrySchema } from "@eide/foir-proto-ts/settings/v1/settings_pb";
|
|
7819
8001
|
function registerVariantCatalogCommands(program2, globalOpts) {
|
|
@@ -8536,7 +8718,7 @@ function classToLabel(n) {
|
|
|
8536
8718
|
}
|
|
8537
8719
|
|
|
8538
8720
|
// src/commands/secrets.ts
|
|
8539
|
-
import { existsSync as
|
|
8721
|
+
import { existsSync as existsSync7 } from "fs";
|
|
8540
8722
|
import { promises as fs5 } from "fs";
|
|
8541
8723
|
import { resolve as resolvePath } from "path";
|
|
8542
8724
|
function registerSecretsCommands(program2, globalOpts) {
|
|
@@ -8836,14 +9018,14 @@ var PLAINTEXT_CONFIG_NAMES = [
|
|
|
8836
9018
|
];
|
|
8837
9019
|
async function resolveSecretsConfigPath(explicit) {
|
|
8838
9020
|
if (explicit) {
|
|
8839
|
-
if (!
|
|
9021
|
+
if (!existsSync7(explicit)) {
|
|
8840
9022
|
throw new Error(`Secrets config not found: ${explicit}`);
|
|
8841
9023
|
}
|
|
8842
9024
|
return resolvePath(explicit);
|
|
8843
9025
|
}
|
|
8844
9026
|
for (const name of SECRETS_CONFIG_NAMES) {
|
|
8845
9027
|
const path3 = resolvePath(process.cwd(), name);
|
|
8846
|
-
if (
|
|
9028
|
+
if (existsSync7(path3)) return path3;
|
|
8847
9029
|
}
|
|
8848
9030
|
throw new Error(
|
|
8849
9031
|
`No secrets config found. Looked for: ${SECRETS_CONFIG_NAMES.join(", ")}.`
|
|
@@ -8851,14 +9033,14 @@ async function resolveSecretsConfigPath(explicit) {
|
|
|
8851
9033
|
}
|
|
8852
9034
|
async function resolvePlaintextPath(explicit) {
|
|
8853
9035
|
if (explicit) {
|
|
8854
|
-
if (!
|
|
9036
|
+
if (!existsSync7(explicit)) {
|
|
8855
9037
|
throw new Error(`Plaintext file not found: ${explicit}`);
|
|
8856
9038
|
}
|
|
8857
9039
|
return resolvePath(explicit);
|
|
8858
9040
|
}
|
|
8859
9041
|
for (const name of PLAINTEXT_CONFIG_NAMES) {
|
|
8860
9042
|
const path3 = resolvePath(process.cwd(), name);
|
|
8861
|
-
if (
|
|
9043
|
+
if (existsSync7(path3)) return path3;
|
|
8862
9044
|
}
|
|
8863
9045
|
return null;
|
|
8864
9046
|
}
|
|
@@ -8941,7 +9123,7 @@ function formatPushPlan(plan, opts) {
|
|
|
8941
9123
|
// src/cli.ts
|
|
8942
9124
|
var __filename = fileURLToPath(import.meta.url);
|
|
8943
9125
|
var __dirname = dirname4(__filename);
|
|
8944
|
-
config({ path:
|
|
9126
|
+
config({ path: resolve7(__dirname, "../.env.local") });
|
|
8945
9127
|
var require2 = createRequire(import.meta.url);
|
|
8946
9128
|
var { version } = require2("../package.json");
|
|
8947
9129
|
var program = new Command();
|
|
@@ -8980,6 +9162,7 @@ registerApiKeysCommands(program, getGlobalOpts);
|
|
|
8980
9162
|
registerAuthProvidersCommands(program, getGlobalOpts);
|
|
8981
9163
|
registerLocalesCommands(program, getGlobalOpts);
|
|
8982
9164
|
registerSettingsCommands(program, getGlobalOpts);
|
|
9165
|
+
registerDesignTokensCommands(program, getGlobalOpts);
|
|
8983
9166
|
registerVariantCatalogCommands(program, getGlobalOpts);
|
|
8984
9167
|
registerFilesCommands(program, getGlobalOpts);
|
|
8985
9168
|
registerNotesCommands(program, getGlobalOpts);
|
|
@@ -338,6 +338,27 @@ interface ApplyConfigProjectInput {
|
|
|
338
338
|
*/
|
|
339
339
|
settings?: ApplyConfigProjectSettingsInput;
|
|
340
340
|
}
|
|
341
|
+
/**
|
|
342
|
+
* W3C Design Tokens Format Module document. The CLI applies this
|
|
343
|
+
* verbatim — references like "{font.size.display1}" are preserved on
|
|
344
|
+
* disk so renames in one place propagate to consumers. The platform's
|
|
345
|
+
* resolver runs at write time and rejects cycles or unknown references.
|
|
346
|
+
*
|
|
347
|
+
* See foir-docs/content/platform/design-tokens.md for the full shape.
|
|
348
|
+
*/
|
|
349
|
+
interface ApplyConfigDesignTokensInput {
|
|
350
|
+
color?: Record<string, unknown>;
|
|
351
|
+
font?: {
|
|
352
|
+
family?: Record<string, unknown>;
|
|
353
|
+
weight?: Record<string, unknown>;
|
|
354
|
+
size?: Record<string, unknown>;
|
|
355
|
+
lineHeight?: Record<string, unknown>;
|
|
356
|
+
letterSpacing?: Record<string, unknown>;
|
|
357
|
+
};
|
|
358
|
+
typography?: Record<string, unknown>;
|
|
359
|
+
/** Escape hatch for forward-compatible W3C groups (`spacing`, `border`, …). */
|
|
360
|
+
[key: string]: unknown;
|
|
361
|
+
}
|
|
341
362
|
interface ApplyConfigInput {
|
|
342
363
|
key: string;
|
|
343
364
|
name: string;
|
|
@@ -361,6 +382,12 @@ interface ApplyConfigInput {
|
|
|
361
382
|
apiKeys?: ApplyConfigApiKeyInput[];
|
|
362
383
|
/** Per-project app declarations, keyed by app name. */
|
|
363
384
|
apps?: Record<string, AppInput>;
|
|
385
|
+
/**
|
|
386
|
+
* W3C-formatted design tokens document for this project. Reconciled by
|
|
387
|
+
* `foir push` — the document is applied verbatim to the draft channel.
|
|
388
|
+
* Add `--publish-tokens` to promote draft → published in the same push.
|
|
389
|
+
*/
|
|
390
|
+
designTokens?: ApplyConfigDesignTokensInput;
|
|
364
391
|
[key: string]: unknown;
|
|
365
392
|
}
|
|
366
393
|
/** Define a complete config manifest. */
|
|
@@ -371,6 +398,13 @@ declare function defineModel(model: ApplyConfigModelInput): ApplyConfigModelInpu
|
|
|
371
398
|
declare function defineField(field: FieldDefinitionInput): FieldDefinitionInput;
|
|
372
399
|
/** Define a select field — requires `optionModelKey` pointing to a model whose records become options. */
|
|
373
400
|
declare function defineSelectField(field: SelectFieldDefinitionInput): FieldDefinitionInput;
|
|
401
|
+
/**
|
|
402
|
+
* Define a W3C design tokens document. Pure pass-through that gives
|
|
403
|
+
* IntelliSense for the supported groups (`color`, `font.*`,
|
|
404
|
+
* `typography`); the type permits arbitrary additional groups for
|
|
405
|
+
* forward compatibility.
|
|
406
|
+
*/
|
|
407
|
+
declare function defineDesignTokens(tokens: ApplyConfigDesignTokensInput): ApplyConfigDesignTokensInput;
|
|
374
408
|
/** Define an enum field — config-only choice from inline `{label, value}` options. */
|
|
375
409
|
declare function defineEnumField(field: EnumFieldDefinitionInput): FieldDefinitionInput;
|
|
376
410
|
/** Define an operation with type safety. */
|
|
@@ -419,4 +453,4 @@ interface FoirSecretsConfig {
|
|
|
419
453
|
*/
|
|
420
454
|
declare function defineSecrets(config: FoirSecretsConfig): FoirSecretsConfig;
|
|
421
455
|
|
|
422
|
-
export { type AppInput, type AppPlacementFieldChoiceInput, type AppSinkMappingInput, type AppSourceMappingInput, type ApplyConfigApiKeyInput, type ApplyConfigAuthProviderInput, type ApplyConfigHookInput, type ApplyConfigInput, type ApplyConfigModelInput, type ApplyConfigOperationInput, type ApplyConfigPlacementInput, type ApplyConfigProjectInput, type ApplyConfigProjectSettingsInput, type ApplyConfigScheduleInput, type ApplyConfigSegmentInput, type EnumFieldConfig, type EnumFieldDefinitionInput, type EnumFieldOption, type ExpressionPrecondition, type FieldDefinitionInput, type FoirSecretsConfig, type Precondition, type QuotaRule, type SecretDeclaration, type SecretOwnerKind, type SegmentPrecondition, type SelectFieldConfig, type SelectFieldDefinitionInput, defineAuthProvider, defineConfig, defineEnumField, defineField, defineHook, defineModel, defineOperation, definePlacement, defineSchedule, defineSecrets, defineSegment, defineSelectField };
|
|
456
|
+
export { type AppInput, type AppPlacementFieldChoiceInput, type AppSinkMappingInput, type AppSourceMappingInput, type ApplyConfigApiKeyInput, type ApplyConfigAuthProviderInput, type ApplyConfigDesignTokensInput, type ApplyConfigHookInput, type ApplyConfigInput, type ApplyConfigModelInput, type ApplyConfigOperationInput, type ApplyConfigPlacementInput, type ApplyConfigProjectInput, type ApplyConfigProjectSettingsInput, type ApplyConfigScheduleInput, type ApplyConfigSegmentInput, type EnumFieldConfig, type EnumFieldDefinitionInput, type EnumFieldOption, type ExpressionPrecondition, type FieldDefinitionInput, type FoirSecretsConfig, type Precondition, type QuotaRule, type SecretDeclaration, type SecretOwnerKind, type SegmentPrecondition, type SelectFieldConfig, type SelectFieldDefinitionInput, defineAuthProvider, defineConfig, defineDesignTokens, defineEnumField, defineField, defineHook, defineModel, defineOperation, definePlacement, defineSchedule, defineSecrets, defineSegment, defineSelectField };
|
|
@@ -11,6 +11,9 @@ function defineField(field) {
|
|
|
11
11
|
function defineSelectField(field) {
|
|
12
12
|
return field;
|
|
13
13
|
}
|
|
14
|
+
function defineDesignTokens(tokens) {
|
|
15
|
+
return tokens;
|
|
16
|
+
}
|
|
14
17
|
function defineEnumField(field) {
|
|
15
18
|
return field;
|
|
16
19
|
}
|
|
@@ -38,6 +41,7 @@ function defineSecrets(config) {
|
|
|
38
41
|
export {
|
|
39
42
|
defineAuthProvider,
|
|
40
43
|
defineConfig,
|
|
44
|
+
defineDesignTokens,
|
|
41
45
|
defineEnumField,
|
|
42
46
|
defineField,
|
|
43
47
|
defineHook,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eide/foir-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Universal platform CLI for Foir platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@bufbuild/protovalidate": "^1.1.1",
|
|
51
51
|
"@connectrpc/connect": "^2.0.0",
|
|
52
52
|
"@connectrpc/connect-node": "^2.0.0",
|
|
53
|
-
"@eide/foir-proto-ts": "^0.
|
|
53
|
+
"@eide/foir-proto-ts": "^0.59.0",
|
|
54
54
|
"chalk": "^5.3.0",
|
|
55
55
|
"commander": "^12.1.0",
|
|
56
56
|
"dotenv": "^16.4.5",
|