@eide/foir-cli 0.21.1 → 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 +196 -14
- 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,
|
|
@@ -5270,6 +5311,18 @@ async function reconcileProfileSchema(client, manifest, summary) {
|
|
|
5270
5311
|
});
|
|
5271
5312
|
summary.profileSchemaUpdated = true;
|
|
5272
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
|
+
}
|
|
5273
5326
|
async function reconcileApiKeys(client, configKey, apiKeys, summary, rotateKeys) {
|
|
5274
5327
|
if (apiKeys.length === 0) return;
|
|
5275
5328
|
const existing = await client.identity.listApiKeys({ limit: 200 });
|
|
@@ -5553,6 +5606,10 @@ function printSummary(summary) {
|
|
|
5553
5606
|
if (summary.profileSchemaUpdated) {
|
|
5554
5607
|
lines.push(" Profile: schema updated");
|
|
5555
5608
|
}
|
|
5609
|
+
if (summary.designTokensUpdated) {
|
|
5610
|
+
const detail = summary.designTokensPublished ? "applied & published" : "applied (draft)";
|
|
5611
|
+
lines.push(` Design tokens: ${detail}`);
|
|
5612
|
+
}
|
|
5556
5613
|
if (lines.length > 0) {
|
|
5557
5614
|
for (const line of lines) {
|
|
5558
5615
|
console.log(line);
|
|
@@ -5572,6 +5629,10 @@ function registerPushCommand(program2, globalOpts) {
|
|
|
5572
5629
|
"--publish",
|
|
5573
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.",
|
|
5574
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
|
|
5575
5636
|
).option("--env <path>", "Path to .env file (default: .env)").action(
|
|
5576
5637
|
withErrorHandler(
|
|
5577
5638
|
globalOpts,
|
|
@@ -5631,7 +5692,8 @@ function registerPushCommand(program2, globalOpts) {
|
|
|
5631
5692
|
rotateKeys: opts.rotateKeys ?? false,
|
|
5632
5693
|
tenantId: resolved?.project.tenantId,
|
|
5633
5694
|
projectId: resolved?.project.id,
|
|
5634
|
-
force: opts.force ?? false
|
|
5695
|
+
force: opts.force ?? false,
|
|
5696
|
+
publishDesignTokens: opts.publishTokens ?? false
|
|
5635
5697
|
});
|
|
5636
5698
|
} catch (e) {
|
|
5637
5699
|
if (e instanceof PushConflictError) {
|
|
@@ -5860,6 +5922,17 @@ function registerPullCommand(program2, globalOpts) {
|
|
|
5860
5922
|
}
|
|
5861
5923
|
const configDataNoInteg = { ...configData };
|
|
5862
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
|
+
}
|
|
5863
5936
|
const configDataNoProject = { ...configDataNoInteg };
|
|
5864
5937
|
delete configDataNoProject.project;
|
|
5865
5938
|
const manifest = {
|
|
@@ -5871,7 +5944,8 @@ function registerPullCommand(program2, globalOpts) {
|
|
|
5871
5944
|
...config2.connectionDomain ? { operationBaseUrl: config2.connectionDomain } : {},
|
|
5872
5945
|
...projectBlock ? { project: projectBlock } : {},
|
|
5873
5946
|
...configDataNoProject,
|
|
5874
|
-
...apps ? { apps } : {}
|
|
5947
|
+
...apps ? { apps } : {},
|
|
5948
|
+
...designTokens ? { designTokens } : {}
|
|
5875
5949
|
};
|
|
5876
5950
|
delete manifest.force;
|
|
5877
5951
|
const jsonContent = JSON.stringify(manifest, null, 2);
|
|
@@ -5951,6 +6025,7 @@ export default defineConfig(${jsonContent});
|
|
|
5951
6025
|
if (schedules.length > 0) parts.push(`${schedules.length} schedule(s)`);
|
|
5952
6026
|
if (authProviders.length > 0) parts.push(`${authProviders.length} auth provider(s)`);
|
|
5953
6027
|
if (configData.customerProfileSchema) parts.push("customer profile schema");
|
|
6028
|
+
if (designTokens) parts.push("design tokens");
|
|
5954
6029
|
if (apps) {
|
|
5955
6030
|
parts.push(`${Object.keys(apps).length} app(s)`);
|
|
5956
6031
|
}
|
|
@@ -7815,6 +7890,112 @@ function registerSettingsCommands(program2, globalOpts) {
|
|
|
7815
7890
|
);
|
|
7816
7891
|
}
|
|
7817
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
|
+
|
|
7818
7999
|
// src/commands/variant-catalog.ts
|
|
7819
8000
|
import { VariantCatalogEntrySchema } from "@eide/foir-proto-ts/settings/v1/settings_pb";
|
|
7820
8001
|
function registerVariantCatalogCommands(program2, globalOpts) {
|
|
@@ -8537,7 +8718,7 @@ function classToLabel(n) {
|
|
|
8537
8718
|
}
|
|
8538
8719
|
|
|
8539
8720
|
// src/commands/secrets.ts
|
|
8540
|
-
import { existsSync as
|
|
8721
|
+
import { existsSync as existsSync7 } from "fs";
|
|
8541
8722
|
import { promises as fs5 } from "fs";
|
|
8542
8723
|
import { resolve as resolvePath } from "path";
|
|
8543
8724
|
function registerSecretsCommands(program2, globalOpts) {
|
|
@@ -8837,14 +9018,14 @@ var PLAINTEXT_CONFIG_NAMES = [
|
|
|
8837
9018
|
];
|
|
8838
9019
|
async function resolveSecretsConfigPath(explicit) {
|
|
8839
9020
|
if (explicit) {
|
|
8840
|
-
if (!
|
|
9021
|
+
if (!existsSync7(explicit)) {
|
|
8841
9022
|
throw new Error(`Secrets config not found: ${explicit}`);
|
|
8842
9023
|
}
|
|
8843
9024
|
return resolvePath(explicit);
|
|
8844
9025
|
}
|
|
8845
9026
|
for (const name of SECRETS_CONFIG_NAMES) {
|
|
8846
9027
|
const path3 = resolvePath(process.cwd(), name);
|
|
8847
|
-
if (
|
|
9028
|
+
if (existsSync7(path3)) return path3;
|
|
8848
9029
|
}
|
|
8849
9030
|
throw new Error(
|
|
8850
9031
|
`No secrets config found. Looked for: ${SECRETS_CONFIG_NAMES.join(", ")}.`
|
|
@@ -8852,14 +9033,14 @@ async function resolveSecretsConfigPath(explicit) {
|
|
|
8852
9033
|
}
|
|
8853
9034
|
async function resolvePlaintextPath(explicit) {
|
|
8854
9035
|
if (explicit) {
|
|
8855
|
-
if (!
|
|
9036
|
+
if (!existsSync7(explicit)) {
|
|
8856
9037
|
throw new Error(`Plaintext file not found: ${explicit}`);
|
|
8857
9038
|
}
|
|
8858
9039
|
return resolvePath(explicit);
|
|
8859
9040
|
}
|
|
8860
9041
|
for (const name of PLAINTEXT_CONFIG_NAMES) {
|
|
8861
9042
|
const path3 = resolvePath(process.cwd(), name);
|
|
8862
|
-
if (
|
|
9043
|
+
if (existsSync7(path3)) return path3;
|
|
8863
9044
|
}
|
|
8864
9045
|
return null;
|
|
8865
9046
|
}
|
|
@@ -8942,7 +9123,7 @@ function formatPushPlan(plan, opts) {
|
|
|
8942
9123
|
// src/cli.ts
|
|
8943
9124
|
var __filename = fileURLToPath(import.meta.url);
|
|
8944
9125
|
var __dirname = dirname4(__filename);
|
|
8945
|
-
config({ path:
|
|
9126
|
+
config({ path: resolve7(__dirname, "../.env.local") });
|
|
8946
9127
|
var require2 = createRequire(import.meta.url);
|
|
8947
9128
|
var { version } = require2("../package.json");
|
|
8948
9129
|
var program = new Command();
|
|
@@ -8981,6 +9162,7 @@ registerApiKeysCommands(program, getGlobalOpts);
|
|
|
8981
9162
|
registerAuthProvidersCommands(program, getGlobalOpts);
|
|
8982
9163
|
registerLocalesCommands(program, getGlobalOpts);
|
|
8983
9164
|
registerSettingsCommands(program, getGlobalOpts);
|
|
9165
|
+
registerDesignTokensCommands(program, getGlobalOpts);
|
|
8984
9166
|
registerVariantCatalogCommands(program, getGlobalOpts);
|
|
8985
9167
|
registerFilesCommands(program, getGlobalOpts);
|
|
8986
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",
|