@apifuse/provider-sdk 2.2.0-beta.47 → 2.2.0-beta.49

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 (114) hide show
  1. package/AUTHORING.md +91 -36
  2. package/CHANGELOG.md +8 -0
  3. package/README.md +11 -9
  4. package/SUBMISSION.md +1 -1
  5. package/bin/apifuse-dev.ts +24 -13
  6. package/bin/apifuse-migrate-operation-declaration.ts +55 -0
  7. package/bin/apifuse-pack-smoke.ts +1 -1
  8. package/bin/apifuse-pack-types.ts +2 -1
  9. package/bin/apifuse-record.ts +30 -16
  10. package/bin/apifuse-submit-check.ts +20 -35
  11. package/dist/cli/commands.d.ts +1 -1
  12. package/dist/cli/commands.js +11 -0
  13. package/dist/cli/migrate-operation-declaration.d.ts +59 -0
  14. package/dist/cli/migrate-operation-declaration.js +1178 -0
  15. package/dist/cli/templates/provider/README.md.tpl +3 -3
  16. package/dist/cli/templates/provider/operations/ping.ts.tpl +2 -0
  17. package/dist/config/loader.d.ts +2 -0
  18. package/dist/config/loader.js +18 -7
  19. package/dist/contract-types.d.ts +11 -5
  20. package/dist/contract.js +21 -10
  21. package/dist/define.d.ts +25 -22
  22. package/dist/define.js +49 -75
  23. package/dist/dev.d.ts +3 -0
  24. package/dist/dev.js +1 -1
  25. package/dist/engine.d.ts +78 -0
  26. package/dist/engine.js +133 -0
  27. package/dist/index.d.ts +3 -2
  28. package/dist/index.js +2 -1
  29. package/dist/lint.d.ts +7 -15
  30. package/dist/lint.js +45 -70
  31. package/dist/provider.d.ts +3 -1
  32. package/dist/provider.js +1 -0
  33. package/dist/runtime/chrome149-header-order.d.ts +58 -0
  34. package/dist/runtime/chrome149-header-order.js +289 -0
  35. package/dist/runtime/env.js +12 -0
  36. package/dist/runtime/executor.d.ts +2 -1
  37. package/dist/runtime/executor.js +3 -36
  38. package/dist/runtime/insights.js +2 -2
  39. package/dist/runtime/otlp.d.ts +71 -2
  40. package/dist/runtime/otlp.js +397 -16
  41. package/dist/runtime/resolver-public.d.ts +1 -1
  42. package/dist/runtime/resolver-public.js +1 -1
  43. package/dist/runtime/resolver-vendors/capsolver.js +9 -3
  44. package/dist/runtime/resolver-vendors/twocaptcha.js +1 -0
  45. package/dist/runtime/resolver.d.ts +12 -0
  46. package/dist/runtime/resolver.js +45 -11
  47. package/dist/runtime/stealth.d.ts +13 -4
  48. package/dist/runtime/stealth.js +362 -85
  49. package/dist/runtime/trace-config.js +2 -1
  50. package/dist/runtime/trace.d.ts +5 -0
  51. package/dist/runtime/trace.js +43 -10
  52. package/dist/server/self-test.d.ts +1 -3
  53. package/dist/server/self-test.js +2 -12
  54. package/dist/server/serve-implementation.d.ts +6 -1
  55. package/dist/server/serve-implementation.js +55 -40
  56. package/dist/server/trace-output.d.ts +3 -1
  57. package/dist/server/trace-output.js +61 -2
  58. package/dist/stealth/profiles.d.ts +9 -8
  59. package/dist/stealth/profiles.js +123 -286
  60. package/dist/types.d.ts +116 -108
  61. package/package.json +2 -1
  62. package/src/cli/__tests__/fixtures/migrate-operation-declaration/approval-override.ts.txt +6 -0
  63. package/src/cli/__tests__/fixtures/migrate-operation-declaration/codemod-syntax.ts.txt +3 -0
  64. package/src/cli/__tests__/fixtures/migrate-operation-declaration/connection-precedence.ts.txt +10 -0
  65. package/src/cli/__tests__/fixtures/migrate-operation-declaration/docs-conflict.ts.txt +8 -0
  66. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-map.ts.txt +5 -0
  67. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-operation.ts.txt +16 -0
  68. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-map.ts.txt +3 -0
  69. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoist-all.ts.txt +31 -0
  70. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoisted-const.ts.txt +11 -0
  71. package/src/cli/__tests__/fixtures/migrate-operation-declaration/imported-spread.ts.txt +11 -0
  72. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-map.ts.txt +11 -0
  73. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-cast-tail.ts.txt +21 -0
  74. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-ekitan.ts.txt +11 -0
  75. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-override.ts.txt +14 -0
  76. package/src/cli/__tests__/fixtures/migrate-operation-declaration/missing-english-locale.ts.txt +7 -0
  77. package/src/cli/__tests__/fixtures/migrate-operation-declaration/no-safety.ts.txt +6 -0
  78. package/src/cli/__tests__/fixtures/migrate-operation-declaration/non-literal.ts.txt +7 -0
  79. package/src/cli/__tests__/fixtures/migrate-operation-declaration/redundant-approval.ts.txt +6 -0
  80. package/src/cli/__tests__/fixtures/migrate-operation-declaration/safety-conflict.ts.txt +7 -0
  81. package/src/cli/__tests__/fixtures/migrate-operation-declaration/stream.ts.txt +7 -0
  82. package/src/cli/__tests__/fixtures/migrate-operation-declaration/tool-router-spread.ts.txt +15 -0
  83. package/src/cli/__tests__/fixtures/migrate-operation-declaration/unparseable.ts.txt +4 -0
  84. package/src/cli/__tests__/fixtures/migrate-operation-declaration/verbatim-template.ts.txt +12 -0
  85. package/src/cli/commands.ts +13 -0
  86. package/src/cli/migrate-operation-declaration.ts +1654 -0
  87. package/src/cli/templates/provider/README.md.tpl +3 -3
  88. package/src/cli/templates/provider/operations/ping.ts.tpl +2 -0
  89. package/src/config/loader.ts +31 -6
  90. package/src/contract-types.ts +11 -5
  91. package/src/contract.ts +21 -10
  92. package/src/define.ts +107 -119
  93. package/src/dev.ts +4 -1
  94. package/src/engine.ts +279 -0
  95. package/src/index.ts +13 -5
  96. package/src/lint.ts +58 -92
  97. package/src/provider.ts +25 -3
  98. package/src/runtime/chrome149-header-order.ts +330 -0
  99. package/src/runtime/env.ts +13 -0
  100. package/src/runtime/executor.ts +7 -40
  101. package/src/runtime/insights.ts +2 -2
  102. package/src/runtime/otlp.ts +467 -21
  103. package/src/runtime/resolver-public.ts +3 -0
  104. package/src/runtime/resolver-vendors/capsolver.ts +12 -4
  105. package/src/runtime/resolver-vendors/twocaptcha.ts +1 -0
  106. package/src/runtime/resolver.ts +68 -19
  107. package/src/runtime/stealth.ts +435 -103
  108. package/src/runtime/trace-config.ts +3 -2
  109. package/src/runtime/trace.ts +57 -17
  110. package/src/server/self-test.ts +2 -9
  111. package/src/server/serve-implementation.ts +89 -72
  112. package/src/server/trace-output.ts +99 -2
  113. package/src/stealth/profiles.ts +169 -327
  114. package/src/types.ts +114 -137
