Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

npx: warp-drive retrofit types@canary 🪄 #9473

Merged
merged 5 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions packages/-warp-drive/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "warp-drive",
"version": "0.1.0-alpha.1",
"private": true,
"private": false,
"description": "WarpDrive is the data framework for ambitious web applications",
"keywords": [
"typescript",
Expand Down Expand Up @@ -53,7 +53,8 @@
"@embroider/macros": "^1.16.1",
"@warp-drive/build-config": "workspace:0.0.0-alpha.15",
"semver": "^7.6.2",
"chalk": "^5.3.0"
"chalk": "^5.3.0",
"comment-json": "^4.2.3"
},
"devDependencies": {
"@babel/core": "^7.24.5",
Expand Down
20 changes: 8 additions & 12 deletions packages/-warp-drive/src/-private/shared/git.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import chalk from 'chalk';
import {
branchForChannelAndVersion,
CHANNEL,
channelForBranch,
npmDistTagForChannelAndVersion,
SEMVER_VERSION,
VALID_BRANCHES,
} from './channel';
import { getFile } from './json-file';
import { exec } from './cmd';
import { gatherPackages, loadStrategy, Package } from './package';
import path from 'path';

import type { CHANNEL, SEMVER_VERSION, VALID_BRANCHES } from './channel';
import { branchForChannelAndVersion, channelForBranch, npmDistTagForChannelAndVersion } from './channel';
import { exec } from './cmd';
import { getFile } from './json-file';
import type { Package } from './package';
import { gatherPackages, loadStrategy } from './package';

export type LTS_TAG = `lts-${number}-${number}`;
export type RELEASE_TAG = `release-${number}-${number}`;
export type GIT_TAG =
Expand Down Expand Up @@ -192,7 +188,7 @@ export async function getAllPackagesForGitTag(tag: GIT_TAG): Promise<Map<string,
try {
await exec({ cmd: ['sh', '-c', `git archive ${tag} --prefix ${relativeTmpDir} | tar -x`] });
} catch (e) {
if (await isUnrecoverableExtractionError(e as unknown as Error)) {
if (await isUnrecoverableExtractionError(e as Error)) {
console.log(chalk.red(`🔴 Failed to extract git tag ${tag} to ${relativeTmpDir}`));
throw e;
} else {
Expand Down
50 changes: 50 additions & 0 deletions packages/-warp-drive/src/-private/shared/npm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import fs from 'fs';
import { execSync } from 'node:child_process';

type NpmInfo = {
'dist-tags': Record<string, string>;
version: string;
dependencies: Record<string, string>;
devDependencies: Record<string, string>;
peerDependencies: Record<string, string>;
peerDependenciesMeta: Record<string, { optional?: boolean }>;
};

const InfoCache: Record<string, NpmInfo> = {};

// eslint-disable-next-line @typescript-eslint/require-await
export async function exec(cmd: string) {
return execSync(cmd);
}

export async function getTags(project: string): Promise<Set<string>> {
if (!InfoCache[project]) {
const info = await exec(`npm view ${project} --json`);
InfoCache[project] = JSON.parse(String(info)) as unknown as NpmInfo;
}

const keys = Object.keys(InfoCache[project]['dist-tags']);
return new Set(keys);
}

export async function getInfo(project: string): Promise<NpmInfo> {
if (!InfoCache[project]) {
const info = await exec(`npm view ${project} --json`);
InfoCache[project] = JSON.parse(String(info)) as unknown as NpmInfo;
}

return InfoCache[project];
}

export function getPackageManagerFromLockfile(): 'yarn' | 'npm' | 'bun' | 'pnpm' {
if (fs.existsSync('pnpm-lock.yaml')) {
return 'pnpm';
} else if (fs.existsSync('package-lock.json')) {
return 'npm';
} else if (fs.existsSync('yarn.lock')) {
return 'yarn';
} else if (fs.existsSync('bun.lock')) {
return 'bun';
}
return 'npm';
}
29 changes: 18 additions & 11 deletions packages/-warp-drive/src/-private/shared/parse-args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ export type Command = {
load: () => Promise<CmdFn>;
};

export type CmdFn = (args: string[]) => Promise<void>;
type FlagPrimitiveValue = string | number | boolean | null;
export type ParsedFlags = {
full: Map<string, FlagPrimitiveValue>;
specified: Map<string, FlagPrimitiveValue>;
};
export type CmdFn = (flags: ParsedFlags) => Promise<void>;

export type CommandConfig = Record<string, Command>;
export type Flag = {
Expand All @@ -39,7 +44,7 @@ export type Flag = {
flag_aliases?: string[];
flag_mispellings?: string[];
description: string;
validate?: (value: unknown, config: Map<string, string | number | boolean | null>) => void | Promise<void>;
validate?: (value: unknown, config: Map<string, FlagPrimitiveValue>) => void | Promise<void>;
examples: Array<
| string
| {
Expand All @@ -53,9 +58,7 @@ export type Flag = {
| number
| boolean
| null
| ((
config: Map<string, string | number | boolean | null>
) => string | number | boolean | null | Promise<string | number | boolean | null>);
| ((config: Map<string, FlagPrimitiveValue>) => FlagPrimitiveValue | Promise<FlagPrimitiveValue>);
/*
Positional flags are not specified by name, but by position
When using this with more than one positional flag, you must specify positional_index
Expand Down Expand Up @@ -101,7 +104,7 @@ export type BinConfig = {

const FalseyStrings = new Set(['false', '0', 'no', 'n', 'off', '']);

function processRawValue(config: Flag, raw_value: string | undefined): string | number | boolean | null {
function processRawValue(config: Flag, raw_value: string | undefined): FlagPrimitiveValue {
if (raw_value === undefined) {
if (config.type === Boolean) {
return config.invert_boolean ? false : true;
Expand All @@ -120,10 +123,7 @@ function processRawValue(config: Flag, raw_value: string | undefined): string |
}
}

async function processMissingFlag(
config: Flag,
values: Map<string, string | number | boolean | null>
): Promise<string | number | boolean | null> {
async function processMissingFlag(config: Flag, values: Map<string, FlagPrimitiveValue>): Promise<FlagPrimitiveValue> {
if (config.default_value !== undefined) {
if (typeof config.default_value === 'function') {
return await config.default_value(values);
Expand Down Expand Up @@ -384,6 +384,11 @@ export function getCommands<T extends Record<string, { default?: boolean; alt?:
return commands;
}

const EMPTY_FLAGS = {
full: new Map<string, FlagPrimitiveValue>(),
specified: new Map<string, FlagPrimitiveValue>(),
};

export async function runBinCommand(config: BinConfig): Promise<void> {
const args = process.argv.slice(2);

Expand All @@ -404,6 +409,8 @@ export async function runBinCommand(config: BinConfig): Promise<void> {
}

const cmdFn = await cmd.load();
await cmdFn(args);
const flags = cmd.options ? await parseRawFlags(args, cmd.options) : EMPTY_FLAGS;

await cmdFn(flags);
process.exit(0);
}
92 changes: 92 additions & 0 deletions packages/-warp-drive/src/-private/shared/the-big-list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
export const Main = [
'@ember-data/active-record',
'@ember-data/adapter',
'@ember-data/codemods',
'@ember-data/debug',
'@ember-data/graph',
'@ember-data/json-api',
'@ember-data/legacy-compat',
'@ember-data/model',
'@ember-data/request-utils',
'@ember-data/request',
'@ember-data/rest',
'@ember-data/serializer',
'@ember-data/store',
'@ember-data/tracking',
'@warp-drive/build-config',
'@warp-drive/core-types',
'@warp-drive/diagnostic',
'@warp-drive/ember',
'@warp-drive/holodeck',
'@warp-drive/schema-record',
'@warp-drive/schema',
'ember-data',
'eslint-plugin-ember-data',
'warp-drive',
];

export const Types = [
'@ember-data-types/active-record',
'@ember-data-types/adapter',
'@ember-data-types/graph',
'@ember-data-types/json-api',
'@ember-data-types/legacy-compat',
'@ember-data-types/model',
'@ember-data-types/request-utils',
'@ember-data-types/request',
'@ember-data-types/rest',
'@ember-data-types/serializer',
'@ember-data-types/store',
'@ember-data-types/tracking',
'@warp-drive-types/core-types',
'ember-data-types',
];

export const Mirror = [
'@ember-data-mirror/active-record',
'@ember-data-mirror/adapter',
'@ember-data-mirror/graph',
'@ember-data-mirror/json-api',
'@ember-data-mirror/legacy-compat',
'@ember-data-mirror/model',
'@ember-data-mirror/request-utils',
'@ember-data-mirror/request',
'@ember-data-mirror/rest',
'@ember-data-mirror/serializer',
'@ember-data-mirror/store',
'@ember-data-mirror/tracking',
'@warp-drive-mirror/build-config',
'@warp-drive-mirror/core-types',
'@warp-drive-mirror/schema-record',
'ember-data-mirror',
];

export const DefinitelyTyped = [
'@types/ember',
'@types/ember-data',
'@types/ember-data__adapter',
'@types/ember-data__model',
'@types/ember-data__serializer',
'@types/ember-data__store',
'@types/ember__application',
'@types/ember__array',
'@types/ember__component',
'@types/ember__controller',
'@types/ember__debug',
'@types/ember__destroyable',
'@types/ember__engine',
'@types/ember__error',
'@types/ember__helper',
'@types/ember__modifier',
'@types/ember__object',
'@types/ember__owner',
'@types/ember__routing',
'@types/ember__runloop',
'@types/ember__service',
'@types/ember__string',
'@types/ember__template',
'@types/ember__test',
'@types/ember__utils',
];

export const ALL = ([] as string[]).concat(Main, Types, Mirror);
56 changes: 56 additions & 0 deletions packages/-warp-drive/src/-private/shared/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import chalk from 'chalk';
import fs from 'fs';
import path from 'path';

import type { SEMVER_VERSION } from './channel';

/**
* Like Pick but returns an object type instead of a union type.
Expand Down Expand Up @@ -243,3 +247,55 @@ export function write(out: string): void {
// eslint-disable-next-line no-console
console.log(out);
}

type ExportConfig = Record<string, string | Record<string, string | Record<string, string>>>;

export type PACKAGEJSON = {
name: string;
version: SEMVER_VERSION;
private: boolean;
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
peerDependencies?: Record<string, string>;
scripts?: Record<string, string>;
files?: string[];
exports?: ExportConfig;
'ember-addon'?: {
main?: 'addon-main.js';
type?: 'addon';
version?: 1 | 2;
};
author?: string;
license?: string;
repository?: {
type: string;
url: string;
directory?: string;
};
};

export function getPkgJson() {
const file = fs.readFileSync(path.join(process.cwd(), 'package.json'), { encoding: 'utf-8' });
const json = JSON.parse(file) as PACKAGEJSON;
return json;
}

export function writePkgJson(json: PACKAGEJSON) {
fs.writeFileSync(path.join(process.cwd(), 'package.json'), JSON.stringify(json, null, 2) + '\n');
}

export function getLocalPkgJson(name: string) {
const file = fs.readFileSync(path.join(process.cwd(), 'node_modules', name, 'package.json'), { encoding: 'utf-8' });
const json = JSON.parse(file) as PACKAGEJSON;
return json;
}

export function getTypePathFor(name: string) {
const pkg = getLocalPkgJson(name);
const isAlpha = pkg.files?.includes('unstable-preview-types');
const isBeta = pkg.files?.includes('preview-types');
const base = pkg.exports?.['.'];
const isStable = !isAlpha && !isBeta && typeof base === 'object' && base?.['types'] !== undefined;

return isAlpha ? 'unstable-preview-types' : isBeta ? 'preview-types' : isStable ? 'types' : null;
}
Loading
Loading