atmn 2.0.11 → 2.0.13
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/bin.js +725 -186
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/actions/init/runInit.ts +2 -0
- package/src/actions/pull/applyMappings.ts +100 -0
- package/src/actions/pull/locateFixture.ts +19 -4
- package/src/actions/pull.ts +22 -0
- package/src/actions/skills/ignoreBundledSkills.ts +32 -0
- package/src/cli.ts +5 -0
- package/src/generated/apiRoutes.ts +24 -24
- package/src/generated/emit.ts +42 -0
- package/src/generated/emitRuntime.ts +3 -5
- package/src/generated/mappingAssignments.ts +204 -0
- package/src/generated/skills.ts +10 -10
- package/src/surgery/appendPropertyEdit.ts +3 -1
- package/src/surgery/findFixture.ts +24 -12
- package/src/surgery/patchFixturePaths.ts +204 -0
- package/src/surgery/readFixtureValue.ts +99 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"7.0.0-dev.20260511.1","root":["../src/bin.ts","../src/cli.ts","../src/index.ts","../src/version.ts","../src/actions/env.ts","../src/actions/login.ts","../src/actions/pull.ts","../src/actions/push.ts","../src/actions/api/callApi.ts","../src/actions/api/registerApiCommands.ts","../src/actions/env/fetchOrgInfo.ts","../src/actions/env/types/orgInfo.ts","../src/actions/init/runInit.ts","../src/actions/login/keyless.ts","../src/actions/pull/appendPlanVersionFixture.ts","../src/actions/pull/applyPreview.ts","../src/actions/pull/applySettingsPreview.ts","../src/actions/pull/changedFixtureKeys.ts","../src/actions/pull/listSourceFiles.ts","../src/actions/pull/locateFixture.ts","../src/actions/pull/resolveCollectionTarget.ts","../src/actions/pull/rewriteConfig.ts","../src/actions/pull/scaffoldConfig.ts","../src/actions/push/backfillInternalIds.ts","../src/actions/push/deprecatedFields.ts","../src/actions/reset/runReset.ts","../src/actions/sandbox/createSandbox.ts","../src/actions/sandbox/deleteSandbox.ts","../src/actions/sandbox/listSandboxes.ts","../src/actions/sandbox/useSandbox.ts","../src/actions/sandbox/withSandboxScopeHint.ts","../src/actions/sandbox/types/sandboxClient.ts","../src/actions/skills/skills.ts","../src/auth/announceAuthorizationUrl.ts","../src/auth/buildAuthorizationUrl.ts","../src/auth/callbackPages.ts","../src/auth/createOrgApiKeys.ts","../src/auth/keyless.ts","../src/auth/oauthConfig.ts","../src/auth/runOAuthFlow.ts","../src/auth/browser/openSystemBrowser.ts","../src/auth/browser/tryOpenBrowser.ts","../src/auth/browser/watchLauncher.ts","../src/auth/types/browserOpener.ts","../src/auth/types/impersonationTokens.ts","../src/auth/types/oauthTokens.ts","../src/auth/types/orgApiKeys.ts","../src/config/configPackageName.ts","../src/config/legacyConfig.ts","../src/config/loadConfig.ts","../src/env/assertSandboxTarget.ts","../src/env/loadEnv.ts","../src/env/resolveTarget.ts","../src/env/sandboxKeyName.ts","../src/generated/apiRoutes.ts","../src/generated/client.ts","../src/generated/emit.ts","../src/generated/emitRuntime.ts","../src/generated/features.ts","../src/generated/labels.ts","../src/generated/licenses.ts","../src/generated/lintRules.ts","../src/generated/lintRuntime.ts","../src/generated/plans.ts","../src/generated/referralPrograms.ts","../src/generated/rewards.ts","../src/generated/settings.ts","../src/generated/skills.ts","../src/generated/variants.ts","../src/generated/wire.ts","../src/http/autumnFetch.ts","../src/project/chooseConfigDir.ts","../src/project/resolveProject.ts","../src/project/rootMarker.ts","../src/prompt/prompt.ts","../src/prompt/select.ts","../src/render/renderEnv.ts","../src/render/renderPreview.ts","../src/render/renderSandboxes.ts","../src/render/stripTerminalControls.ts","../src/repo/findRepoRoot.ts","../src/surgery/appendPropertyEdit.ts","../src/surgery/appendToArray.ts","../src/surgery/appendToBinding.ts","../src/surgery/appendToCollection.ts","../src/surgery/appendToFixtureArray.ts","../src/surgery/arrayBinding.ts","../src/surgery/deleteFixtureLiteral.ts","../src/surgery/deleteReference.ts","../src/surgery/ensureBuilderImport.ts","../src/surgery/findFixture.ts","../src/surgery/fixtureEdit.ts","../src/surgery/fixtureLocation.ts","../src/surgery/insertCollection.ts","../src/surgery/insertFirstProperty.ts","../src/surgery/patchFixtureProperty.ts","../src/surgery/patchSingletonProperty.ts","../src/surgery/replaceFixture.ts","../src/surgery/setFixtureProperty.ts","../src/surgery/staticFixtureRule.ts","../test/apiCommand.test.ts","../test/authorizationUrl.test.ts","../test/autumnFetch.test.ts","../test/backfill.test.ts","../test/backfillInlineVariants.test.ts","../test/backfillSlug.test.ts","../test/backfillVariants.test.ts","../test/chooseConfigDir.test.ts","../test/cliTargetFlags.test.ts","../test/client.test.ts","../test/configPackageName.test.ts","../test/emitFixture.test.ts","../test/env.test.ts","../test/envWriter.test.ts","../test/init.test.ts","../test/keyless.test.ts","../test/legacyConfig.test.ts","../test/lintDocument.test.ts","../test/loadConfigNode.test.ts","../test/loadConfigV2.test.ts","../test/login.test.ts","../test/nodeNextTypes.test.ts","../test/plans.test.ts","../test/previewIsEmpty.test.ts","../test/prompt.test.ts","../test/pull.test.ts","../test/pullByReference.test.ts","../test/pullFieldLevel.test.ts","../test/pullOmitDefaults.test.ts","../test/pullPlans.test.ts","../test/pullStatesSlugs.test.ts","../test/pullTwoCollections.test.ts","../test/renameHint.test.ts","../test/renderPreview.test.ts","../test/renderSandboxes.test.ts","../test/renderSettings.test.ts","../test/reset.test.ts","../test/resolveCollectionTarget.test.ts","../test/resolveProject.test.ts","../test/resolveTarget.test.ts","../test/sandboxActions.test.ts","../test/sandboxKeyName.test.ts","../test/sandboxUse.test.ts","../test/settingsActions.test.ts","../test/settingsWire.test.ts","../test/skills.test.ts","../test/watchLauncher.test.ts","../test/wireDocument.test.ts","../test/helpers/targetFor.ts","../test/surgery/appendToCollection.test.ts","../test/surgery/deleteFixtureLiteral.test.ts","../test/surgery/deleteReference.test.ts","../test/surgery/findFixture.test.ts","../test/surgery/fixtureLocation.test.ts","../test/surgery/insertCollection.test.ts","../test/surgery/insertFirstProperty.test.ts","../test/surgery/patchFixtureProperty.test.ts","../test/surgery/patchSingletonProperty.test.ts","../test/surgery/replaceFixture.test.ts","../test/surgery/staticFixtureRule.test.ts"]}
|
|
1
|
+
{"version":"7.0.0-dev.20260511.1","root":["../src/bin.ts","../src/cli.ts","../src/index.ts","../src/version.ts","../src/actions/env.ts","../src/actions/login.ts","../src/actions/pull.ts","../src/actions/push.ts","../src/actions/api/callApi.ts","../src/actions/api/registerApiCommands.ts","../src/actions/env/fetchOrgInfo.ts","../src/actions/env/types/orgInfo.ts","../src/actions/init/runInit.ts","../src/actions/login/keyless.ts","../src/actions/pull/appendPlanVersionFixture.ts","../src/actions/pull/applyMappings.ts","../src/actions/pull/applyPreview.ts","../src/actions/pull/applySettingsPreview.ts","../src/actions/pull/changedFixtureKeys.ts","../src/actions/pull/listSourceFiles.ts","../src/actions/pull/locateFixture.ts","../src/actions/pull/resolveCollectionTarget.ts","../src/actions/pull/rewriteConfig.ts","../src/actions/pull/scaffoldConfig.ts","../src/actions/push/backfillInternalIds.ts","../src/actions/push/deprecatedFields.ts","../src/actions/reset/runReset.ts","../src/actions/sandbox/createSandbox.ts","../src/actions/sandbox/deleteSandbox.ts","../src/actions/sandbox/listSandboxes.ts","../src/actions/sandbox/useSandbox.ts","../src/actions/sandbox/withSandboxScopeHint.ts","../src/actions/sandbox/types/sandboxClient.ts","../src/actions/skills/ignoreBundledSkills.ts","../src/actions/skills/skills.ts","../src/auth/announceAuthorizationUrl.ts","../src/auth/buildAuthorizationUrl.ts","../src/auth/callbackPages.ts","../src/auth/createOrgApiKeys.ts","../src/auth/keyless.ts","../src/auth/oauthConfig.ts","../src/auth/runOAuthFlow.ts","../src/auth/browser/openSystemBrowser.ts","../src/auth/browser/tryOpenBrowser.ts","../src/auth/browser/watchLauncher.ts","../src/auth/types/browserOpener.ts","../src/auth/types/impersonationTokens.ts","../src/auth/types/oauthTokens.ts","../src/auth/types/orgApiKeys.ts","../src/config/configPackageName.ts","../src/config/legacyConfig.ts","../src/config/loadConfig.ts","../src/env/assertSandboxTarget.ts","../src/env/loadEnv.ts","../src/env/resolveTarget.ts","../src/env/sandboxKeyName.ts","../src/generated/apiRoutes.ts","../src/generated/client.ts","../src/generated/emit.ts","../src/generated/emitRuntime.ts","../src/generated/features.ts","../src/generated/labels.ts","../src/generated/licenses.ts","../src/generated/lintRules.ts","../src/generated/lintRuntime.ts","../src/generated/mappingAssignments.ts","../src/generated/plans.ts","../src/generated/referralPrograms.ts","../src/generated/rewards.ts","../src/generated/settings.ts","../src/generated/skills.ts","../src/generated/variants.ts","../src/generated/wire.ts","../src/http/autumnFetch.ts","../src/project/chooseConfigDir.ts","../src/project/resolveProject.ts","../src/project/rootMarker.ts","../src/prompt/prompt.ts","../src/prompt/select.ts","../src/render/renderEnv.ts","../src/render/renderPreview.ts","../src/render/renderSandboxes.ts","../src/render/stripTerminalControls.ts","../src/repo/findRepoRoot.ts","../src/surgery/appendPropertyEdit.ts","../src/surgery/appendToArray.ts","../src/surgery/appendToBinding.ts","../src/surgery/appendToCollection.ts","../src/surgery/appendToFixtureArray.ts","../src/surgery/arrayBinding.ts","../src/surgery/deleteFixtureLiteral.ts","../src/surgery/deleteReference.ts","../src/surgery/ensureBuilderImport.ts","../src/surgery/findFixture.ts","../src/surgery/fixtureEdit.ts","../src/surgery/fixtureLocation.ts","../src/surgery/insertCollection.ts","../src/surgery/insertFirstProperty.ts","../src/surgery/patchFixturePaths.ts","../src/surgery/patchFixtureProperty.ts","../src/surgery/patchSingletonProperty.ts","../src/surgery/readFixtureValue.ts","../src/surgery/replaceFixture.ts","../src/surgery/setFixtureProperty.ts","../src/surgery/staticFixtureRule.ts","../test/apiCommand.test.ts","../test/authorizationUrl.test.ts","../test/autumnFetch.test.ts","../test/backfill.test.ts","../test/backfillInlineVariants.test.ts","../test/backfillSlug.test.ts","../test/backfillVariants.test.ts","../test/chooseConfigDir.test.ts","../test/cliTargetFlags.test.ts","../test/client.test.ts","../test/configPackageName.test.ts","../test/emitFixture.test.ts","../test/env.test.ts","../test/envWriter.test.ts","../test/ignoreBundledSkills.test.ts","../test/init.test.ts","../test/keyless.test.ts","../test/legacyConfig.test.ts","../test/lintDocument.test.ts","../test/loadConfigNode.test.ts","../test/loadConfigV2.test.ts","../test/locateFixtureUnique.test.ts","../test/login.test.ts","../test/nodeNextTypes.test.ts","../test/patchFixturePaths.test.ts","../test/plans.test.ts","../test/previewIsEmpty.test.ts","../test/prompt.test.ts","../test/pull.test.ts","../test/pullByReference.test.ts","../test/pullFieldLevel.test.ts","../test/pullMappings.test.ts","../test/pullOmitDefaults.test.ts","../test/pullPlans.test.ts","../test/pullStatesSlugs.test.ts","../test/pullTwoCollections.test.ts","../test/readFixtureValue.test.ts","../test/renameHint.test.ts","../test/renderPreview.test.ts","../test/renderSandboxes.test.ts","../test/renderSettings.test.ts","../test/reset.test.ts","../test/resolveCollectionTarget.test.ts","../test/resolveProject.test.ts","../test/resolveTarget.test.ts","../test/sandboxActions.test.ts","../test/sandboxKeyName.test.ts","../test/sandboxUse.test.ts","../test/settingsActions.test.ts","../test/settingsWire.test.ts","../test/skills.test.ts","../test/watchLauncher.test.ts","../test/wireDocument.test.ts","../test/helpers/targetFor.ts","../test/surgery/appendToCollection.test.ts","../test/surgery/deleteFixtureLiteral.test.ts","../test/surgery/deleteReference.test.ts","../test/surgery/findFixture.test.ts","../test/surgery/fixtureLocation.test.ts","../test/surgery/insertCollection.test.ts","../test/surgery/insertFirstProperty.test.ts","../test/surgery/patchFixtureProperty.test.ts","../test/surgery/patchSingletonProperty.test.ts","../test/surgery/replaceFixture.test.ts","../test/surgery/staticFixtureRule.test.ts"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atmn",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.13",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "The CLI for Autumn — define your pricing in code, sync it to Autumn, and keep everything in version control.",
|
|
6
6
|
"bin": {
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"open": "10.2.0",
|
|
50
50
|
"yaml": "2.9.0"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "56a30233085c57237f966558842ec13e17e3b2fc"
|
|
53
53
|
}
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
runKeylessLogin,
|
|
30
30
|
} from "../login/keyless";
|
|
31
31
|
import { scaffoldConfig } from "../pull/scaffoldConfig";
|
|
32
|
+
import { ignoreBundledSkills } from "../skills/ignoreBundledSkills";
|
|
32
33
|
import { installSkills, SKILLS_DIR_NAME } from "../skills/skills";
|
|
33
34
|
|
|
34
35
|
/** The network, behind functions so a test can hand over fakes. */
|
|
@@ -385,6 +386,7 @@ export const runInit = async ({
|
|
|
385
386
|
|
|
386
387
|
const skillsDir = join(configDir, SKILLS_DIR_NAME);
|
|
387
388
|
const { written } = installSkills({ dir: skillsDir, write: () => {} });
|
|
389
|
+
ignoreBundledSkills({ repoRoot, configDir });
|
|
388
390
|
prompter.write(
|
|
389
391
|
`${done(`Skills: ${relative(repoRoot, skillsDir)}/${written.join(", ")}`)}\n`,
|
|
390
392
|
);
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { COLLECTIONS, NESTED_FIXTURES } from "../../generated/emit";
|
|
2
|
+
import { resolveBranch } from "../../generated/emitRuntime";
|
|
3
|
+
import { mappingAssignments } from "../../generated/mappingAssignments";
|
|
4
|
+
import { patchFixturePaths } from "../../surgery/patchFixturePaths";
|
|
5
|
+
import { readFixtureValue } from "../../surgery/readFixtureValue";
|
|
6
|
+
import { locateFixture } from "./locateFixture";
|
|
7
|
+
|
|
8
|
+
export const applyMappings = ({
|
|
9
|
+
catalog,
|
|
10
|
+
configPath,
|
|
11
|
+
files,
|
|
12
|
+
}: {
|
|
13
|
+
catalog: Record<string, unknown>;
|
|
14
|
+
configPath: string;
|
|
15
|
+
files: Map<string, string>;
|
|
16
|
+
}): {
|
|
17
|
+
replaced: string[];
|
|
18
|
+
unlocated: { collection: string; id: string; action: string }[];
|
|
19
|
+
} => {
|
|
20
|
+
const replaced: string[] = [];
|
|
21
|
+
const unlocated: { collection: string; id: string; action: string }[] = [];
|
|
22
|
+
const builders = Object.values(NESTED_FIXTURES).map(({ builder }) => builder);
|
|
23
|
+
for (const [collection, collectionSpec] of Object.entries(COLLECTIONS)) {
|
|
24
|
+
const rows = catalog[collection];
|
|
25
|
+
if (!collectionSpec.pull || !Array.isArray(rows)) continue;
|
|
26
|
+
for (const entry of rows) {
|
|
27
|
+
const { spec, row } = resolveBranch({ spec: collectionSpec, row: entry });
|
|
28
|
+
const id = row[spec.responseIdField];
|
|
29
|
+
if (!spec.mappings || typeof id !== "string" || row.archived === true)
|
|
30
|
+
continue;
|
|
31
|
+
const key = spec.versioned ? `${id}@${row.versionSlug ?? "v1"}` : id;
|
|
32
|
+
const located = locateFixture({
|
|
33
|
+
configPath,
|
|
34
|
+
files,
|
|
35
|
+
builder: spec.builder,
|
|
36
|
+
idField: spec.idField,
|
|
37
|
+
id,
|
|
38
|
+
internalId:
|
|
39
|
+
typeof row.internalId === "string" ? row.internalId : undefined,
|
|
40
|
+
where: spec.versioned
|
|
41
|
+
? [
|
|
42
|
+
{
|
|
43
|
+
field: "versionSlug",
|
|
44
|
+
equals:
|
|
45
|
+
typeof row.versionSlug === "string" ? row.versionSlug : "v1",
|
|
46
|
+
absentMeans: "v1",
|
|
47
|
+
},
|
|
48
|
+
]
|
|
49
|
+
: undefined,
|
|
50
|
+
allowDynamic: true,
|
|
51
|
+
requireUnique: true,
|
|
52
|
+
});
|
|
53
|
+
if (!located) {
|
|
54
|
+
unlocated.push({
|
|
55
|
+
collection,
|
|
56
|
+
id: key,
|
|
57
|
+
action: "cannot locate the fixture to write processor mappings",
|
|
58
|
+
});
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const planned = mappingAssignments({
|
|
62
|
+
projection: spec.mappings,
|
|
63
|
+
local: readFixtureValue({
|
|
64
|
+
node: located.node,
|
|
65
|
+
builders: [spec.builder, ...builders],
|
|
66
|
+
}),
|
|
67
|
+
remote: row,
|
|
68
|
+
});
|
|
69
|
+
if (planned.errors.length) {
|
|
70
|
+
unlocated.push(
|
|
71
|
+
...planned.errors.map((action) => ({ collection, id: key, action })),
|
|
72
|
+
);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (!planned.assignments.length) continue;
|
|
76
|
+
const patched = patchFixturePaths({
|
|
77
|
+
source: located.source,
|
|
78
|
+
builder: located.builder,
|
|
79
|
+
idField: located.idField,
|
|
80
|
+
id: located.id,
|
|
81
|
+
where: located.where,
|
|
82
|
+
builders,
|
|
83
|
+
assignments: planned.assignments,
|
|
84
|
+
});
|
|
85
|
+
if (!patched || patched.skipped.length) {
|
|
86
|
+
unlocated.push({
|
|
87
|
+
collection,
|
|
88
|
+
id: key,
|
|
89
|
+
action:
|
|
90
|
+
"cannot safely splice processor mappings into a computed or ambiguous value",
|
|
91
|
+
});
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (patched.source === located.source) continue;
|
|
95
|
+
files.set(located.file, patched.source);
|
|
96
|
+
replaced.push(key);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return { replaced, unlocated };
|
|
100
|
+
};
|
|
@@ -2,7 +2,7 @@ import type { SgNode } from "@ast-grep/napi";
|
|
|
2
2
|
import {
|
|
3
3
|
type FixtureConstraint,
|
|
4
4
|
type FixtureShape,
|
|
5
|
-
|
|
5
|
+
findFixtures,
|
|
6
6
|
} from "../../surgery/findFixture";
|
|
7
7
|
|
|
8
8
|
/** The file, its source, the node, and the lookup that found it — reuse the
|
|
@@ -35,6 +35,7 @@ export const locateFixture = ({
|
|
|
35
35
|
internalId,
|
|
36
36
|
where,
|
|
37
37
|
allowDynamic = false,
|
|
38
|
+
requireUnique = false,
|
|
38
39
|
}: {
|
|
39
40
|
configPath: string;
|
|
40
41
|
files: Map<string, string>;
|
|
@@ -44,6 +45,7 @@ export const locateFixture = ({
|
|
|
44
45
|
internalId?: string | null;
|
|
45
46
|
where?: FixtureConstraint[];
|
|
46
47
|
allowDynamic?: boolean;
|
|
48
|
+
requireUnique?: boolean;
|
|
47
49
|
}): LocatedFixture | null => {
|
|
48
50
|
const others = [...files.keys()].filter((file) => file !== configPath);
|
|
49
51
|
const ordered = [configPath, ...others];
|
|
@@ -59,20 +61,33 @@ export const locateFixture = ({
|
|
|
59
61
|
];
|
|
60
62
|
const shapes = Array.isArray(builder) ? builder : [builder];
|
|
61
63
|
for (const attempt of attempts) {
|
|
64
|
+
const matches = new Map<string, LocatedFixture>();
|
|
62
65
|
for (const file of ordered) {
|
|
63
66
|
const source = files.get(file);
|
|
64
67
|
if (source === undefined) continue;
|
|
65
68
|
for (const shape of shapes) {
|
|
66
|
-
const
|
|
69
|
+
const nodes = findFixtures({
|
|
67
70
|
source,
|
|
68
71
|
builder: shape,
|
|
69
72
|
allowDynamic,
|
|
70
73
|
...attempt,
|
|
71
74
|
});
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
for (const node of nodes) {
|
|
76
|
+
const located = { file, source, node, builder: shape, ...attempt };
|
|
77
|
+
if (!requireUnique) return located;
|
|
78
|
+
const range = node.range();
|
|
79
|
+
const key = JSON.stringify([
|
|
80
|
+
file,
|
|
81
|
+
range.start.index,
|
|
82
|
+
range.end.index,
|
|
83
|
+
]);
|
|
84
|
+
matches.set(key, located);
|
|
85
|
+
if (matches.size > 1) return null;
|
|
86
|
+
}
|
|
74
87
|
}
|
|
75
88
|
}
|
|
89
|
+
const match = matches.values().next().value;
|
|
90
|
+
if (match !== undefined) return match;
|
|
76
91
|
}
|
|
77
92
|
return null;
|
|
78
93
|
};
|
package/src/actions/pull.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { resolveProject } from "../project/resolveProject";
|
|
|
16
16
|
import { writeRootMarker } from "../project/rootMarker";
|
|
17
17
|
import { createPrompter, done, type Prompter } from "../prompt/prompt";
|
|
18
18
|
import type { SettingsPreview } from "../render/renderPreview";
|
|
19
|
+
import { applyMappings } from "./pull/applyMappings";
|
|
19
20
|
import { applyPreview, type PreviewEntry } from "./pull/applyPreview";
|
|
20
21
|
import { applySettingsPreview } from "./pull/applySettingsPreview";
|
|
21
22
|
import { listSourceFiles } from "./pull/listSourceFiles";
|
|
@@ -341,6 +342,27 @@ export const runPull = async ({
|
|
|
341
342
|
);
|
|
342
343
|
}
|
|
343
344
|
|
|
345
|
+
if (includeMappings) {
|
|
346
|
+
const managedCatalog = Object.fromEntries(
|
|
347
|
+
Object.entries(COLLECTIONS)
|
|
348
|
+
.filter(
|
|
349
|
+
([, spec]) =>
|
|
350
|
+
spec.wireKey !== undefined && wire[spec.wireKey] !== undefined,
|
|
351
|
+
)
|
|
352
|
+
.map(([collection]) => [collection, catalogRows[collection]]),
|
|
353
|
+
);
|
|
354
|
+
const mapped = applyMappings({
|
|
355
|
+
catalog: managedCatalog,
|
|
356
|
+
configPath,
|
|
357
|
+
files,
|
|
358
|
+
});
|
|
359
|
+
unlocated.push(...mapped.unlocated);
|
|
360
|
+
for (const id of mapped.replaced) {
|
|
361
|
+
if (!replaced.includes(id) && !appended.includes(id)) replaced.push(id);
|
|
362
|
+
lines.push(`↳ wrote processor mappings into ${id}`);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
344
366
|
// A fixture that is not a plain literal cannot be edited in place; saying
|
|
345
367
|
// so before writing anything beats a half-applied pull.
|
|
346
368
|
if (unlocated.length > 0) throw new UnlocatableFixturesError({ unlocated });
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { isAbsolute, join, relative, sep } from "node:path";
|
|
3
|
+
import { SKILLS_DIR_NAME } from "./skills";
|
|
4
|
+
|
|
5
|
+
export const ignoreBundledSkills = ({
|
|
6
|
+
repoRoot,
|
|
7
|
+
configDir,
|
|
8
|
+
}: {
|
|
9
|
+
repoRoot: string;
|
|
10
|
+
configDir: string;
|
|
11
|
+
}): void => {
|
|
12
|
+
const path = relative(repoRoot, join(configDir, SKILLS_DIR_NAME));
|
|
13
|
+
if (isAbsolute(path) || path === ".." || path.startsWith(`..${sep}`)) return;
|
|
14
|
+
if (/[\r\n]/.test(path)) return;
|
|
15
|
+
const pattern = `/${path
|
|
16
|
+
.split(sep)
|
|
17
|
+
.join("/")
|
|
18
|
+
.replace(/[\\*?[\] ]/g, "\\$&")}/`;
|
|
19
|
+
const ignorePath = join(repoRoot, ".gitignore");
|
|
20
|
+
const contents = existsSync(ignorePath)
|
|
21
|
+
? readFileSync(ignorePath, "utf8")
|
|
22
|
+
: "";
|
|
23
|
+
if (contents.split(/\r?\n/).includes(pattern)) return;
|
|
24
|
+
const newline = contents.includes("\r\n") ? "\r\n" : "\n";
|
|
25
|
+
const separator =
|
|
26
|
+
contents.length > 0 && !contents.endsWith("\n") ? newline : "";
|
|
27
|
+
writeFileSync(
|
|
28
|
+
ignorePath,
|
|
29
|
+
`${contents}${separator}${pattern}${newline}`,
|
|
30
|
+
"utf8",
|
|
31
|
+
);
|
|
32
|
+
};
|
package/src/cli.ts
CHANGED
|
@@ -21,6 +21,7 @@ import { runSandboxDelete } from "./actions/sandbox/deleteSandbox";
|
|
|
21
21
|
import { runSandboxList } from "./actions/sandbox/listSandboxes";
|
|
22
22
|
import { runSandboxUse } from "./actions/sandbox/useSandbox";
|
|
23
23
|
import { withSandboxScopeHint } from "./actions/sandbox/withSandboxScopeHint";
|
|
24
|
+
import { ignoreBundledSkills } from "./actions/skills/ignoreBundledSkills";
|
|
24
25
|
import {
|
|
25
26
|
installSkills,
|
|
26
27
|
linkSkills,
|
|
@@ -431,6 +432,8 @@ Linking a keyless org to an account:
|
|
|
431
432
|
async (options: { dir?: string; link?: boolean }, command: Command) => {
|
|
432
433
|
const dir = skillsDirOf({ command, dir: options.dir });
|
|
433
434
|
installSkills({ dir, write: (text) => process.stdout.write(text) });
|
|
435
|
+
if (options.dir === undefined)
|
|
436
|
+
ignoreBundledSkills(projectOf({ command }));
|
|
434
437
|
if (options.link === true)
|
|
435
438
|
await linkSkills({
|
|
436
439
|
dir,
|
|
@@ -449,6 +452,8 @@ Linking a keyless org to an account:
|
|
|
449
452
|
.action((options: { dir?: string }, command: Command) => {
|
|
450
453
|
const dir = skillsDirOf({ command, dir: options.dir });
|
|
451
454
|
updateSkills({ dir, write: (text) => process.stdout.write(text) });
|
|
455
|
+
if (options.dir === undefined)
|
|
456
|
+
ignoreBundledSkills(projectOf({ command }));
|
|
452
457
|
});
|
|
453
458
|
|
|
454
459
|
program
|
|
@@ -299,6 +299,30 @@ export const API_ROUTES: readonly ApiRoute[] = [
|
|
|
299
299
|
},
|
|
300
300
|
],
|
|
301
301
|
},
|
|
302
|
+
{
|
|
303
|
+
group: "customers",
|
|
304
|
+
method: "advance_test_clock",
|
|
305
|
+
path: "/v1/customers.advance_test_clock",
|
|
306
|
+
description:
|
|
307
|
+
"Advance a customer's Stripe test clock to a future time in milliseconds. Only Stripe test-mode customers with a test clock are supported. Advancement is asynchronous; Stripe enforces clock status and advancement limits.",
|
|
308
|
+
body: "object",
|
|
309
|
+
fields: [
|
|
310
|
+
{
|
|
311
|
+
name: "customer_id",
|
|
312
|
+
type: "string",
|
|
313
|
+
required: true,
|
|
314
|
+
description:
|
|
315
|
+
"The ID of the customer whose Stripe test clock to advance.",
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
name: "frozen_time",
|
|
319
|
+
type: "number",
|
|
320
|
+
required: true,
|
|
321
|
+
description:
|
|
322
|
+
"Target time as a Unix timestamp in milliseconds. Rounded down to whole seconds; must be later than the current clock time.",
|
|
323
|
+
},
|
|
324
|
+
],
|
|
325
|
+
},
|
|
302
326
|
{
|
|
303
327
|
group: "plans",
|
|
304
328
|
method: "create",
|
|
@@ -1072,30 +1096,6 @@ export const API_ROUTES: readonly ApiRoute[] = [
|
|
|
1072
1096
|
},
|
|
1073
1097
|
],
|
|
1074
1098
|
},
|
|
1075
|
-
{
|
|
1076
|
-
group: "billing",
|
|
1077
|
-
method: "advance_test_clock",
|
|
1078
|
-
path: "/v1/billing.advance_test_clock",
|
|
1079
|
-
description:
|
|
1080
|
-
"Advance a customer's Stripe test clock to a future time in milliseconds. Only Stripe test-mode customers with a test clock are supported. Advancement is asynchronous; Stripe enforces clock status and advancement limits.",
|
|
1081
|
-
body: "object",
|
|
1082
|
-
fields: [
|
|
1083
|
-
{
|
|
1084
|
-
name: "customer_id",
|
|
1085
|
-
type: "string",
|
|
1086
|
-
required: true,
|
|
1087
|
-
description:
|
|
1088
|
-
"The ID of the customer whose Stripe test clock to advance.",
|
|
1089
|
-
},
|
|
1090
|
-
{
|
|
1091
|
-
name: "frozen_time",
|
|
1092
|
-
type: "number",
|
|
1093
|
-
required: true,
|
|
1094
|
-
description:
|
|
1095
|
-
"Target time as a Unix timestamp in milliseconds. Rounded down to whole seconds; must be later than the current clock time.",
|
|
1096
|
-
},
|
|
1097
|
-
],
|
|
1098
|
-
},
|
|
1099
1099
|
{
|
|
1100
1100
|
group: "billing",
|
|
1101
1101
|
method: "create_schedule",
|
package/src/generated/emit.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { CollectionSpec, SingletonSpec } from "./emitRuntime";
|
|
|
5
5
|
|
|
6
6
|
export const COLLECTIONS: Readonly<Record<string, CollectionSpec>> = {
|
|
7
7
|
features: {
|
|
8
|
+
wireKey: "features",
|
|
8
9
|
builder: "feature",
|
|
9
10
|
idField: "featureId",
|
|
10
11
|
responseIdField: "id",
|
|
@@ -80,11 +81,13 @@ export const COLLECTIONS: Readonly<Record<string, CollectionSpec>> = {
|
|
|
80
81
|
"providerMarkups.*.markup",
|
|
81
82
|
"type",
|
|
82
83
|
],
|
|
84
|
+
mappings: { properties: { processors: { mapping: true } } },
|
|
83
85
|
defaults: {},
|
|
84
86
|
pull: true,
|
|
85
87
|
deprecated: [],
|
|
86
88
|
},
|
|
87
89
|
plans: {
|
|
90
|
+
wireKey: "plans",
|
|
88
91
|
builder: "plan",
|
|
89
92
|
idField: "planId",
|
|
90
93
|
responseIdField: "id",
|
|
@@ -865,6 +868,43 @@ export const COLLECTIONS: Readonly<Record<string, CollectionSpec>> = {
|
|
|
865
868
|
"variants.versionSlug",
|
|
866
869
|
"versionSlug",
|
|
867
870
|
],
|
|
871
|
+
mappings: {
|
|
872
|
+
properties: {
|
|
873
|
+
processors: { mapping: true },
|
|
874
|
+
price: { properties: { processors: { mapping: true } } },
|
|
875
|
+
items: {
|
|
876
|
+
items: {
|
|
877
|
+
properties: {
|
|
878
|
+
price: { properties: { processors: { mapping: true } } },
|
|
879
|
+
},
|
|
880
|
+
},
|
|
881
|
+
identity: {
|
|
882
|
+
responseField: "mappingIdentity",
|
|
883
|
+
components: [
|
|
884
|
+
{ paths: ["featureId"], default: "" },
|
|
885
|
+
{ paths: ["price.billingMethod"], default: "" },
|
|
886
|
+
{ paths: ["price.interval", "reset.interval"], default: "" },
|
|
887
|
+
{
|
|
888
|
+
paths: ["price.intervalCount", "reset.intervalCount"],
|
|
889
|
+
default: "",
|
|
890
|
+
defaultWhen: { component: 2, value: 1 },
|
|
891
|
+
},
|
|
892
|
+
],
|
|
893
|
+
},
|
|
894
|
+
},
|
|
895
|
+
variants: {
|
|
896
|
+
items: {
|
|
897
|
+
properties: {
|
|
898
|
+
processors: { mapping: true, sourcePath: ["plan", "processors"] },
|
|
899
|
+
},
|
|
900
|
+
},
|
|
901
|
+
identity: {
|
|
902
|
+
responseField: "mappingIdentity",
|
|
903
|
+
components: [{ paths: ["variantPlanId"], default: "" }],
|
|
904
|
+
},
|
|
905
|
+
},
|
|
906
|
+
},
|
|
907
|
+
},
|
|
868
908
|
defaults: {
|
|
869
909
|
addOn: false,
|
|
870
910
|
autoEnable: false,
|
|
@@ -961,6 +1001,7 @@ export const COLLECTIONS: Readonly<Record<string, CollectionSpec>> = {
|
|
|
961
1001
|
],
|
|
962
1002
|
},
|
|
963
1003
|
rewards: {
|
|
1004
|
+
wireKey: "rewards",
|
|
964
1005
|
builder: "reward",
|
|
965
1006
|
idField: "id",
|
|
966
1007
|
responseIdField: "id",
|
|
@@ -1103,6 +1144,7 @@ export const COLLECTIONS: Readonly<Record<string, CollectionSpec>> = {
|
|
|
1103
1144
|
],
|
|
1104
1145
|
},
|
|
1105
1146
|
referralPrograms: {
|
|
1147
|
+
wireKey: "referral_programs",
|
|
1106
1148
|
builder: "referralProgram",
|
|
1107
1149
|
idField: "id",
|
|
1108
1150
|
responseIdField: "id",
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
// Copied by @autumn/atmn-generator from packages/atmn-generator/src/emit/runtime/emitFixture.ts.
|
|
2
2
|
// Do not edit — change that file and run `bun generate` instead.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
* Copied verbatim into the CLI by the generator, so this file imports nothing:
|
|
6
|
-
* a pulled server row becomes fixture source here, in the exact shape the
|
|
7
|
-
* surgery module splices into the user's config.
|
|
8
|
-
*/
|
|
4
|
+
import type { MappingProjection } from "./mappingAssignments";
|
|
9
5
|
|
|
10
6
|
export type CollectionSpec = {
|
|
7
|
+
readonly wireKey?: string;
|
|
8
|
+
readonly mappings?: MappingProjection;
|
|
11
9
|
readonly builder: string;
|
|
12
10
|
readonly idField: string;
|
|
13
11
|
readonly responseIdField: string;
|