@@ -2947,13 +2947,17 @@ function collectProviderRequiredLocaleKeys(provider: ProviderDefinition): string
2947
2947
 
2948
2948
  for (const operation of Object.values(provider.operations)) {
2949
2949
  addLocaleKeys(keys, [
2950
+ operation.titleKey,
2950
2951
  operation.descriptionKey,
2951
- operation.docs?.titleKey,
2952
- operation.docs?.descriptionKey,
2953
- operation.docs?.summaryKey,
2954
- operation.docs?.markdownKey,
2952
+ operation.summaryKey,
2953
+ operation.markdownKey,
2955
2954
  ...(operation.whenToUseKeys ?? []),
2956
2955
  ...(operation.whenNotToUseKeys ?? []),
2956
+ ...(operation.normalizationNotesKeys ?? []),
2957
+ ...(operation.examples ?? []).flatMap((example) => [
2958
+ example.scenarioKey,
2959
+ example.rationaleKey,
2960
+ ]),
2957
2961
  ...collectSchemaDescriptionKeys(operation.input),
2958
2962
  ...collectSchemaDescriptionKeys(operation.output),
2959
2963
  ]);
@@ -3020,8 +3024,8 @@ function scoreOperationMetadata(provider: ProviderDefinition): SubmitCheck {
3020
3024
  return true;
3021
3025
  })
3022
3026
  .map(([operationId]) => operationId);
3023
- const missingAnnotations = operations
3024
- .filter(([, operation]) => !operation.annotations)
3027
+ const missingRiskClass = operations
3028
+ .filter(([, operation]) => !operation.riskClass)
3025
3029
  .map(([operationId]) => operationId);
3026
3030
 
