@santi020k/lumen 3.0.1 → 4.1.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.
Files changed (125) hide show
  1. package/README.md +211 -3
  2. package/dist/cli.js +49 -5
  3. package/dist/consumer-upgrade-audit.d.ts +10 -0
  4. package/dist/consumer-upgrade-audit.d.ts.map +1 -0
  5. package/dist/consumer-upgrade-audit.js +52 -0
  6. package/dist/index.d.ts +3 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +3 -0
  9. package/dist/installer.d.ts.map +1 -1
  10. package/dist/installer.js +16 -0
  11. package/dist/integration-diagnostics.d.ts.map +1 -1
  12. package/dist/integration-diagnostics.js +199 -3
  13. package/dist/registry-component-name.d.ts +2 -0
  14. package/dist/registry-component-name.d.ts.map +1 -0
  15. package/dist/registry-component-name.js +53 -0
  16. package/dist/registry-data.d.ts +339 -18
  17. package/dist/registry-data.d.ts.map +1 -1
  18. package/dist/registry-data.js +789 -3
  19. package/dist/registry.d.ts.map +1 -1
  20. package/dist/registry.js +11 -9
  21. package/dist/source-script-ranges.d.ts +3 -0
  22. package/dist/source-script-ranges.d.ts.map +1 -0
  23. package/dist/source-script-ranges.js +41 -0
  24. package/dist/v2-migration.d.ts +38 -0
  25. package/dist/v2-migration.d.ts.map +1 -1
  26. package/dist/v2-migration.js +26 -14
  27. package/dist/v4-migration.d.ts +26 -0
  28. package/dist/v4-migration.d.ts.map +1 -0
  29. package/dist/v4-migration.js +272 -0
  30. package/dist/version-migration-dependencies.d.ts +8 -0
  31. package/dist/version-migration-dependencies.d.ts.map +1 -0
  32. package/dist/version-migration-dependencies.js +10 -0
  33. package/dist/version-migration-source.d.ts +4 -0
  34. package/dist/version-migration-source.d.ts.map +1 -0
  35. package/dist/version-migration-source.js +281 -0
  36. package/dist/version-migration.d.ts +34 -0
  37. package/dist/version-migration.d.ts.map +1 -0
  38. package/dist/version-migration.js +158 -0
  39. package/native-components.json +564 -17
  40. package/package.json +26 -11
  41. package/release-manifest.json +22 -17
  42. package/styles/critical.css +696 -66
  43. package/styles/motion.css +61 -0
  44. package/styles/world-map.css +30 -0
  45. package/styles.css +1756 -409
  46. package/templates/astro/advanced-fields/src/lumen/advanced-fields.astro +35 -0
  47. package/templates/astro/ai-docs/llms.txt +3 -0
  48. package/templates/astro/analytics-dashboard/src/lumen/analytics-dashboard.astro +110 -0
  49. package/templates/astro/auth-onboarding/src/lumen/auth-onboarding.astro +107 -0
  50. package/templates/astro/command-center/src/lumen/command-center.astro +34 -0
  51. package/templates/astro/commerce-dashboard/src/lumen/commerce-dashboard.astro +108 -0
  52. package/templates/astro/content-flow-actions/src/lumen/content-flow-actions.astro +10 -0
  53. package/templates/astro/content-flow-header/src/lumen/content-flow-header.astro +14 -0
  54. package/templates/astro/content-flow-list/src/lumen/content-flow-list.astro +13 -0
  55. package/templates/astro/content-flow-settings/src/lumen/content-flow-settings.astro +17 -0
  56. package/templates/astro/data-collections/src/lumen/data-collections.astro +52 -0
  57. package/templates/astro/feature-preview/src/lumen/feature-preview.astro +32 -0
  58. package/templates/astro/guided-onboarding/src/lumen/guided-onboarding.astro +35 -0
  59. package/templates/astro/interactive-pricing/src/lumen/interactive-pricing.astro +32 -0
  60. package/templates/astro/media-workspace/src/lumen/adjustment-controls.astro +89 -0
  61. package/templates/astro/media-workspace/src/lumen/media-processing.astro +47 -0
  62. package/templates/astro/media-workspace/src/lumen/media-workspace.astro +77 -0
  63. package/templates/astro/page-header/src/lumen/page-header.astro +41 -0
  64. package/templates/astro/project-workspace/src/lumen/project-workspace.astro +103 -0
  65. package/templates/astro/rich-text-editor/src/lumen/rich-text-editor.astro +21 -0
  66. package/templates/astro/saas-admin/src/lumen/saas-admin.astro +110 -0
  67. package/templates/astro/scheduler/src/lumen/scheduler.astro +36 -0
  68. package/templates/astro/section-header/src/lumen/section-header.astro +35 -0
  69. package/templates/astro/theme-builder/src/lumen/theme-builder.astro +28 -0
  70. package/templates/elements/advanced-fields/src/lumen/advanced-fields.html +25 -0
  71. package/templates/elements/analytics-dashboard/src/lumen/analytics-dashboard.html +28 -0
  72. package/templates/elements/auth-onboarding/src/lumen/auth-onboarding.html +79 -0
  73. package/templates/elements/command-center/src/lumen/command-center.html +15 -0
  74. package/templates/elements/commerce-dashboard/src/lumen/commerce-dashboard.html +24 -0
  75. package/templates/elements/content-flow-actions/src/lumen/content-flow-actions.html +11 -0
  76. package/templates/elements/content-flow-header/src/lumen/content-flow-header.html +15 -0
  77. package/templates/elements/content-flow-list/src/lumen/content-flow-list.html +14 -0
  78. package/templates/elements/content-flow-settings/src/lumen/content-flow-settings.html +18 -0
  79. package/templates/elements/data-collections/src/lumen/data-collections.html +31 -0
  80. package/templates/elements/feature-preview/src/lumen/feature-preview.html +13 -0
  81. package/templates/elements/guided-onboarding/src/lumen/guided-onboarding.html +16 -0
  82. package/templates/elements/interactive-pricing/src/lumen/interactive-pricing.html +13 -0
  83. package/templates/elements/media-workspace/src/lumen/media-workspace.html +57 -0
  84. package/templates/elements/media-workspace/src/lumen/media-workspace.ts +163 -0
  85. package/templates/elements/page-header/src/lumen/page-header.html +20 -0
  86. package/templates/elements/project-workspace/src/lumen/project-workspace.html +17 -0
  87. package/templates/elements/rich-text-editor/src/lumen/rich-text-editor.html +17 -0
  88. package/templates/elements/saas-admin/src/lumen/saas-admin.html +18 -0
  89. package/templates/elements/scheduler/src/lumen/scheduler.html +27 -0
  90. package/templates/elements/section-header/src/lumen/section-header.html +21 -0
  91. package/templates/elements/theme-builder/src/lumen/theme-builder.html +59 -0
  92. package/templates/react/advanced-fields/src/lumen/advanced-fields.tsx +37 -0
  93. package/templates/react/analytics-dashboard/src/lumen/analytics-dashboard.tsx +143 -0
  94. package/templates/react/auth-onboarding/src/lumen/auth-onboarding.tsx +129 -0
  95. package/templates/react/command-center/src/lumen/command-center.tsx +85 -0
  96. package/templates/react/commerce-dashboard/src/lumen/commerce-dashboard.tsx +148 -0
  97. package/templates/react/content-flow-actions/src/lumen/content-flow-actions.tsx +11 -0
  98. package/templates/react/content-flow-header/src/lumen/content-flow-header.tsx +14 -0
  99. package/templates/react/content-flow-list/src/lumen/content-flow-list.tsx +19 -0
  100. package/templates/react/content-flow-settings/src/lumen/content-flow-settings.tsx +26 -0
  101. package/templates/react/data-collections/src/lumen/data-collections.tsx +60 -0
  102. package/templates/react/feature-preview/src/lumen/feature-preview.tsx +42 -0
  103. package/templates/react/guided-onboarding/src/lumen/guided-onboarding.tsx +100 -0
  104. package/templates/react/import-review/src/lumen/import-review.tsx +150 -0
  105. package/templates/react/interactive-pricing/src/lumen/interactive-pricing.tsx +60 -0
  106. package/templates/react/media-workspace/src/lumen/adjustment-controls.tsx +61 -0
  107. package/templates/react/media-workspace/src/lumen/media-processing.tsx +43 -0
  108. package/templates/react/media-workspace/src/lumen/media-workspace.tsx +100 -0
  109. package/templates/react/operational-records/src/lumen/operational-records.tsx +92 -0
  110. package/templates/react/page-header/src/lumen/page-header.tsx +41 -0
  111. package/templates/react/project-workspace/src/lumen/project-workspace.tsx +112 -0
  112. package/templates/react/record-workspace/src/lumen/record-workspace.tsx +67 -0
  113. package/templates/react/review-workflow/src/lumen/review-workflow.tsx +202 -0
  114. package/templates/react/rich-text-editor/src/lumen/rich-text-editor.tsx +33 -0
  115. package/templates/react/saas-admin/src/lumen/saas-admin.tsx +119 -0
  116. package/templates/react/scheduler/src/lumen/scheduler.tsx +45 -0
  117. package/templates/react/section-header/src/lumen/section-header.tsx +33 -0
  118. package/templates/react/styles.d.ts +1 -0
  119. package/templates/react/theme-builder/src/lumen/theme-builder.tsx +57 -0
  120. package/templates/react/tsconfig.json +14 -0
  121. package/templates/react/validated-form/src/lumen/validated-form.tsx +166 -0
  122. package/templates/shared/common/src/lumen/lumen-template.css +247 -0
  123. package/templates/shared/media-workspace/src/lumen/media-workspace.css +14 -0
  124. package/templates/shared/visual-blocks/src/lumen/product-blocks.ts +224 -0
  125. package/v4-migration.json +448 -0
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,OAAO,KAAK,EACV,aAAa,EACb,sBAAsB,EACtB,8BAA8B,EAC9B,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,aAAa,EAAE,CAAA;AAExB,YAAY,EACV,aAAa,EACb,sBAAsB,EACtB,8BAA8B,EAC9B,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACzB,CAAA;AAwBD,eAAO,MAAM,uBAAuB,GAAI,WAAU,aAA6B,KAAG,kBAAkB,EAGnG,CAAA;AAED,eAAO,MAAM,oBAAoB,GAC/B,MAAM,MAAM,EACZ,WAAU,aAA6B,KACtC,kBAAkB,GAAG,SAQvB,CAAA;AA6JD,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,MAAM,GAAG,GAAG,EACpB,UAAS,wBAA6B,KACrC,OAAO,CAAC,aAAa,CAsBvB,CAAA;AAED,OAAO,EACL,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,OAAO,KAAK,EACV,aAAa,EACb,sBAAsB,EACtB,8BAA8B,EAC9B,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,aAAa,EAAE,CAAA;AAExB,YAAY,EACV,aAAa,EACb,sBAAsB,EACtB,8BAA8B,EAC9B,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACzB,CAAA;AAwBD,eAAO,MAAM,uBAAuB,GAAI,WAAU,aAA6B,KAAG,kBAAkB,EAGnG,CAAA;AAED,eAAO,MAAM,oBAAoB,GAC/B,MAAM,MAAM,EACZ,WAAU,aAA6B,KACtC,kBAAkB,GAAG,SAQvB,CAAA;AAsKD,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,MAAM,GAAG,GAAG,EACpB,UAAS,wBAA6B,KACrC,OAAO,CAAC,aAAa,CAsBvB,CAAA;AAED,OAAO,EACL,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAA"}
package/dist/registry.js CHANGED
@@ -1,5 +1,5 @@
1
- /* eslint-disable complexity */
2
1
  import { readFile, stat } from 'node:fs/promises';