3027
3031
  if (weakDescriptions.length > 0) {
@@ -3033,30 +3037,30 @@ function scoreOperationMetadata(provider: ProviderDefinition): SubmitCheck {
3033
3037
  points: 0,
3034
3038
  maxPoints: CATEGORY_MAX_POINTS.operations,
3035
3039
  message: "One or more operations have weak descriptions.",
3036
- remediation: `For ${weakDescriptions.join(", ")}, add an operation \`descriptionKey\` backed by \`locales/en.json\` and \`locales/ko.json\`, or add a 150+ character \`description\` explaining when to use it, when not to use it, outputs, and caveats.`,
3040
+ remediation: `For ${weakDescriptions.join(", ")}, add an operation \`descriptionKey\` backed by \`locales/en.json\` and \`locales/ko.json\`.`,
3037
3041
  evidence: weakDescriptions,
3038
3042
  };
3039
3043
  }
3040
3044
 
3041
- const points = missingAnnotations.length > 0 ? 11 : CATEGORY_MAX_POINTS.operations;
3045
+ const points = missingRiskClass.length > 0 ? 11 : CATEGORY_MAX_POINTS.operations;
3042
3046
  return {
3043
3047
  id: "operation-metadata",
3044
3048
  category: "operations",
3045
- level: missingAnnotations.length > 0 ? "warn" : "info",
3046
- status: missingAnnotations.length > 0 ? "warn" : "pass",
3049
+ level: missingRiskClass.length > 0 ? "warn" : "info",
3050
+ status: missingRiskClass.length > 0 ? "warn" : "pass",
3047
3051
  points,
3048
3052
  maxPoints: CATEGORY_MAX_POINTS.operations,
3049
3053
  message:
3050
- missingAnnotations.length > 0
3051
- ? "Operations are described, but some are missing safety annotations."
3054
+ missingRiskClass.length > 0
3055
+ ? "Operations are described, but some are missing a safety classification."
3052
3056
  : "Operation descriptions and metadata are review-ready.",
3053
3057
  remediation:
3054
- missingAnnotations.length > 0
3055
- ? `For ${missingAnnotations.join(", ")}, add \`annotations\` with the applicable safety fields, such as \`readOnly\`, \`destructive\`, \`idempotent\`, \`openWorld\`, \`rateLimit\`, or \`timeoutMs\`.`
3058
+ missingRiskClass.length > 0
3059
+ ? `For ${missingRiskClass.join(", ")}, declare the operation's required \`riskClass\` as \`read\`, \`write\`, \`destructive\`, or \`external-send\`.`
3056
3060
  : undefined,
3057
3061
  evidence:
3058
- missingAnnotations.length > 0
3059
- ? missingAnnotations.map((operationId) => `${operationId}: missing annotations`)
3062
+ missingRiskClass.length > 0
3063
+ ? missingRiskClass.map((operationId) => `${operationId}: missing riskClass`)
3060
3064
  : operations.map(([operationId]) => operationId),
3061
3065
  };
3062
3066
  }
@@ -5332,25 +5336,6 @@ function scoreAuthSafety(provider: ProviderDefinition): SubmitCheck {
5332
5336
  };
5333
5337
  }
5334
5338
 