2
+ import { isSafeRegistryComponentName } from './registry-component-name.js';
3
3
  import { lumenRegistry } from './registry-data.js';
4
4
  import { isSafeRegistryFilePath } from './registry-path.js';
5
5
  export { lumenRegistry };
@@ -50,30 +50,32 @@ const isRegistryItem = (value) => {
50
50
  (item.components === undefined || isStringArray(item.components)) &&
51
51
  (item.files === undefined || isRegistryFileArray(item.files)));
52
52
  };
53
+ const isNonEmptyString = (value) => typeof value === 'string' && value.trim().length > 0;
53
54
  const isRegistryComponent = (value) => {
54
55
  if (!value || typeof value !== 'object')
55
56
  return false;
56
57
  const component = value;
57
- return (typeof component.name === 'string' && component.name.trim().length > 0 &&
58
+ return (isSafeRegistryComponentName(component.name) &&
58
59
  component.type === 'component' &&
59
- typeof component.description === 'string' && component.description.trim().length > 0 &&
60
- typeof component.category === 'string' && component.category.trim().length > 0 &&
60
+ isNonEmptyString(component.description) &&
61
+ isNonEmptyString(component.category) &&
61
62
  isRegistryFileArray(component.files) &&
62
63
  (component.dependencies === undefined || isStringArray(component.dependencies)));
63
64
  };
65
+ const isRegistryComponents = (value) => (Array.isArray(value) && value.every((component) => isRegistryComponent(component)));
66
+ const isPositiveSafeInteger = (value) => (typeof value === 'number' && Number.isSafeInteger(value) && value > 0);
64
67
  const isLumenRegistry = (value) => {
65
68
  if (!value || typeof value !== 'object')
66
69
  return false;
67
70
  const registry = value;
68
- return (typeof registry.name === 'string' && registry.name.trim().length > 0 &&
69
- typeof registry.version === 'number' &&
70
- Number.isSafeInteger(registry.version) && registry.version > 0 &&
71
- typeof registry.description === 'string' && registry.description.trim().length > 0 &&
71
+ return (isNonEmptyString(registry.name) &&
72
+ isPositiveSafeInteger(registry.version) &&
73
+ isNonEmptyString(registry.description) &&
72
74
  isStringArray(registry.packages) &&
73
75
  Array.isArray(registry.items) &&
74
76
  registry.items.every(item => isRegistryItem(item)) &&
75
77
  (registry.components === undefined ||
76
- (Array.isArray(registry.components) && registry.components.every(component => isRegistryComponent(component)))));
78
+ isRegistryComponents(registry.components)));
77
79
  };