5335
- if (authMode === "none") {
5336
- const securedOperations = Object.entries(provider.operations).filter(
5337
- ([, operation]) => operation.annotations?.openWorld === false,
5338
- );
5339
- if (securedOperations.length > 0) {
5340
- return {
5341
- id: "auth-safety",
5342
- category: "auth",
5343
- level: "warn",
5344
- status: "warn",
5345
- points: 7,
5346
- maxPoints: CATEGORY_MAX_POINTS.auth,
5347
- message: "Provider is no-auth but at least one operation is not marked openWorld.",
5348
- remediation: `Either set \`auth.mode\` to the upstream auth model, or mark these public no-auth operations with \`annotations.openWorld: true\`: ${securedOperations.map(([operationId]) => operationId).join(", ")}.`,
5349
- evidence: securedOperations.map(([operationId]) => operationId),
5350
- };
5351
- }
5352
- }
5353
-
5354
5339
  return pass(
5355
5340
  "auth-safety",
5356
5341
  "auth",
@@ -1,4 +1,4 @@
1
- export type ApifuseCommandName = "create" | "dev" | "check" | "sync-assets" | "migrate-shape" | "submit-check" | "bounty-check" | "record" | "test" | "perf";
1
+ export type ApifuseCommandName = "create" | "dev" | "check" | "sync-assets" | "migrate-shape" | "migrate-operation-declaration" | "submit-check" | "bounty-check" | "record" | "test" | "perf";
2
2
  export type ApifuseCommandManifest = {
3
3
  name: ApifuseCommandName;
4
4
  summary: string;
@@ -37,6 +37,16 @@ export const COMMAND_MANIFEST = {
37
37
  examples: ["apifuse migrate-shape .", "apifuse migrate-shape . --check"],
38
38
  modulePath: "./apifuse-migrate-shape",
39
39
  },
40
+ "migrate-operation-declaration": {
41
+ name: "migrate-operation-declaration",
42
+ summary: "Migrate legacy nested operation declarations to the ADR-0009 flat shape, refusing ambiguous safety or metadata.",
43
+ usage: "apifuse migrate-operation-declaration [path] [--check] [--json]",
44
+ examples: [
45
+ "apifuse migrate-operation-declaration .",
46
+ "apifuse migrate-operation-declaration . --check --json",
47
+ ],
48
+ modulePath: "./apifuse-migrate-operation-declaration",
49
+ },
40
50
  "submit-check": {
41
51
  name: "submit-check",
42
52
  summary: "Score provider bounty submission readiness and emit checklist evidence.",
@@ -89,6 +99,7 @@ export const COMMAND_ORDER = [
89
99
  "check",
90
100
  "sync-assets",
91
101
  "migrate-shape",
102
+ "migrate-operation-declaration",
92
103
  "submit-check",
93
104
  "record",
94
105
  "test",
@@ -0,0 +1,59 @@
1
+ export type OperationDeclarationRefusalReason = "no_safety" | "safety_conflict" | "locale_key_conflict" | "connection_mode_conflict" | "execution_conflict" | "approval_conflict" | "non_literal" | "unsupported_member" | "factory_composed_operations" | "source_syntax" | "codemod_syntax" | "missing_english_locale" | "operation_id_unresolved" | "examples_conflict" | "locale_todo_conflict";
2
+ export type OperationDeclarationRefusal = {
3
+ readonly file: string;
4
+ readonly operationKey: string;
5
+ readonly reason: OperationDeclarationRefusalReason;
6
+ readonly detail: string;
7
+ };
8
+ export type LocaleTodo = {
9
+ readonly localeFile: string;
10
+ readonly operationKey: string;
11
+ readonly key: string;
12
+ readonly originalProse: string;
13
+ };
14
+ export type OperationDeclarationMigration = {
15
+ readonly status: "migrated";
16
+ readonly code: string;
17
+ readonly operations: number;
18
+ readonly localeTodos: readonly LocaleTodo[];
19
+ } | {
20
+ readonly status: "unchanged";
21
+ readonly code: string;
22
+ readonly operations: number;
23
+ } | {
24
+ readonly status: "refused";
25
+ readonly refusals: readonly OperationDeclarationRefusal[];
26
+ };
27
+ export type OperationDeclarationMigrationOptions = {
28
+ /** Exact operation ids proven from a static operations map, keyed by local binding name. */
29
+ readonly operationIds?: ReadonlyMap<string, string>;
30
+ /** Locale paths relative to the provider root. */
31
+ readonly localeFiles?: readonly string[];
32
+ };
33
+ /**
34
+ * Rewrite every operation declaration in one TypeScript module.
35
+ *
36
+ * The function is file-atomic: a single refusal discards every planned edit.
37
+ * It uses AST ranges as a string/comment/template-aware brace balancer and
38
+ * copies every untouched source slice byte-for-byte.
39
+ */
40
+ export declare function migrateOperationDeclaration(sourceText: string, fileName: string, options?: OperationDeclarationMigrationOptions): OperationDeclarationMigration;
41
+ /** Parse a proposed rewrite and classify a codemod-introduced syntax failure. */
42
+ export declare function verifyOperationDeclarationRewrite(code: string, fileName: string): OperationDeclarationRefusal | undefined;
43
+ export type OperationDeclarationRepositoryResult = {
44
+ readonly status: "migrated" | "would-migrate" | "unchanged";
45
+ readonly providerRoot: string;
46
+ readonly changedFiles: readonly string[];
47
+ readonly operationCount: number;
48
+ readonly sidecar?: string;
49
+ readonly localeTodoCount: number;
50
+ } | {
51
+ readonly status: "refused";
52
+ readonly providerRoot: string;
53
+ readonly refusals: readonly OperationDeclarationRefusal[];
54
+ };
55
+ /** Run the file transform repository-wide, committing writes only if every file is provable. */
56
+ export declare function migrateOperationDeclarationRepository(providerRootInput: string, options?: {
57
+ readonly check?: boolean;
58
+ }): OperationDeclarationRepositoryResult;
59
+ export declare function renderLocaleTodoSidecar(todos: readonly LocaleTodo[]): string;