78
80
  const getResponseBody = (response) => response.body;
79
81
  const readBoundedResponse = async (response, maxBytes) => {
@@ -0,0 +1,3 @@
1
+ /** Use compiler grammar for regex/division; callers fail closed when the parser exceeds its nesting limit. */
2
+ export declare const scriptRegexRanges: (source: string, file: string) => ReadonlyMap<number, number> | undefined;
3
+ //# sourceMappingURL=source-script-ranges.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-script-ranges.d.ts","sourceRoot":"","sources":["../src/source-script-ranges.ts"],"names":[],"mappings":"AAsBA,8GAA8G;AAC9G,eAAO,MAAM,iBAAiB,GAAI,QAAQ,MAAM,EAAE,MAAM,MAAM,KAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SA0B9F,CAAA"}
@@ -0,0 +1,41 @@
1
+ import { createSourceFile, ScriptKind, ScriptTarget, SyntaxKind } from 'typescript';
2
+ const frontmatter = (source) => {
3
+ if (!source.startsWith('---'))
4
+ return { offset: 0, source: '' };
5
+ const end = source.indexOf('\n---', 3);
6
+ return { offset: 3, source: source.slice(3, end < 0 ? source.length : end) };
7
+ };
8
+ const parseRoot = (source, file) => {
9
+ const jsx = ['.tsx', '.jsx'].some(extension => file.endsWith(extension));
10
+ try {
11
+ return createSourceFile(file, source, ScriptTarget.Latest, false, jsx ? ScriptKind.TSX : ScriptKind.TS);
12
+ }
13
+ catch (error) {
14
+ if (!(error instanceof RangeError))
15
+ throw error;
16
+ return undefined;
17
+ }
18
+ };
19
+ /** Use compiler grammar for regex/division; callers fail closed when the parser exceeds its nesting limit. */
20
+ export const scriptRegexRanges = (source, file) => {
21
+ if (['.html', '.htm', '.css', '.swift', '.kt', '.kts'].some(extension => file.endsWith(extension)))
22
+ return new Map();
23
+ const fragment = file.endsWith('.astro') ? frontmatter(source) : { offset: 0, source };
24
+ const root = parseRoot(fragment.source, file);
25
+ if (!root)
26
+ return undefined;
27
+ const pending = [root];
28
+ const ranges = new Map();
29
+ while (pending.length > 0) {
30
+ const node = pending.pop();
31
+ if (!node)
32
+ continue;
33
+ if (node.kind === SyntaxKind.RegularExpressionLiteral) {
34
+ ranges.set(node.getStart(root) + fragment.offset, node.end + fragment.offset);
35
+ }
36
+ node.forEachChild(child => {
37
+ pending.push(child);
38
+ });
39
+ }
40
+ return ranges;
41
+ };
@@ -23,7 +23,45 @@ export interface LumenV2MigrationReport {
23
23
  manualReview: LumenV2MigrationFinding[];
24
24
  root: string;
25
25
  }
26
+ interface ImportStatement {
27
+ clause: string;
28
+ end: number;
29
+ module: string;
30
+ quote: '\'' | '"';
31
+ semicolon: boolean;
32
+ start: number;
33
+ }
34
+ interface NamedImport {
35
+ imported: string;
36
+ local: string;
37
+ source: string;
38
+ typeOnly: boolean;
39
+ }
40
+ interface ParsedNamedImports {
41
+ close: number;
42
+ complete: boolean;
43
+ imports: NamedImport[];
44
+ open: number;
45
+ }
46
+ interface MarkupAttribute {
47
+ end: number;
48
+ name: string;
49
+ nameEnd: number;
50
+ nameStart: number;
51
+ start: number;
52
+ value: string | undefined;
53
+ valueKind: 'boolean' | 'expression' | 'literal';
54
+ }
55
+ export declare const findImportStatements: (source: string, module: string) => ImportStatement[];
56
+ export declare const parseNamedImports: (clause: string) => ParsedNamedImports | undefined;
57
+ export declare const findBalancedEnd: (source: string, start: number, opening: string, closing: string) => number;
58
+ export declare const parseMarkupAttributes: (source: string, start: number, end: number) => MarkupAttribute[];
59
+ export declare const findMarkupTagEnd: (source: string, start: number, rejectNestedTags?: boolean) => number;
60
+ export declare const getTagNameEnd: (source: string, start: number) => number;
61
+ export declare const getMarkupStart: (source: string, file: string) => number;
26
62
  export declare const migrateLumenV2Source: (source: string, file?: string) => LumenV2SourceMigration;
63
+ export declare const discoverSourceFiles: (path: string, extensions?: ReadonlySet<string>) => Promise<string[]>;
27
64
  export declare const migrateLumenV2: (options?: LumenV2MigrationOptions) => Promise<LumenV2MigrationReport>;
28
65
  export declare const formatLumenV2Migration: (report: LumenV2MigrationReport) => string;
66
+ export {};
29
67
  //# sourceMappingURL=v2-migration.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"v2-migration.d.ts","sourceRoot":"","sources":["../src/v2-migration.ts"],"names":[],"mappings":"AA4CA,MAAM,MAAM,oBAAoB,GAC5B,uBAAuB,GACzB,+BAA+B,GAC/B,sBAAsB,GACtB,2BAA2B,CAAA;AAE7B,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,oBAAoB,CAAA;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,uBAAuB,EAAE,CAAA;IAClC,YAAY,EAAE,uBAAuB,EAAE,CAAA;IACvC,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,OAAO,EAAE,uBAAuB,EAAE,CAAA;IAClC,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,uBAAuB,EAAE,CAAA;IACvC,IAAI,EAAE,MAAM,CAAA;CACb;AA8nCD,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,MAAM,EACd,aAAiB,KAChB,sBA4DF,CAAA;AAqBD,eAAO,MAAM,cAAc,GACzB,UAAS,uBAA4B,KACpC,OAAO,CAAC,sBAAsB,CAgChC,CAAA;AAED,eAAO,MAAM,sBAAsB,GACjC,QAAQ,sBAAsB,KAC7B,MA0BF,CAAA"}
1
+ {"version":3,"file":"v2-migration.d.ts","sourceRoot":"","sources":["../src/v2-migration.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { readdir, readFile, stat, writeFile } from 'node:fs/promises';
1
+ import { lstat, readdir, readFile, writeFile } from 'node:fs/promises';
2
2
  import { extname, relative, resolve } from 'node:path';
3
3
  // cspell:words swiftpm
4
4
  const ASTRO_PACKAGE = '@santi020k/lumen-astro';
@@ -76,7 +76,7 @@ const createFinding = (source, file, index, kind, message) => ({
76
76
  kind,
77
77
  message
78
78
  });
79
- const findImportStatements = (source, module) => {
79
+ export const findImportStatements = (source, module) => {
80
80
  const statements = [];
81
81
  for (const quote of ['\'', '"']) {
82
82
  const needle = `${quote}${module}${quote}`;
@@ -101,7 +101,7 @@ const findImportStatements = (source, module) => {
101
101
  }
102
102
  return statements.sort((left, right) => left.start - right.start);
103
103
  };
104
- const parseNamedImports = (clause) => {
104
+ export const parseNamedImports = (clause) => {
105
105
  const open = clause.indexOf('{');
106
106
  const close = clause.lastIndexOf('}');
107
107
  if (open < 0 || close <= open)
@@ -136,7 +136,7 @@ const formatImport = (clause, statement) => `import ${clause} from ${statement.q
136
136
  const applyEdits = (source, edits) => edits
137
137
  .sort((left, right) => right.start - left.start)
138
138
  .reduce((result, edit) => `${result.slice(0, edit.start)}${edit.replacement}${result.slice(edit.end)}`, source);
139
- const findBalancedEnd = (source, start, opening, closing) => {
139
+ export const findBalancedEnd = (source, start, opening, closing) => {
140
140
  let depth = 0;
141
141
  let quote;
142
142
  for (let index = start; index < source.length; index += 1) {
@@ -236,7 +236,7 @@ const parseMarkupAttribute = (source, start, end) => {
236
236
  const valueStart = skipWhitespace(source, equalsStart + 1, end);
237
237
  return parseMarkupAttributeValue(source, start, nameEnd, name, valueStart, end);
238
238
  };
239
- const parseMarkupAttributes = (source, start, end) => {
239
+ export const parseMarkupAttributes = (source, start, end) => {
240
240
  const attributes = [];
241
241
  let cursor = start;
242
242
  while (cursor < end) {
@@ -255,7 +255,14 @@ const advanceQuotedSource = (character, quote) => ({
255
255
  close: character === quote,
256
256
  skip: character === '\\'
257
257
  });
258
- const findMarkupTagEnd = (source, start) => {
258
+ const getMarkupBoundary = (character, braceDepth, rejectNestedTags, index) => {
259
+ if (braceDepth !== 0)
260
+ return undefined;
261
+ if (character === '>')
262
+ return index;
263
+ return character === '<' && rejectNestedTags ? -1 : undefined;
264
+ };
265
+ export const findMarkupTagEnd = (source, start, rejectNestedTags = false) => {
259
266
  let braceDepth = 0;
260
267
  let quote;
261
268
  for (let index = start; index < source.length; index += 1) {
@@ -274,8 +281,11 @@ const findMarkupTagEnd = (source, start) => {
274
281
  braceDepth += 1;
275
282
  else if (character === '}')
276
283
  braceDepth = Math.max(0, braceDepth - 1);
277
- else if (character === '>' && braceDepth === 0)
278
- return index;
284
+ else {
285
+ const boundary = getMarkupBoundary(character, braceDepth, rejectNestedTags, index);
286
+ if (boundary !== undefined)
287
+ return boundary;
288
+ }
279
289
  }
280
290
  return source.length;
281
291
  };
@@ -359,7 +369,7 @@ const migrateRuntimeImports = (source, file) => {
359
369
  }
360
370
  return { changes, manualReview, source: applyEdits(source, edits) };
361
371
  };
362
- const getTagNameEnd = (source, start) => {
372
+ export const getTagNameEnd = (source, start) => {
363
373
  let end = start;
364
374
  while (/[\w:.-]/u.test(source[end] ?? ''))
365
375
  end += 1;
@@ -400,7 +410,7 @@ const inspectVisualSize = (source, file, tagName, replacementName, attributes) =
400
410
  review: createFinding(source, file, size.start, 'visual-size-alias-removal', message)
401
411
  };
402
412
  };
403
- const getMarkupStart = (source, file) => {
413
+ export const getMarkupStart = (source, file) => {
404
414
  if (!file.endsWith('.astro'))
405
415
  return 0;
406
416
  const opening = /^(?:\uFEFF)?\s*---\s*(?:\r?\n|$)/u.exec(source);
@@ -675,14 +685,16 @@ export const migrateLumenV2Source = (source, file = '<source>') => {
675
685
  source: sonnerElements.source
676
686
  };
677
687
  };
678
- const discoverSourceFiles = async (path) => {
679
- const details = await stat(path);
688
+ export const discoverSourceFiles = async (path, extensions = SOURCE_EXTENSIONS) => {
689
+ const details = await lstat(path);
690
+ if (details.isSymbolicLink())
691
+ return [];
680
692
  if (details.isFile())
681
- return SOURCE_EXTENSIONS.has(extname(path)) ? [path] : [];
693
+ return extensions.has(extname(path)) ? [path] : [];
682
694
  const entries = await readdir(path, { withFileTypes: true });
683
695
  const nested = await Promise.all(entries
684
696
  .filter(entry => !entry.isDirectory() || !IGNORED_DIRECTORIES.has(entry.name))
685
- .map(entry => discoverSourceFiles(resolve(path, entry.name))));
697
+ .map(entry => discoverSourceFiles(resolve(path, entry.name), extensions)));
686
698
  return nested.flat().sort();
687
699
  };
688
700
  export const migrateLumenV2 = async (options = {}) => {
@@ -0,0 +1,26 @@
1
+ export interface LumenV4MigrationFinding {
2
+ column: number;
3
+ file: string;
4
+ line: number;
5
+ message: string;
6
+ rule: string;
7
+ }
8
+ export interface LumenV4MigrationReport {
9
+ applied: boolean;
10
+ changedFiles: string[];
11
+ changes: LumenV4MigrationFinding[];
12
+ filesScanned: number;
13
+ manualReview: LumenV4MigrationFinding[];
14
+ packageVersions: Record<string, string>;
15
+ root: string;
16
+ targetVersion: string;
17
+ }
18
+ export declare const migrateLumenV4Source: (source: string, file?: string) => {
19
+ changes: LumenV4MigrationFinding[];
20
+ source: string;
21
+ };
22
+ export declare const migrateLumenV4: (options?: {
23
+ apply?: boolean | undefined;
24
+ cwd?: string | undefined;
25
+ }) => Promise<LumenV4MigrationReport>;
26
+ //# sourceMappingURL=v4-migration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v4-migration.d.ts","sourceRoot":"","sources":["../src/v4-migration.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,OAAO,EAAE,uBAAuB,EAAE,CAAA;IAClC,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,uBAAuB,EAAE,CAAA;IACvC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACvC,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,CAAA;CACtB;AAqKD,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,EAAE,aAAiB,KAAG;IACvE,OAAO,EAAE,uBAAuB,EAAE,CAAA;IAClC,MAAM,EAAE,MAAM,CAAA;CAuCf,CAAA;AA+HD,eAAO,MAAM,cAAc,GACzB,UAAS;IAAE,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAO,KACtE,OAAO,CAAC,sBAAsB,CAwBhC,CAAA"}
@@ -0,0 +1,272 @@
1
+ import { readdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { createRequire } from 'node:module';
3
+ import { basename, extname, join, relative, resolve } from 'node:path';
4
+ import { pathToFileURL } from 'node:url';
5
+ import { scriptRegexRanges } from './source-script-ranges.js';
6
+ const modules = new Map([
7
+ ['@modelcontextprotocol/sdk/client/index.js', '@modelcontextprotocol/client'],
8
+ ['@modelcontextprotocol/sdk/client/stdio.js', '@modelcontextprotocol/client/stdio'],
9
+ ['@modelcontextprotocol/sdk/server/mcp.js', '@modelcontextprotocol/server'],
10
+ ['@modelcontextprotocol/sdk/server/stdio.js', '@modelcontextprotocol/server/stdio']
11
+ ]);
12
+ const sourceExtensions = new Set(['.astro', '.html', '.htm', '.js', '.jsx', '.mjs', '.ts', '.tsx', '.swift', '.kt', '.kts']);
13
+ const ignored = new Set(['.git', '.build', '.astro', '.next', '.expo', '.turbo', '.wrangler', '.swiftpm', 'node_modules', 'dist', 'build', 'coverage', 'Pods', 'DerivedData', 'vendor']);
14
+ const identifier = (character) => /[A-Za-z0-9_$]/u.test(character);
15
+ const stringToken = (source, start, quote) => {
16
+ let end = start + 1;
17
+ while (end < source.length && source[end] !== quote)
18
+ end += source[end] === '\\' ? 2 : 1;
19
+ end = Math.min(end + 1, source.length);
20
+ return { end, kind: 'string', start, value: source.slice(start + 1, end - 1) };
21
+ };
22
+ const commentAt = (source, start) => {
23
+ if (source.startsWith('//', start)) {
24
+ const end = source.indexOf('\n', start + 2);
25
+ return end < 0 ? source.length : end;
26
+ }
27
+ if (source.startsWith('/*', start)) {
28
+ const end = source.indexOf('*/', start + 2);
29
+ return end < 0 ? source.length : end + 2;
30
+ }
31
+ return undefined;
32
+ };
33
+ // Comments and complete string/template literals are consumed once. Never edit text examples.
34
+ const tokenAt = (source, start) => {
35
+ const character = source[start] ?? '';
36
+ if (/\s/u.test(character))
37
+ return start + 1;
38
+ const commentEnd = commentAt(source, start);
39
+ if (commentEnd !== undefined)
40
+ return commentEnd;
41
+ if (['"', '\'', '`'].includes(character))
42
+ return stringToken(source, start, character);
43
+ if (identifier(character)) {
44
+ let end = start + 1;
45
+ while (end < source.length && identifier(source[end] ?? ''))
46
+ end += 1;
47
+ return { end, kind: 'identifier', start, value: source.slice(start, end) };
48
+ }
49
+ return { end: start + 1, kind: 'punctuation', start, value: character };
50
+ };
51
+ const tokenize = (source, exclusions) => {
52
+ const tokens = [];
53
+ let cursor = 0;
54
+ while (cursor < source.length) {
55
+ const excludedEnd = exclusions.get(cursor);
56
+ if (excludedEnd !== undefined) {
57
+ cursor = excludedEnd;
58
+ continue;
59
+ }
60
+ const token = tokenAt(source, cursor);
61
+ if (typeof token === 'number')
62
+ cursor = token;
63
+ else {
64
+ tokens.push(token);
65
+ cursor = token.end;
66
+ }
67
+ }
68
+ return tokens;
69
+ };
70
+ const location = (source, index) => {
71
+ const prefix = source.slice(0, index);
72
+ return { column: index - prefix.lastIndexOf('\n'), line: prefix.split('\n').length };
73
+ };
74
+ const planImport = (source, token, state, startsLine) => {
75
+ if (token.value === 'import') {
76
+ state.inImport = startsLine;
77
+ state.afterFrom = false;
78
+ return undefined;
79
+ }
80
+ if (!state.inImport)
81
+ return undefined;
82
+ if ([';', '(', '='].includes(token.value)) {
83
+ state.inImport = false;
84
+ return undefined;
85
+ }
86
+ if (token.kind === 'identifier' && token.value === 'from') {
87
+ state.afterFrom = true;
88
+ return undefined;
89
+ }
90
+ if (token.kind !== 'string')
91
+ return undefined;
92
+ state.inImport = false;
93
+ const replacement = modules.get(token.value);
94
+ if (!state.afterFrom)
95
+ return undefined;
96
+ if (!replacement)
97
+ return undefined;
98
+ if (source[token.start] === '`')
99
+ return undefined;
100
+ return { end: token.end - 1, replacement, start: token.start + 1 };
101
+ };
102
+ const advancePosition = (source, end, position) => {
103
+ while (position.cursor < end) {
104
+ const character = source[position.cursor] ?? '';
105
+ if (character === '\n') {
106
+ position.line += 1;
107
+ position.column = 1;
108
+ position.blankPrefix = true;
109
+ }
110
+ else {
111
+ position.column += 1;
112
+ if (!/\s/u.test(character))
113
+ position.blankPrefix = false;
114
+ }
115
+ position.cursor += 1;
116
+ }
117
+ };
118
+ export const migrateLumenV4Source = (source, file = '<source>') => {
119
+ const exclusions = scriptRegexRanges(source, file);
120
+ if (!exclusions)
121
+ return { changes: [], source };
122
+ const edits = [];
123
+ const changes = [];
124
+ const state = { afterFrom: false, inImport: false };
125
+ const position = { blankPrefix: true, column: 1, cursor: 0, line: 1 };
126
+ for (const token of tokenize(source, exclusions)) {
127
+ advancePosition(source, token.start, position);
128
+ const edit = planImport(source, token, state, position.blankPrefix);
129
+ if (!edit)
130
+ continue;
131
+ edits.push(edit);
132
+ changes.push({
133
+ column: position.column,
134
+ line: position.line,
135
+ file,
136
+ message: `Replace ${token.value} with ${edit.replacement}; update SDK dependencies and rebuild together.`,
137
+ rule: 'embedded-mcp-sdk-v2'
138
+ });
139
+ }
140
+ let migrated = '';
141
+ let cursor = 0;
142
+ for (const edit of edits) {
143
+ migrated += source.slice(cursor, edit.start) + edit.replacement;
144
+ cursor = edit.end;
145
+ }
146
+ return { changes, source: migrated + source.slice(cursor) };
147
+ };
148
+ const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
149
+ const strings = (value) => {
150
+ if (!Array.isArray(value) || !value.every((entry) => typeof entry === 'string'))
151
+ throw new Error('Invalid v4 migration string list.');
152
+ return value;
153
+ };
154
+ const loadRules = async () => {
155
+ const value = JSON.parse(await readFile(new URL('../v4-migration.json', import.meta.url), 'utf8'));
156
+ if (!isRecord(value) || typeof value.targetVersion !== 'string' || !Array.isArray(value.changes))
157
+ throw new Error('Invalid v4 migration contract.');
158
+ const rules = value.changes.map((entry) => {
159
+ if (!isRecord(entry) || typeof entry.id !== 'string' || typeof entry.migration !== 'string')
160
+ throw new Error('Invalid v4 migration rule.');
161
+ return {
162
+ id: entry.id,
163
+ migration: entry.migration,
164
+ packages: strings(entry.packages),
165
+ signals: strings(entry.signals)
166
+ };
167
+ });
168
+ return { rules, targetVersion: value.targetVersion };
169
+ };
170
+ const discover = async (directory) => {
171
+ const files = [];
172
+ for (const entry of await readdir(directory, { withFileTypes: true })) {
173
+ if (entry.isSymbolicLink())
174
+ continue;
175
+ const path = join(directory, entry.name);
176
+ if (entry.isDirectory() && !ignored.has(entry.name))
177
+ files.push(...await discover(path));
178
+ else if (entry.isFile() && (sourceExtensions.has(extname(path)) || entry.name === 'package.json'))
179
+ files.push(path);
180
+ }
181
+ return files.sort();
182
+ };
183
+ const resolveInstalled = async (path, name, range) => {
184
+ const require = createRequire(pathToFileURL(path));
185
+ try {
186
+ const installed = JSON.parse(await readFile(require.resolve(`${name}/package.json`), 'utf8'));
187
+ if (isRecord(installed) && typeof installed.version === 'string')
188
+ return installed.version;
189
+ throw new Error(`Invalid installed package metadata for ${name}.`);
190
+ }
191
+ catch (error) {
192
+ if (!isRecord(error) || !['MODULE_NOT_FOUND', 'ERR_PACKAGE_PATH_NOT_EXPORTED'].includes(String(error.code)))
193
+ throw error;
194
+ return `unresolved:${range}`;
195
+ }
196
+ };
197
+ const inventoryGroup = async (path, group) => {
198
+ const result = {};
199
+ if (!isRecord(group))
200
+ return result;
201
+ for (const [name, range] of Object.entries(group)) {
202
+ if (!name.startsWith('@santi020k/lumen') && !name.startsWith('@modelcontextprotocol/'))
203
+ continue;
204
+ if (typeof range !== 'string')
205
+ throw new Error(`Invalid dependency version for ${name}.`);
206
+ result[name] = await resolveInstalled(path, name, range);
207
+ }
208
+ return result;
209
+ };
210
+ const inventory = async (path) => {
211
+ const value = JSON.parse(await readFile(path, 'utf8'));
212
+ if (!isRecord(value))
213
+ throw new Error(`Invalid package manifest: ${path}`);
214
+ const result = {};
215
+ for (const group of [value.dependencies, value.devDependencies, value.peerDependencies]) {
216
+ for (const [name, version] of Object.entries(await inventoryGroup(path, group)))
217
+ result[name] = version;
218
+ }
219
+ return result;
220
+ };
221
+ const reviewSource = (source, file, rules) => {
222
+ const usesLumen = source.includes('lumen') || source.includes('LumenUI') || source.includes('Lumen');
223
+ return rules.flatMap(rule => {
224
+ if (!usesLumen && rule.id !== 'embedded-mcp-sdk-v2')
225
+ return [];
226
+ const signal = rule.signals.find(value => source.includes(value));
227
+ if (!signal)
228
+ return [];
229
+ return [{ ...location(source, source.indexOf(signal)), file, message: rule.migration, rule: rule.id }];
230
+ });
231
+ };
232
+ const migrateFile = async (path, rules, report) => {
233
+ report.filesScanned += 1;
234
+ const file = relative(report.root, path);
235
+ const source = await readFile(path, 'utf8');
236
+ const webCode = ['.ts', '.js', '.mjs'].includes(extname(path));
237
+ const migration = webCode ? migrateLumenV4Source(source, file) : { changes: [], source };
238
+ report.changes.push(...migration.changes);
239
+ report.manualReview.push(...reviewSource(source, file, rules));
240
+ if (migration.source === source)
241
+ return;
242
+ report.changedFiles.push(file);
243
+ if (!report.applied)
244
+ return;
245
+ if (await readFile(path, 'utf8') !== source)
246
+ throw new Error(`Source changed during migration: ${file}`);
247
+ await writeFile(path, migration.source, 'utf8');
248
+ };
249
+ export const migrateLumenV4 = async (options = {}) => {
250
+ const root = resolve(options.cwd ?? process.cwd());
251
+ const { rules, targetVersion } = await loadRules();
252
+ const report = {
253
+ applied: options.apply === true,
254
+ changedFiles: [],
255
+ changes: [],
256
+ filesScanned: 0,
257
+ manualReview: [],
258
+ packageVersions: {},
259
+ root,
260
+ targetVersion
261
+ };
262
+ for (const path of await discover(root)) {
263
+ if (basename(path) === 'package.json') {
264
+ for (const [name, version] of Object.entries(await inventory(path))) {
265
+ report.packageVersions[`${relative(root, path)}:${name}`] = version;
266
+ }
267
+ }
268
+ else
269
+ await migrateFile(path, rules, report);
270
+ }
271
+ return report;
272
+ };
@@ -0,0 +1,8 @@
1
+ export interface LumenMigrationDependencyOptions {
2
+ allowDirty?: boolean;
3
+ apply?: boolean;
4
+ dependencies?: boolean;
5
+ }
6
+ /** Dependency mutations precede source edits so rollout's dirty-worktree guard stays authoritative. */
7
+ export declare const applyLumenVersionMigrationDependencies: (root: string, targetVersion: string, options: LumenMigrationDependencyOptions) => Promise<import("./consumer-rollout.js").ConsumerRolloutReport>;
8
+ //# sourceMappingURL=version-migration-dependencies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-migration-dependencies.d.ts","sourceRoot":"","sources":["../src/version-migration-dependencies.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,+BAA+B;IAC9C,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,uGAAuG;AACvG,eAAO,MAAM,sCAAsC,GACjD,MAAM,MAAM,EACZ,eAAe,MAAM,EACrB,SAAS,+BAA+B,mEAQxC,CAAA"}
@@ -0,0 +1,10 @@
1
+ import { runConsumerRollout } from './consumer-rollout.js';
2
+ /** Dependency mutations precede source edits so rollout's dirty-worktree guard stays authoritative. */
3
+ export const applyLumenVersionMigrationDependencies = (root, targetVersion, options) => runConsumerRollout({
4
+ allowDirty: options.allowDirty === true,
5
+ apply: options.apply === true,
6
+ repositories: [root],
7
+ targetVersion,
8
+ // Verify after source migration, through the consumer's normal completion gate.
9
+ verify: false
10
+ });
@@ -0,0 +1,4 @@
1
+ import type { LumenMigrationVersion, LumenVersionSourceMigration } from './version-migration.js';
2
+ /** Assumes v3 input for v4. Filesystem apply uses a ledger to prevent repeated spacing rewrites. */
3
+ export declare const migrateLumenVersionSource: (source: string, file: string, version: LumenMigrationVersion) => LumenVersionSourceMigration;
4
+ //# sourceMappingURL=version-migration-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-migration-source.d.ts","sourceRoot":"","sources":["../src/version-migration-source.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,qBAAqB,EAAgC,2BAA2B,EAAE,MAAM,wBAAwB,CAAA;AA8V9H,oGAAoG;AACpG,eAAO,MAAM,yBAAyB,GACpC,QAAQ,MAAM,EACd,MAAM,MAAM,EACZ,SAAS,qBAAqB,KAC7B,2BA4BF,CAAA"}